トップ «前の日記(2012-04-03) 最新 次の日記(2012-04-05)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|

2012-04-04 [iOS]Looping Recorderの基礎(Audio Unit (6))

録音したデータを再生しようとしたが、上手くいかなかったので、アプリケーション内部で生成したサイン波の再生から、一歩ずつ進める事にした。

再生部を検討していて、録音部で使用したAudio Unit Processing Graph Servicesの使用方法は見直した方が良さそうだったので、再生部はAudio Unitを直接生成した。ヘッダーの内容は以下のとおり。

再生はAudioUnitを直接生成した。

@interface AudioUnitViewController : UIViewController
	:
@property (nonatomic, assign) AudioUnit                     audioUnit;
@property (nonatomic, assign) double                        phase;
@property (nonatomic, assign) Float64                       sampleRate;
@property (nonatomic, assign) BOOL                          isPlaying;
	:
@end

Audio Unitの生成メソッドだ。

- (void)prepareAudioUnit
{
    AudioComponentDescription   cd;
    cd.componentType            = kAudioUnitType_Output;
    cd.componentSubType         = kAudioUnitSubType_RemoteIO;
    cd.componentManufacturer    = kAudioUnitManufacturer_Apple;
    cd.componentFlags           = 0;
    cd.componentFlagsMask       = 0;
 
    AudioComponent  component = AudioComponentFindNext(NULL, &cd);
    AudioComponentInstanceNew(component, &__audioUnit);
    AudioUnitInitialize(self.audioUnit);
    AURenderCallbackStruct  callbackStruct;
    callbackStruct.inputProc = MyPlayAURenderCallack;
    callbackStruct.inputProcRefCon = self;
    AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callbackStruct, sizeof(AURenderCallbackStruct));
 
    self.phase = 0.0;
    self.sampleRate = 44100.0;
    
    AudioStreamBasicDescription audioFormat = [self auCanonicalASBDSampleRate:self.sampleRate channel:2];
    
    AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &audioFormat, sizeof(AudioStreamBasicDescription));
}

再生のコールバック関数。サイン波を設定している。

static OSStatus MyPlayAURenderCallack (
                                       void                        *inRefCon,
                                       AudioUnitRenderActionFlags  *ioActionFlags,
                                       const AudioTimeStamp        *inTimeStamp,
                                       UInt32                      inBusNumber,
                                       UInt32                      inNumberFrames,
                                       AudioBufferList             *ioData
                                       )
{
    AudioUnitViewController *viewController = (AudioUnitViewController *)inRefCon;
    float   freq = 440 * 2.0 * M_PI / viewController.sampleRate;
    double  phase = viewController.phase;
    AudioUnitSampleType *outL = ioData->mBuffers[0].mData;
    AudioUnitSampleType *outR = ioData->mBuffers[1].mData;
    for (int i = 0; i < inNumberFrames; i++) {
        float   wave = sin(phase);
        AudioUnitSampleType sample = wave * (1 << kAudioUnitSampleFractionBits);
        *outL++ = sample;
        *outR++ = sample;
        phase = phase + freq;
    }
    viewController.phase = phase;
    return noErr;
}

色々、デバッグ出力を入れている為か、スムーズでないか、鳴るようになった。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/DemoAudio - GitHub

_ 関連情報

Cocoa Life KOF2011特別編 - Facebook
Cocoa勉強会 関西の会誌。
iPhone Core Audioプログラミング(永野 哲久 著)
とれも参考にさせていただきました。

トップ «前の日記(2012-04-03) 最新 次の日記(2012-04-05)» 編集