#include "config.h"
#include "aubio_priv.h"
#include "fvec.h"
+#include "fmat.h"
#include "io/source_apple_audio.h"
// ExtAudioFileRef, AudioStreamBasicDescription, AudioBufferList, ...
struct _aubio_source_apple_audio_t {
uint_t channels;
- uint_t samplerate;
+ uint_t samplerate; //< requested samplerate
+ uint_t source_samplerate; //< actual source samplerate
uint_t block_size;
char_t *path;
aubio_source_apple_audio_t * s = AUBIO_NEW(aubio_source_apple_audio_t);
s->path = path;
- s->samplerate = samplerate;
s->block_size = block_size;
- s->channels = 1;
OSStatus err = noErr;
UInt32 propSize;
- AudioStreamBasicDescription clientFormat;
- propSize = sizeof(clientFormat);
- memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
- clientFormat.mFormatID = kAudioFormatLinearPCM;
- clientFormat.mSampleRate = (Float64)(s->samplerate);
- clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
- clientFormat.mChannelsPerFrame = s->channels;
- clientFormat.mBitsPerChannel = sizeof(short) * 8;
- clientFormat.mFramesPerPacket = 1;
- clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
- clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
- clientFormat.mReserved = 0;
-
// open the resource url
CFURLRef fileURL = getURLFromPath(path);
err = ExtAudioFileOpenURL(fileURL, &s->audioFile);
kExtAudioFileProperty_FileDataFormat, &propSize, &fileFormat);
if (err) { AUBIO_ERROR("error in ExtAudioFileGetProperty, %d\n", (int)err); goto beach;}
- if (s->samplerate == 1) {
- clientFormat.mSampleRate = fileFormat.mSampleRate;
- s->samplerate = fileFormat.mSampleRate;
+ if (samplerate == 0) {
+ samplerate = fileFormat.mSampleRate;
+ //AUBIO_DBG("sampling rate set to 0, automagically adjusting to %d\n", samplerate);
}
+ s->samplerate = samplerate;
+ s->source_samplerate = fileFormat.mSampleRate;
+ s->channels = fileFormat.mChannelsPerFrame;
+
+ AudioStreamBasicDescription clientFormat;
+ propSize = sizeof(clientFormat);
+ memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
+ clientFormat.mFormatID = kAudioFormatLinearPCM;
+ clientFormat.mSampleRate = (Float64)(s->samplerate);
+ clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
+ clientFormat.mChannelsPerFrame = s->channels;
+ clientFormat.mBitsPerChannel = sizeof(short) * 8;
+ clientFormat.mFramesPerPacket = 1;
+ clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
+ clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
+ clientFormat.mReserved = 0;
// set the client format description
err = ExtAudioFileSetProperty(s->audioFile, kExtAudioFileProperty_ClientDataFormat,
propSize, &clientFormat);
- if (err) { AUBIO_ERROR("error in ExtAudioFileSetProperty, %d\n", (int)err); goto beach;}
-
-#if 0
+ if (err) {
+ AUBIO_ERROR("error in ExtAudioFileSetProperty, %d\n", (int)err);
+#if 1
// print client and format descriptions
AUBIO_DBG("Opened %s\n", s->path);
AUBIO_DBG("file/client Format.mFormatID: : %3c%c%c%c / %c%c%c%c\n",
AUBIO_DBG("file/client Format.mBytesPerPacket : %6d / %d\n", (int)fileFormat.mBytesPerPacket , (int)clientFormat.mBytesPerPacket);
AUBIO_DBG("file/client Format.mReserved : %6d / %d\n", (int)fileFormat.mReserved , (int)clientFormat.mReserved);
#endif
+ goto beach;
+ }
// compute the size of the segments needed to read the input file
UInt32 samples = s->block_size * clientFormat.mChannelsPerFrame;
} else if (rateRatio > 1.) {
AUBIO_WRN("up-sampling %s from %0.2fHz to %0.2fHz\n", s->path, fileFormat.mSampleRate, clientFormat.mSampleRate);
} else {
- assert (segmentSize == samples );
+ assert ( segmentSize == samples );
//AUBIO_DBG("not resampling, segmentSize %d, block_size %d\n", segmentSize, s->block_size);
}
void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to, uint_t * read) {
UInt32 c, v, loadedPackets = s->block_size;
OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
- if (err) { AUBIO_ERROR("error in ExtAudioFileRead, %d\n", (int)err); goto beach;}
+ if (err) { AUBIO_ERROR("error in ExtAudioFileRead %s %d\n", s->path, (int)err); goto beach;}
+
+ short *data = (short*)s->bufferList.mBuffers[0].mData;
smpl_t *buf = read_to->data;
+ for (v = 0; v < loadedPackets; v++) {
+ buf[v] = 0.;
+ for (c = 0; c < s->channels; c++) {
+ buf[v] += SHORT_TO_FLOAT(data[ v * s->channels + c]);
+ }
+ buf[v] /= (smpl_t)s->channels;
+ }
+ // short read, fill with zeros
+ if (loadedPackets < s->block_size) {
+ for (v = loadedPackets; v < s->block_size; v++) {
+ buf[v] = 0.;
+ }
+ }
+
+ *read = (uint_t)loadedPackets;
+ return;
+beach:
+ *read = 0;
+ return;
+}
+
+void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) {
+ UInt32 c, v, loadedPackets = s->block_size;
+ OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
+ if (err) { AUBIO_ERROR("source_apple_audio: error in ExtAudioFileRead, %d\n", (int)err); goto beach;}
+
short *data = (short*)s->bufferList.mBuffers[0].mData;
- if (buf) {
+ smpl_t **buf = read_to->data;
+
+ for (v = 0; v < loadedPackets; v++) {
+ for (c = 0; c < s->channels; c++) {
+ buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + c]);
+ }
+ }
+ // short read, fill with zeros
+ if (loadedPackets < s->block_size) {
+ for (v = loadedPackets; v < s->block_size; v++) {
for (c = 0; c < s->channels; c++) {
- for (v = 0; v < s->block_size; v++) {
- if (v < loadedPackets) {
- buf[v * s->channels + c] =
- SHORT_TO_FLOAT(data[ v * s->channels + c]);
- } else {
- buf[v * s->channels + c] = 0.f;
- }
- }
+ buf[c][v] = 0.;
}
+ }
}
- //if (loadedPackets < s->block_size) return EOF;
*read = (uint_t)loadedPackets;
return;
beach:
return;
}
+uint_t aubio_source_apple_audio_seek (aubio_source_apple_audio_t * s, uint_t pos) {
+ SInt64 resampled_pos = (SInt64)ROUND( pos * s->source_samplerate * 1. / s->samplerate );
+ OSStatus err = ExtAudioFileSeek(s->audioFile, resampled_pos);
+ if (err) AUBIO_ERROR("source_apple_audio: error in ExtAudioFileSeek (%d)\n", (int)err);
+ return err;
+}
+
uint_t aubio_source_apple_audio_get_samplerate(aubio_source_apple_audio_t * s) {
return s->samplerate;
}
+uint_t aubio_source_apple_audio_get_channels(aubio_source_apple_audio_t * s) {
+ return s->channels;
+}
+
#endif /* __APPLE__ */