質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

iPad

iPadは、Appleがデザインしたタブレット型コンピュータです。iPadアプリケーションは通常Xcode IDEのObjective-Cで書かれますが、iPadアプリケーションを組むためのほかのツールを使うことも可能です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

1回答

3689閲覧

【CoreAudio】AudioUnitでオーディオデータ再生【iOS】

otokichi_

総合スコア25

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

iPad

iPadは、Appleがデザインしたタブレット型コンピュータです。iPadアプリケーションは通常Xcode IDEのObjective-Cで書かれますが、iPadアプリケーションを組むためのほかのツールを使うことも可能です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2016/10/02 06:09

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);

}

文字数オーバーにつき以下省略

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

iOS8以上ならAVAudioEngineを使ったらどうでしょうか?
できることはCoreAudioに比べて減りますが、swiftとの相性はいいです。

Appleのサンプルコードがあります。Obj-Cです。PlayerNodeのところにPanがあります。

https://developer.apple.com/library/content/samplecode/AVAEMixerSample/Introduction/Intro.html

AVAudioEngineの概要についてはこの辺のVideoがオススメです。

https://developer.apple.com/videos/play/wwdc2014/502/

ObjCのサンプルをswiftに書き換えた方もいるようです。
https://github.com/ooper-shlab/AVAEMixerSample-Swift

[追記]
CoreAudioの場合、最も簡単にやるには、

https://developer.apple.com/library/content/samplecode/iOSMultichannelMixerTest/Introduction/Intro.html

上記サンプルで、kMultiChannelMixerParam_Volumeの代わりにkMultiChannelMixerParam_Panを使えばできます。

投稿2016/10/02 08:09

編集2016/10/02 10:53
pebble8888

総合スコア390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otokichi_

2016/10/02 10:39

たしかにAVAEなら読みやすいし簡単にできそうでした。 でも、低レイテンシでこだわりのあるアプリにするためにもAUでやりたいんですよ。 またなにか情報だけでもありましたら書き込んでいただきたいと思います。 ありがとうございました。
pebble8888

2016/10/02 10:55

CoreAudioでやる場合も記載を追加しました。
otokichi_

2016/10/02 13:02

ご丁寧にありがとうございます。これはVolumeをパンに変える方法でしょうか。 ボリュームもコントロールできて、パンも振れて、エフェクトもかけれて・・・となるとAUを繋ぎ合わせていけば良いのはイメージができますが。(難しそう) まずは、一般的なDAWのように 複数のオーディオファイルをそれぞれのUISliderでボリュームコントロールするところから始めたいです。もしわかれば教えてください!!
otokichi_

2016/10/02 13:06

教えていただいた 「Using an AUGraph with the Multi-Channel Mixer and Remote I/O Audio Unit 」 のサンプルは2chミキサーですね。これのチャンネル数を増やしたいんですが、複雑すぎて理解が難しいです・・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問