Changes in src/io/sink_apple_audio.c [7b5e1a5:00c9444]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/io/sink_apple_audio.c
r7b5e1a5 r00c9444 39 39 uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s); 40 40 41 uint_t aubio_str_extension_matches(const char_t *ext, 42 const char_t *pattern); 43 const char_t *aubio_str_get_extension(const char_t *filename); 44 41 45 #define MAX_SIZE 4096 // the maximum number of frames that can be written at a time 42 46 … … 53 57 ExtAudioFileRef audioFile; 54 58 bool async; 59 AudioFileTypeID fileType; 55 60 }; 56 61 … … 71 76 s->channels = 0; 72 77 78 aubio_sink_apple_audio_preset_format(s, aubio_str_get_extension(uri)); 79 73 80 // zero samplerate given. do not open yet 74 81 if ((sint_t)samplerate == 0) { … … 121 128 } 122 129 130 uint_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 s->fileType = kAudioFileWAVEType; 147 if (fmt && strnlen(fmt, PATH_MAX)) { 148 AUBIO_WRN("sink_apple_audio: could not guess format for %s," 149 " using default (wav)\n", s->path); 150 return AUBIO_FAIL; 151 } 152 } 153 return AUBIO_OK; 154 } 155 156 static void aubio_sink_apple_audio_set_client_format(aubio_sink_apple_audio_t* s, 157 AudioStreamBasicDescription *clientFormat) 158 { 159 memset(clientFormat, 0, sizeof(AudioStreamBasicDescription)); 160 // always set samplerate and channels first 161 clientFormat->mSampleRate = (Float64)(s->samplerate); 162 clientFormat->mChannelsPerFrame = s->channels; 163 164 switch (s->fileType) { 165 case kAudioFileM4AType: 166 clientFormat->mFormatID = kAudioFormatAppleLossless; 167 break; 168 case kAudioFileMPEG4Type: 169 clientFormat->mFormatID = kAudioFormatMPEG4AAC; 170 clientFormat->mFormatFlags = kMPEG4Object_AAC_Main; 171 clientFormat->mFormatFlags |= kAppleLosslessFormatFlag_16BitSourceData; 172 clientFormat->mFramesPerPacket = 1024; 173 break; 174 case kAudioFileWAVEType: 175 clientFormat->mFormatID = kAudioFormatLinearPCM; 176 clientFormat->mFormatFlags = kAudioFormatFlagIsSignedInteger; 177 clientFormat->mFormatFlags |= kAudioFormatFlagIsPacked; 178 clientFormat->mBitsPerChannel = sizeof(short) * 8; 179 clientFormat->mFramesPerPacket = 1; 180 clientFormat->mBytesPerFrame = clientFormat->mBitsPerChannel * clientFormat->mChannelsPerFrame / 8; 181 clientFormat->mBytesPerPacket = clientFormat->mFramesPerPacket * clientFormat->mBytesPerFrame; 182 break; 183 case kAudioFileAIFFType: 184 clientFormat->mFormatID = kAudioFormatLinearPCM; 185 clientFormat->mFormatFlags = kAudioFormatFlagIsSignedInteger; 186 clientFormat->mFormatFlags |= kAudioFormatFlagIsPacked; 187 clientFormat->mFormatFlags |= kAudioFormatFlagIsBigEndian; 188 clientFormat->mBitsPerChannel = sizeof(short) * 8; 189 clientFormat->mFramesPerPacket = 1; 190 clientFormat->mBytesPerFrame = clientFormat->mBitsPerChannel * clientFormat->mChannelsPerFrame / 8; 191 clientFormat->mBytesPerPacket = clientFormat->mFramesPerPacket * clientFormat->mBytesPerFrame; 192 break; 193 default: 194 break; 195 } 196 } 197 123 198 uint_t aubio_sink_apple_audio_get_samplerate(const aubio_sink_apple_audio_t *s) 124 199 { … … 135 210 if (s->samplerate == 0 || s->channels == 0) return AUBIO_FAIL; 136 211 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;150 212 CFURLRef fileURL = createURLFromPath(s->path); 151 213 bool overwrite = true; … … 162 224 inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8; 163 225 inputFormat.mBytesPerPacket = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame; 226 227 // get the in-file format 228 AudioStreamBasicDescription clientFormat; 229 aubio_sink_apple_audio_set_client_format(s, &clientFormat); 230 164 231 OSStatus err = noErr; 165 err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,232 err = ExtAudioFileCreateWithURL(fileURL, s->fileType, &clientFormat, NULL, 166 233 overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile); 167 234 CFRelease(fileURL); … … 173 240 goto beach; 174 241 } 242 243 #if defined(kAppleSoftwareAudioCodecManufacturer) 244 // on iOS, set software based encoding before setting clientDataFormat 245 UInt32 codecManf = kAppleSoftwareAudioCodecManufacturer; 246 err = ExtAudioFileSetProperty(s->audioFile, 247 kExtAudioFileProperty_CodecManufacturer, 248 sizeof(UInt32), &codecManf); 249 if (err) { 250 char_t errorstr[20]; 251 AUBIO_ERR("sink_apple_audio: error when trying to set sofware codec on %s " 252 "(%s)\n", s->path, getPrintableOSStatusError(errorstr, err)); 253 goto beach; 254 } 255 #endif 175 256 176 257 err = ExtAudioFileSetProperty(s->audioFile,
Note: See TracChangeset
for help on using the changeset viewer.