2 SampleRateConverter ioDoc(
3 docCopyright("Steve Dekorte", 2004)
4 docLicense("BSD revised")
6 docDescription("""A binding for lib sample rate.""")
8 #include "IoSampleRateConverter.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
);
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
},
50 IoObject_addMethodTable_(self
, methodTable
);
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
);
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
)
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));
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)));
169 IoObject
*IoSampleRateConverter_start(IoSampleRateConverter
*self
, IoObject
*locals
, IoMessage
*m
)
171 SRC_DATA
*srcData
= IoSampleRateConverter_srcData(self
);
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;
185 IoObject
*IoSampleRateConverter_stop(IoSampleRateConverter
*self
, IoObject
*locals
, IoMessage
*m
)
187 IoSampleRateConverter_freeSampleRateStateIfNeeded(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
);
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;
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
;