Changeset cb0d7d0 for src/io/sink_apple_audio.c
- Timestamp:
- Dec 19, 2018, 7:31:45 PM (5 years ago)
- Branches:
- feature/cnn, feature/crepe, feature/timestretch, fix/ffmpeg5, master
- Children:
- 22d7902
- Parents:
- 6e157df (diff), d0f19a7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/io/sink_apple_audio.c
r6e157df rcb0d7d0 32 32 #include <AudioToolbox/AudioToolbox.h> 33 33 34 #define FLOAT_TO_SHORT(x) (short)(x * 32768) 35 36 extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int segmentSize); 34 extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int segmentSize); 37 35 extern void freeAudioBufferList(AudioBufferList *bufferList); 38 36 extern CFURLRef createURLFromPath(const char * path); … … 62 60 s->async = false; 63 61 64 if ( (uri == NULL) || (str len(uri) < 1) ) {62 if ( (uri == NULL) || (strnlen(uri, PATH_MAX) < 1) ) { 65 63 AUBIO_ERROR("sink_apple_audio: Aborted opening null path\n"); 66 64 goto beach; 67 65 } 68 if (s->path != NULL) AUBIO_FREE(s->path); 66 69 67 s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); 70 68 strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1); … … 77 75 return s; 78 76 } 77 79 78 // invalid samplerate given, abort 80 79 if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) { … … 92 91 return s; 93 92 beach: 94 AUBIO_FREE(s);93 del_aubio_sink_apple_audio(s); 95 94 return NULL; 96 95 } … … 103 102 s->samplerate = samplerate; 104 103 // automatically open when both samplerate and channels have been set 105 if ( s->samplerate != 0 &&s->channels != 0) {104 if (/* s->samplerate != 0 && */ s->channels != 0) { 106 105 return aubio_sink_apple_audio_open(s); 107 106 } … … 116 115 s->channels = channels; 117 116 // automatically open when both samplerate and channels have been set 118 if (s->samplerate != 0 && s->channels != 0) {117 if (s->samplerate != 0 /* && s->channels != 0 */) { 119 118 return aubio_sink_apple_audio_open(s); 120 119 } … … 151 150 CFURLRef fileURL = createURLFromPath(s->path); 152 151 bool overwrite = true; 152 153 // set the in-memory format 154 AudioStreamBasicDescription inputFormat; 155 memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription)); 156 inputFormat.mFormatID = kAudioFormatLinearPCM; 157 inputFormat.mSampleRate = (Float64)(s->samplerate); 158 inputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; 159 inputFormat.mChannelsPerFrame = s->channels; 160 inputFormat.mBitsPerChannel = sizeof(smpl_t) * 8; 161 inputFormat.mFramesPerPacket = 1; 162 inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8; 163 inputFormat.mBytesPerPacket = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame; 153 164 OSStatus err = noErr; 154 165 err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL, … … 162 173 goto beach; 163 174 } 164 if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) { 175 176 err = ExtAudioFileSetProperty(s->audioFile, 177 kExtAudioFileProperty_ClientDataFormat, 178 sizeof(AudioStreamBasicDescription), &inputFormat); 179 if (err) { 180 char_t errorstr[20]; 181 AUBIO_ERR("sink_apple_audio: error when trying to set output format on %s " 182 "(%s)\n", s->path, getPrintableOSStatusError(errorstr, err)); 183 goto beach; 184 } 185 186 if (createAudioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) { 165 187 AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, " 166 188 "out of memory? \n", s->path); … … 175 197 void aubio_sink_apple_audio_do(aubio_sink_apple_audio_t * s, fvec_t * write_data, uint_t write) { 176 198 UInt32 c, v; 177 short *data = (short*)s->bufferList.mBuffers[0].mData; 178 if (write > s->max_frames) { 179 AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames); 180 write = s->max_frames; 181 } 182 smpl_t *buf = write_data->data; 183 184 if (buf) { 185 for (c = 0; c < s->channels; c++) { 186 for (v = 0; v < write; v++) { 187 data[v * s->channels + c] = 188 FLOAT_TO_SHORT(buf[ v * s->channels + c]); 189 } 190 } 191 } 192 aubio_sink_apple_audio_write(s, write); 199 smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; 200 uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path, 201 s->max_frames, write_data->length, write); 202 203 for (c = 0; c < s->channels; c++) { 204 for (v = 0; v < length; v++) { 205 data[v * s->channels + c] = write_data->data[v]; 206 } 207 } 208 209 aubio_sink_apple_audio_write(s, length); 193 210 } 194 211 195 212 void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) { 196 213 UInt32 c, v; 197 short *data = (short*)s->bufferList.mBuffers[0].mData; 198 if (write > s->max_frames) { 199 AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames); 200 write = s->max_frames; 201 } 202 smpl_t **buf = write_data->data; 203 204 if (buf) { 205 for (c = 0; c < s->channels; c++) { 206 for (v = 0; v < write; v++) { 207 data[v * s->channels + c] = 208 FLOAT_TO_SHORT(buf[c][v]); 209 } 210 } 211 } 212 aubio_sink_apple_audio_write(s, write); 214 smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; 215 uint_t channels = aubio_sink_validate_input_channels("sink_apple_audio", 216 s->path, s->channels, write_data->height); 217 uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path, 218 s->max_frames, write_data->length, write); 219 220 for (c = 0; c < channels; c++) { 221 for (v = 0; v < length; v++) { 222 data[v * s->channels + c] = write_data->data[c][v]; 223 } 224 } 225 226 aubio_sink_apple_audio_write(s, length); 213 227 } 214 228 215 229 void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) { 216 230 OSStatus err = noErr; 231 // set mDataByteSize to match the number of frames to be written 232 // see https://www.mail-archive.com/coreaudio-api@lists.apple.com/msg01109.html 233 s->bufferList.mBuffers[0].mDataByteSize = write * s->channels 234 * sizeof(smpl_t); 217 235 if (s->async) { 218 236 err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList); … … 258 276 259 277 void del_aubio_sink_apple_audio(aubio_sink_apple_audio_t * s) { 260 if (s->audioFile) aubio_sink_apple_audio_close (s); 261 if (s->path) AUBIO_FREE(s->path); 278 AUBIO_ASSERT(s); 279 if (s->audioFile) 280 aubio_sink_apple_audio_close (s); 281 if (s->path) 282 AUBIO_FREE(s->path); 262 283 freeAudioBufferList(&s->bufferList); 263 284 AUBIO_FREE(s); 264 return;265 285 } 266 286
Note: See TracChangeset
for help on using the changeset viewer.