Ignore:
Timestamp:
Dec 19, 2018, 2:24:41 PM (6 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/timestretch, fix/ffmpeg5, master
Children:
387b605, dbad82c
Parents:
ff6d1b6
Message:

[io] sink_apple_audio to use native format conversion

The important trick here is setting mDataByteSize to the actual number
of frames to be written, as mentionned by James McCartney? in [0].

[0]:https://www.mail-archive.com/coreaudio-api@lists.apple.com/msg01109.html

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/io/sink_apple_audio.c

    rff6d1b6 r7b5e1a5  
    3232#include <AudioToolbox/AudioToolbox.h>
    3333
    34 #define FLOAT_TO_SHORT(x) (short)(x * 32768)
    35 
    36 extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
     34extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
    3735extern void freeAudioBufferList(AudioBufferList *bufferList);
    3836extern CFURLRef createURLFromPath(const char * path);
     
    7775    return s;
    7876  }
     77
    7978  // invalid samplerate given, abort
    8079  if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) {
     
    151150  CFURLRef fileURL = createURLFromPath(s->path);
    152151  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;
    153164  OSStatus err = noErr;
    154165  err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
     
    162173    goto beach;
    163174  }
    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)) {
    165187    AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, "
    166188        "out of memory? \n", s->path);
     
    175197void aubio_sink_apple_audio_do(aubio_sink_apple_audio_t * s, fvec_t * write_data, uint_t write) {
    176198  UInt32 c, v;
    177   short *data = (short*)s->bufferList.mBuffers[0].mData;
     199  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
    178200  uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path,
    179201      s->max_frames, write_data->length, write);
     
    181203  for (c = 0; c < s->channels; c++) {
    182204    for (v = 0; v < length; v++) {
    183       data[v * s->channels + c] = FLOAT_TO_SHORT(write_data->data[v]);
     205      data[v * s->channels + c] = write_data->data[v];
    184206    }
    185207  }
     
    190212void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) {
    191213  UInt32 c, v;
    192   short *data = (short*)s->bufferList.mBuffers[0].mData;
     214  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
    193215  uint_t channels = aubio_sink_validate_input_channels("sink_apple_audio",
    194216      s->path, s->channels, write_data->height);
     
    198220  for (c = 0; c < channels; c++) {
    199221    for (v = 0; v < length; v++) {
    200       data[v * s->channels + c] = FLOAT_TO_SHORT(write_data->data[c][v]);
     222      data[v * s->channels + c] = write_data->data[c][v];
    201223    }
    202224  }
     
    207229void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) {
    208230  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);
    209235  if (s->async) {
    210236    err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList);
Note: See TracChangeset for help on using the changeset viewer.