AVCodec updates
[io/jrb1.git] / addons / SampleRateConverter / source / IoSampleRateConverter.c
blob434185be6ef36cedbc3b694084c79adc1eec58d6
1 /*#io
2 SampleRateConverter ioDoc(
3 docCopyright("Steve Dekorte", 2004)
4 docLicense("BSD revised")
5 docCategory("Media")
6 docDescription("""A binding for lib sample rate.""")
7 */
8 #include "IoSampleRateConverter.h"
9 #include "List.h"
10 #include "IoState.h"
11 #include "IoNumber.h"
12 #include "IoSeq.h"
14 #define DATA(self) ((IoSampleRateConverterData *)IoObject_dataPointer(self))
16 IoTag *IoSampleRateConverter_newTag(void *state)
18 IoTag *tag = IoTag_newWithName_("SampleRateConverter");
19 IoTag_state_(tag, state);
20 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoSampleRateConverter_rawClone);
21 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoSampleRateConverter_mark);
22 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoSampleRateConverter_free);
23 return tag;
26 IoSampleRateConverter *IoSampleRateConverter_proto(void *state)
28 IoObject *self = IoObject_new(state);
29 IoObject_tag_(self, IoSampleRateConverter_newTag(state));
31 IoObject_setDataPointer_(self, calloc(1, sizeof(IoSampleRateConverterData)));
33 DATA(self)->inputBuffer = IoSeq_new(state);
34 DATA(self)->outputBuffer = IoSeq_new(state);
36 IoState_registerProtoWithFunc_(state, self, IoSampleRateConverter_proto);
39 IoMethodTable methodTable[] = {
40 {"start", IoSampleRateConverter_start},
41 {"process", IoSampleRateConverter_process},
42 {"stop", IoSampleRateConverter_stop},
43 {"setOutputToInputRatio", IoSampleRateConverter_setOutputToInputRatio},
44 {"setEndOFInput", IoSampleRateConverter_setEndOFInput},
45 {"inputBuffer", IoSampleRateConverter_inputBuffer},
46 {"outputBuffer", IoSampleRateConverter_outputBuffer},
47 {"outputToInputRatio", IoSampleRateConverter_outputToInputRatio},
48 {NULL, NULL},
50 IoObject_addMethodTable_(self, methodTable);
53 return self;
56 IoSampleRateConverter *IoSampleRateConverter_rawClone(IoSampleRateConverter *proto)
58 IoObject *self = IoObject_rawClonePrimitive(proto);
59 IoObject_setDataPointer_(self, calloc(1, sizeof(IoSampleRateConverterData)));
61 DATA(self)->inputBuffer = IoSeq_new(IOSTATE);
62 DATA(self)->outputBuffer = IoSeq_new(IOSTATE);
64 return self;
67 IoSampleRateConverter *IoSampleRateConverter_new(void *state)
69 IoObject *proto = IoState_protoWithInitFunction_(state, IoSampleRateConverter_proto);
70 return IOCLONE(proto);
73 /* ----------------------------------------------------------- */
75 void IoSampleRateConverter_freeSampleRateStateIfNeeded(IoSampleRateConverter *self)
77 if (DATA(self)->srcData)
79 src_delete(DATA(self)->srcState);
80 DATA(self)->srcState = NULL;
82 free(DATA(self)->srcData);
83 DATA(self)->srcData = NULL;
87 void IoSampleRateConverter_free(IoSampleRateConverter *self)
89 IoSampleRateConverter_freeSampleRateStateIfNeeded(self);
90 free(IoObject_dataPointer(self));
93 void IoSampleRateConverter_mark(IoSampleRateConverter *self)
95 IoObject_shouldMark(DATA(self)->inputBuffer);
96 IoObject_shouldMark(DATA(self)->outputBuffer);
99 /* ----------------------------------------------------------- */
101 SRC_DATA *IoSampleRateConverter_srcData(IoSampleRateConverter *self)
103 if (DATA(self)->srcData == NULL)
105 int error;
106 DATA(self)->srcState = src_new(SRC_SINC_MEDIUM_QUALITY, 2, &error);
107 DATA(self)->srcData = calloc(1, sizeof(SRC_DATA));
108 DATA(self)->srcData->src_ratio = 1.0;
109 DATA(self)->srcData->end_of_input = 0;
112 return DATA(self)->srcData;
116 IoObject *IoSampleRateConverter_process(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
118 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
120 UArray *inba = IoSeq_rawUArray(DATA(self)->inputBuffer);
121 UArray *outba = IoSeq_rawUArray(DATA(self)->outputBuffer);
123 size_t inSize = UArray_size(inba);
125 UArray_setSize_(outba, inSize);
127 srcData->data_in = (float *)UArray_bytes(inba);
128 srcData->input_frames = inSize / ( 2 * sizeof(float));
130 srcData->data_out = (float *)UArray_bytes(outba);
131 srcData->output_frames = srcData->input_frames;
133 src_process(DATA(self)->srcState, srcData);
135 UArray_setSize_(inba, 0);
136 //UArray_removeRange(inba, 0, srcData->input_frames_used * 2 * sizeof(float));
137 //UArray_setSize_(outba, srcData->output_frames_gen * 2 * sizeof(float));
139 return self;
143 IoObject *IoSampleRateConverter_process(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
145 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
147 UArray *inba = IoSeq_rawUArray(DATA(self)->inputBuffer);
148 UArray *outba = IoSeq_rawUArray(DATA(self)->outputBuffer);
150 size_t inSize = UArray_size(inba);
151 size_t oldOutSize = UArray_size(outba);
153 UArray_setSize_(outba, oldOutSize + inSize);
155 srcData->data_in = (float *)(UArray_bytes(inba));
156 srcData->input_frames = inSize / ( 2 * sizeof(float));
158 srcData->data_out = (float *)(UArray_bytes(outba) + oldOutSize);
159 srcData->output_frames = srcData->input_frames;
161 src_process(DATA(self)->srcState, srcData);
163 UArray_removeRange(inba, 0, srcData->input_frames_used * 2 * sizeof(float));
164 UArray_setSize_(outba, oldOutSize + (srcData->output_frames_gen * 2 * sizeof(float)));
166 return self;
169 IoObject *IoSampleRateConverter_start(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
171 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
173 if (!srcData)
175 int error;
176 DATA(self)->srcState = src_new(SRC_SINC_MEDIUM_QUALITY, 2, &error);
177 srcData = calloc(1, sizeof(srcData));
178 srcData->src_ratio = 1.0;
179 srcData->end_of_input = 0;
182 return self;
185 IoObject *IoSampleRateConverter_stop(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
187 IoSampleRateConverter_freeSampleRateStateIfNeeded(self);
189 return self;
192 IoObject *IoSampleRateConverter_setOutputToInputRatio(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
194 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
195 IoNumber *r = IoMessage_locals_numberArgAt_(m, locals, 0);
196 srcData->src_ratio = CNUMBER(r);
197 return self;
200 IoObject *IoSampleRateConverter_outputToInputRatio(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
202 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
203 return IONUMBER(srcData->src_ratio);
206 IoObject *IoSampleRateConverter_setEndOFInput(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
208 SRC_DATA *srcData = IoSampleRateConverter_srcData(self);
209 IoObject *v = IoMessage_locals_valueArgAt_(m, locals, 0);
210 srcData->end_of_input = ISTRUE(v) ? 1 : 0;
211 return self;
214 IoObject *IoSampleRateConverter_inputBuffer(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
216 return DATA(self)->inputBuffer;
219 IoObject *IoSampleRateConverter_outputBuffer(IoSampleRateConverter *self, IoObject *locals, IoMessage *m)
221 return DATA(self)->outputBuffer;