Changeset 2b208a8


Ignore:
Timestamp:
Dec 19, 2018, 3:18:05 PM (5 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/crepe, fix/ffmpeg5, master
Children:
99365e9
Parents:
dbad82c
Message:

[io] sink_apple_audio can now write aiff, mp4, and aac

Location:
src/io
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/io/sink_apple_audio.c

    rdbad82c r2b208a8  
    3939uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s);
    4040
     41uint_t aubio_str_extension_matches(const char_t *ext,
     42    const char_t *pattern);
     43const char_t *aubio_str_get_extension(const char_t *filename);
     44
    4145#define MAX_SIZE 4096 // the maximum number of frames that can be written at a time
    4246
     
    5357  ExtAudioFileRef audioFile;
    5458  bool async;
     59  AudioFileTypeID fileType;
    5560};
    5661
     
    7176  s->channels = 0;
    7277
     78  aubio_sink_apple_audio_preset_format(s, aubio_str_get_extension(uri));
     79
    7380  // zero samplerate given. do not open yet
    7481  if ((sint_t)samplerate == 0) {
     
    121128}
    122129
     130uint_t aubio_sink_apple_audio_preset_format(aubio_sink_apple_audio_t *s,
     131    const char_t *fmt)
     132{
     133  if (aubio_str_extension_matches(fmt, "wav")) {
     134    s->fileType = kAudioFileWAVEType;
     135  } else if (aubio_str_extension_matches(fmt, "m4a")
     136      || aubio_str_extension_matches(fmt, "mp4") ) {
     137    // use alac for "mp4" and "m4a"
     138    s->fileType = kAudioFileM4AType;
     139  } else if (aubio_str_extension_matches(fmt, "aac") ) {
     140    // only use lossy codec for "aac"
     141    s->fileType = kAudioFileMPEG4Type;
     142  } else if (aubio_str_extension_matches(fmt, "aiff") ) {
     143    // only use lossy codec for "aac"
     144    s->fileType = kAudioFileAIFFType;
     145  } else {
     146    AUBIO_WRN("sink_apple_audio: could not guess format for %s,"
     147       " using default (wav)\n", s->path);
     148    s->fileType = kAudioFileWAVEType;
     149    return AUBIO_FAIL;
     150  }
     151  return AUBIO_OK;
     152}
     153
     154static void aubio_sink_apple_audio_set_client_format(aubio_sink_apple_audio_t* s,
     155    AudioStreamBasicDescription *clientFormat)
     156{
     157  memset(clientFormat, 0, sizeof(AudioStreamBasicDescription));
     158  // always set samplerate and channels first
     159  clientFormat->mSampleRate       = (Float64)(s->samplerate);
     160  clientFormat->mChannelsPerFrame = s->channels;
     161
     162  switch (s->fileType) {
     163    case kAudioFileM4AType:
     164      clientFormat->mFormatID         = kAudioFormatAppleLossless;
     165      break;
     166    case kAudioFileMPEG4Type:
     167      clientFormat->mFormatID         = kAudioFormatMPEG4AAC;
     168      clientFormat->mFormatFlags      = kMPEG4Object_AAC_Main;
     169      clientFormat->mFormatFlags     |= kAppleLosslessFormatFlag_16BitSourceData;
     170      clientFormat->mFramesPerPacket  = 1024;
     171      break;
     172    case kAudioFileWAVEType:
     173      clientFormat->mFormatID         = kAudioFormatLinearPCM;
     174      clientFormat->mFormatFlags      = kAudioFormatFlagIsSignedInteger;
     175      clientFormat->mFormatFlags     |= kAudioFormatFlagIsPacked;
     176      clientFormat->mBitsPerChannel   = sizeof(short) * 8;
     177      clientFormat->mFramesPerPacket  = 1;
     178      clientFormat->mBytesPerFrame    = clientFormat->mBitsPerChannel * clientFormat->mChannelsPerFrame / 8;
     179      clientFormat->mBytesPerPacket   = clientFormat->mFramesPerPacket * clientFormat->mBytesPerFrame;
     180      break;
     181    case kAudioFileAIFFType:
     182      clientFormat->mFormatID         = kAudioFormatLinearPCM;
     183      clientFormat->mFormatFlags      = kAudioFormatFlagIsSignedInteger;
     184      clientFormat->mFormatFlags     |= kAudioFormatFlagIsPacked;
     185      clientFormat->mFormatFlags     |= kAudioFormatFlagIsBigEndian;
     186      clientFormat->mBitsPerChannel   = sizeof(short) * 8;
     187      clientFormat->mFramesPerPacket  = 1;
     188      clientFormat->mBytesPerFrame    = clientFormat->mBitsPerChannel * clientFormat->mChannelsPerFrame / 8;
     189      clientFormat->mBytesPerPacket   = clientFormat->mFramesPerPacket * clientFormat->mBytesPerFrame;
     190      break;
     191    default:
     192      break;
     193  }
     194}
     195
    123196uint_t aubio_sink_apple_audio_get_samplerate(const aubio_sink_apple_audio_t *s)
    124197{
     
    135208  if (s->samplerate == 0 || s->channels == 0) return AUBIO_FAIL;
    136209
    137   AudioStreamBasicDescription clientFormat;
    138   memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
    139   clientFormat.mFormatID         = kAudioFormatLinearPCM;
    140   clientFormat.mSampleRate       = (Float64)(s->samplerate);
    141   clientFormat.mFormatFlags      = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    142   clientFormat.mChannelsPerFrame = s->channels;
    143   clientFormat.mBitsPerChannel   = sizeof(short) * 8;
    144   clientFormat.mFramesPerPacket  = 1;
    145   clientFormat.mBytesPerFrame    = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
    146   clientFormat.mBytesPerPacket   = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
    147   clientFormat.mReserved         = 0;
    148 
    149   AudioFileTypeID fileType = kAudioFileWAVEType;
    150210  CFURLRef fileURL = createURLFromPath(s->path);
    151211  bool overwrite = true;
     
    162222  inputFormat.mBytesPerFrame    = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8;
    163223  inputFormat.mBytesPerPacket   = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame;
     224
     225  // get the in-file format
     226  AudioStreamBasicDescription clientFormat;
     227  aubio_sink_apple_audio_set_client_format(s, &clientFormat);
     228
    164229  OSStatus err = noErr;
    165   err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
     230  err = ExtAudioFileCreateWithURL(fileURL, s->fileType, &clientFormat, NULL,
    166231     overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile);
    167232  CFRelease(fileURL);
  • src/io/sink_apple_audio.h

    rdbad82c r2b208a8  
    9797/**
    9898
     99  preset sink format
     100
     101  \param s sink, created with ::new_aubio_sink_apple_audio
     102  \param fmt format of the file to create
     103
     104  \return 0 on success, 1 on error
     105
     106  Preset the format of the sink. Supported format strings:
     107   - "wav": WAVE, 16 bit (default)
     108   - "aiff": AIFF, 16 bit
     109   - "m4a" or "mp4": Apple Audio Lossless Codec (ALAC)
     110   - "aac": Audio Advanced Codec, lossy
     111
     112  Full list of supported encoding format is available in Table 1-2 of
     113  `Multimedia Programming Guide
     114  <https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html>`_.
     115
     116 */
     117uint_t aubio_sink_apple_audio_preset_format(aubio_sink_apple_audio_t *s,
     118    const char_t *fmt);
     119
     120/**
     121
    99122  get samplerate of sink object
    100123
Note: See TracChangeset for help on using the changeset viewer.