Addons updated to new doc format
[io.git] / addons / PortAudio / source / IoAudioDevice.c
blob0d8ea3cb170fbd00dfc89e0ad20ab4ca5eb114ae
2 //metadoc AudioDevice copyright Steve Dekorte, 2004
3 //metadoc AudioDevice license BSD revised
4 //metadoc AudioDevice category Media")
5 /*metadoc AudioDevice description
6 The AudioDevice object can used to write audio data as if directly to the audio buffer.
7 */
9 #include "IoAudioDevice.h"
10 #include "List.h"
11 #include "UArray.h"
12 #include "IoState.h"
13 #include "IoNumber.h"
14 #include "IoSeq.h"
15 #include "IoList.h"
16 #include <math.h>
18 #define DATA(self) ((IoAudioDeviceData *)IoObject_dataPointer(self))
20 IoTag *IoAudioDevice_newTag(void *state)
22 IoTag *tag = IoTag_newWithName_("AudioDevice");
23 IoTag_state_(tag, state);
24 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoAudioDevice_rawClone);
25 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoAudioDevice_free);
26 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoAudioDevice_mark);
27 return tag;
30 IoAudioDevice *IoAudioDevice_proto(void *state)
32 IoObject *self = IoObject_new(state);
33 IoObject_tag_(self, IoAudioDevice_newTag(state));
35 IoObject_setDataPointer_(self, calloc(1, sizeof(IoAudioDeviceData)));
37 DATA(self)->writeBuffer = IoSeq_new(state);
38 DATA(self)->readBuffer = IoSeq_new(state);
39 DATA(self)->audioDevice = AudioDevice_new();
40 IoState_registerProtoWithFunc_(state, self, IoAudioDevice_proto);
43 IoMethodTable methodTable[] = {
44 {"open", IoAudioDevice_open},
45 {"openForReadingAndWriting", IoAudioDevice_openForReadingAndWriting},
46 {"close", IoAudioDevice_close},
47 {"asyncWrite", IoAudioDevice_asyncWrite},
48 {"asyncRead", IoAudioDevice_read},
49 {"error", IoAudioDevice_error},
50 {"isActive", IoAudioDevice_isActive},
51 {"streamTime", IoAudioDevice_streamTime},
52 {"needsData", IoAudioDevice_needsData},
53 {"writeBufferIsEmpty", IoAudioDevice_writeBufferIsEmpty},
54 {NULL, NULL},
56 IoObject_addMethodTable_(self, methodTable);
58 return self;
61 IoAudioDevice *IoAudioDevice_rawClone(IoAudioDevice *proto)
63 IoObject *self = IoObject_rawClonePrimitive(proto);
64 IoObject_setDataPointer_(self, calloc(1, sizeof(IoAudioDeviceData)));
65 DATA(self)->writeBuffer = IOCLONE(DATA(proto)->writeBuffer);
66 DATA(self)->readBuffer = IOCLONE(DATA(proto)->readBuffer);
67 DATA(self)->audioDevice = AudioDevice_new();
68 return self;
71 IoAudioDevice *IoAudioDevice_new(void *state)
73 IoObject *proto = IoState_protoWithInitFunction_(state, IoAudioDevice_proto);
74 return IOCLONE(proto);
77 /* ----------------------------------------------------------- */
79 void IoAudioDevice_free(IoAudioDevice *self)
81 AudioDevice_free(DATA(self)->audioDevice);
82 free(IoObject_dataPointer(self));
85 void IoAudioDevice_mark(IoAudioDevice *self)
87 IoObject_shouldMark(DATA(self)->writeBuffer);
88 IoObject_shouldMark(DATA(self)->readBuffer);
91 AudioDevice *IoAudioDevice_rawAudioDevice(IoAudioDevice *self)
93 return DATA(self)->audioDevice;
96 void IoAudioDevice_clearBuffers(IoAudioDevice *self)
98 AudioDevice_clearBuffers(DATA(self)->audioDevice);
101 /* ----------------------------------------------------------- */
103 IoObject *IoAudioDevice_openForReadingAndWriting(IoAudioDevice *self, IoObject *locals, IoMessage *m)
105 /*doc AudioDevice openForReadingAndWriting
106 Open audio output and input streams.
109 AudioDevice_openForReadingAndWriting(DATA(self)->audioDevice);
110 AudioDevice_start(DATA(self)->audioDevice);
111 return self;
114 IoObject *IoAudioDevice_open(IoAudioDevice *self, IoObject *locals, IoMessage *m)
116 /*doc AudioDevice open
117 Open an audio output stream.
120 AudioDevice_open(DATA(self)->audioDevice);
121 AudioDevice_start(DATA(self)->audioDevice);
122 return self;
125 IoObject *IoAudioDevice_close(IoAudioDevice *self, IoObject *locals, IoMessage *m)
127 /*doc AudioDevice close
128 Close the audio stream.
131 AudioDevice_close(DATA(self)->audioDevice);
132 return self;
135 IoObject *IoAudioDevice_needsData(IoAudioDevice *self, IoObject *locals, IoMessage *m)
137 /*doc AudioDevice needsData
138 Returns true if the receiver can read more data.
141 return IOBOOL(self, DATA(self)->audioDevice->needsData == 1);
144 IoObject *IoAudioDevice_asyncWrite(IoAudioDevice *self, IoObject *locals, IoMessage *m)
146 /*doc AudioDevice nonBlockingWrite(aBuffer)
147 Writes aBuffer to the audio output buffer and returns immediately.
150 IoSeq *buf = IoMessage_locals_seqArgAt_(m, locals, 0);
152 if (IoSeq_rawSize(buf) == 0)
154 return self;
157 AudioDevice_checkForError(DATA(self)->audioDevice);
158 AudioDevice_write_(DATA(self)->audioDevice, IoSeq_rawUArray(buf));
159 return self;
162 IoObject *IoAudioDevice_read(IoAudioDevice *self, IoObject *locals, IoMessage *m)
164 /*doc AudioDevice read
165 Returns the audio read buffer.
168 AudioDevice *device = DATA(self)->audioDevice;
169 UArray *rba = IoSeq_rawUArray(DATA(self)->readBuffer);
170 UArray *ba;
172 while (device->locked)
174 AudioDevice_nanoSleep(device);
177 ba = AudioDevice_read(device);
178 UArray_copy_(rba, ba);
180 return DATA(self)->readBuffer;
183 IoObject *IoAudioDevice_error(IoAudioDevice *self, IoObject *locals, IoMessage *m)
185 /*doc AudioDevice error
186 Returns an error string if an error has occured, Nil otherwise.
189 const char *e = AudioDevice_error(DATA(self)->audioDevice);
190 return e ? IOSYMBOL(e) : IONIL(self);
193 IoObject *IoAudioDevice_isActive(IoAudioDevice *self, IoObject *locals, IoMessage *m)
195 /*doc AudioDevice isActive
196 Returns self if the receiver is active, Nil otherwise.
199 return AudioDevice_isActive(DATA(self)->audioDevice) ? self : IONIL(self);
202 IoObject *IoAudioDevice_streamTime(IoAudioDevice *self, IoObject *locals, IoMessage *m)
204 /*doc AudioDevice streamTime
205 Returns the audio stream time as a number.
208 return IONUMBER(AudioDevice_streamTime(DATA(self)->audioDevice));
211 IoObject *IoAudioDevice_writeBufferIsEmpty(IoAudioDevice *self, IoObject *locals, IoMessage *m)
213 /*doc AudioDevice writeBufferIsEmpty
214 Returns the true if the audio buffer is empty, false otherwise.
217 return IOBOOL(self, DATA(self)->audioDevice->writeBufferIsEmpty);