Ignore:
Timestamp:
Dec 19, 2018, 7:31:45 PM (12 months ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/timestretch
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.
Message:

Merge branch 'feature/pitchshift' into feature/timestretch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/io/sink_apple_audio.c

    r6e157df rcb0d7d0  
    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);
     
    6260  s->async = false;
    6361
    64   if ( (uri == NULL) || (strlen(uri) < 1) ) {
     62  if ( (uri == NULL) || (strnlen(uri, PATH_MAX) < 1) ) {
    6563    AUBIO_ERROR("sink_apple_audio: Aborted opening null path\n");
    6664    goto beach;
    6765  }
    68   if (s->path != NULL) AUBIO_FREE(s->path);
     66
    6967  s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1);
    7068  strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1);
     
    7775    return s;
    7876  }
     77
    7978  // invalid samplerate given, abort
    8079  if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) {
     
    9291  return s;
    9392beach:
    94   AUBIO_FREE(s);
     93  del_aubio_sink_apple_audio(s);
    9594  return NULL;
    9695}
     
    103102  s->samplerate = samplerate;
    104103  // 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) {
    106105    return aubio_sink_apple_audio_open(s);
    107106  }
     
    116115  s->channels = channels;
    117116  // 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 */) {
    119118    return aubio_sink_apple_audio_open(s);
    120119  }
     
    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;
    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);
    193210}
    194211
    195212void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) {
    196213  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);
    213227}
    214228
    215229void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) {
    216230  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);
    217235  if (s->async) {
    218236    err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList);
     
    258276
    259277void 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);
    262283  freeAudioBufferList(&s->bufferList);
    263284  AUBIO_FREE(s);
    264   return;
    265285}
    266286
Note: See TracChangeset for help on using the changeset viewer.