iPhoneアプリなどでオーディオデータを再生する方法がいくつかありますが、その中でもAudioUnitを使って複数のチャンネルでボリュームコントロール、定位操作(ミキサー)ができるアプリを制作したいと考えています。
下記URLにあるようなサンプルを弄り倒したのですが、まだよくわかりません。
http://qiita.com/shu223/items/cd612613761720ccc059
objective-c、swift等でミキシングする方法がわかる方、是非教えてくださいー。
#import "AudioPlayer.h"
@implementation AudioPlayer
static OSStatus inputRenderCallback (
void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, // Unused here. UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData
){
soundStruct *soundStructPointer = (soundStruct*) inRefCon; UInt32 frameTotalForSound = soundStructPointer->frameCount; BOOL isStereo = soundStructPointer->isStereo; AudioUnitSampleType *dataInLeft; AudioUnitSampleType *dataInRight = NULL; dataInLeft = soundStructPointer->audioDataLeft; if (isStereo) dataInRight = soundStructPointer->audioDataRight; AudioUnitSampleType *outSamplesChannelLeft; AudioUnitSampleType *outSamplesChannelRight; outSamplesChannelLeft = (AudioUnitSampleType *) ioData->mBuffers[0].mData; if (isStereo) outSamplesChannelRight = (AudioUnitSampleType *) ioData->mBuffers[1].mData; UInt32 sampleNumber = soundStructPointer->sampleNumber; for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) { outSamplesChannelLeft[frameNumber] = dataInLeft[sampleNumber]; if (isStereo) outSamplesChannelRight[frameNumber] = dataInRight[sampleNumber]; sampleNumber++; if (sampleNumber >= frameTotalForSound) sampleNumber = 0; } soundStructPointer->sampleNumber = sampleNumber; return noErr;
}
-
(id) init {
self = [super init];
if (!self) return nil;
memset(&soundStructInfo, 0, sizeof(soundStructInfo));
sampleRate = 44100.0;
[self readAudioFilesIntoMemory];
[self configureUnit];return self;
}
-
(void) readAudioFilesIntoMemory {
NSURL *guitarLoop = [[NSBundle mainBundle] URLForResource: @"synth001" withExtension: @"aiff"];
ExtAudioFileRef audioFileObject = 0;
OSStatus result = ExtAudioFileOpenURL ((__bridge CFURLRef)guitarLoop, &audioFileObject);
// Get the audio file's length in frames.
UInt64 totalFramesInFile = 0;
UInt32 frameLengthPropertySize = sizeof (totalFramesInFile);result = ExtAudioFileGetProperty (
audioFileObject,
kExtAudioFileProperty_FileLengthFrames,
&frameLengthPropertySize,
&totalFramesInFile
);soundStructInfo.frameCount = (UInt32)totalFramesInFile;
AudioStreamBasicDescription fileAudioFormat = {0};
UInt32 formatPropertySize = sizeof (fileAudioFormat);result = ExtAudioFileGetProperty (
audioFileObject,
kExtAudioFileProperty_FileDataFormat,
&formatPropertySize,
&fileAudioFormat
);UInt32 channelCount = fileAudioFormat.mChannelsPerFrame;
soundStructInfo.audioDataLeft =
(AudioUnitSampleType *) calloc (totalFramesInFile, sizeof (AudioUnitSampleType));AudioStreamBasicDescription importFormat = {0};
size_t bytesPerSample = sizeof (AudioUnitSampleType);importFormat.mFormatID = kAudioFormatLinearPCM;
importFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
importFormat.mBytesPerPacket = (UInt32)bytesPerSample;
importFormat.mFramesPerPacket = 1;
importFormat.mBytesPerFrame = (UInt32)bytesPerSample;
importFormat.mBitsPerChannel = 8 * (UInt32)bytesPerSample;
importFormat.mSampleRate = sampleRate;if (2 == channelCount) {
soundStructInfo.isStereo = YES; soundStructInfo.audioDataRight = (AudioUnitSampleType *) calloc (totalFramesInFile, sizeof (AudioUnitSampleType)); importFormat.mChannelsPerFrame = 2;
} else if (1 == channelCount) {
soundStructInfo.isStereo = NO; importFormat.mChannelsPerFrame = 1;
}
fileASBD = importFormat;result = ExtAudioFileSetProperty (
audioFileObject,
kExtAudioFileProperty_ClientDataFormat,
sizeof (importFormat),
&importFormat
);AudioBufferList *bufferList;
bufferList = (AudioBufferList *) malloc (
sizeof (AudioBufferList) + sizeof (AudioBuffer) * (channelCount - 1)
);// initialize the mNumberBuffers member
bufferList->mNumberBuffers = channelCount;// initialize the mBuffers member to 0
AudioBuffer emptyBuffer = {0};
size_t arrayIndex;
for (arrayIndex = 0; arrayIndex < channelCount; arrayIndex++) {
bufferList->mBuffers[arrayIndex] = emptyBuffer;
}// set up the AudioBuffer structs in the buffer list
bufferList->mBuffers[0].mNumberChannels = 1;
bufferList->mBuffers[0].mDataByteSize = totalFramesInFile * sizeof (AudioUnitSampleType);
bufferList->mBuffers[0].mData = soundStructInfo.audioDataLeft;if (2 == channelCount) {
bufferList->mBuffers[1].mNumberChannels = 1;
bufferList->mBuffers[1].mDataByteSize = totalFramesInFile * sizeof (AudioUnitSampleType);
bufferList->mBuffers[1].mData = soundStructInfo.audioDataRight;
}UInt32 numberOfPacketsToRead = (UInt32) totalFramesInFile;
result = ExtAudioFileRead (
audioFileObject,
&numberOfPacketsToRead,
bufferList
);
// free (bufferList);
if (noErr != result) { // If reading from the file failed, then free the memory for the sound buffer. free (soundStructInfo.audioDataLeft); soundStructInfo.audioDataLeft = 0; if (2 == channelCount) { free (soundStructInfo.audioDataRight); soundStructInfo.audioDataRight = 0; } ExtAudioFileDispose (audioFileObject); return; } soundStructInfo.sampleNumber = 0; ExtAudioFileDispose (audioFileObject);
}
文字数オーバーにつき以下省略

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/02 10:39
2016/10/02 10:55
2016/10/02 13:02
2016/10/02 13:06