[iPhone]AUGraph AudioFilePlayerでのエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Hi_L
記事: 7
登録日時: 12年前

[iPhone]AUGraph AudioFilePlayerでのエラー

#1

投稿記事 by Hi_L » 12年前

現在音楽関係のアプリを作ろうとしており、以下のサンプルコードを参考にしながら作っています。
https://github.com/tkzic/audiograph

見よう見まねで作っていってシンセサイザーはできたのですが、
ファイルを読み込んで再生という所でエラーが出て再生できません。
色々調べてみたのですが、結局原因は分かりませんでした。
どうすれば上手く再生できるようになるでしょうか。

現在のコードは以下のようになっております。

コード:

    //AUGraph関係
    AUGraph    m_AUGraph;
    
    //AudioUnit
    AudioUnit  remoteIOAudioUnit;
    AudioUnit  multiChannelMixerAudioUnit;
    AudioUnit  audioFilePlayerUnit;
    
    //Node
    AUNode remoteIONode;
    AUNode multiChannelMixerNode;
    AUNode audioFilePlayerNode;
    
    AudioFileID filePlayerFile;

-(id)init{
    
    if(self = [super init]){
        OSStatus err = noErr;
        
        Float64 sampleRate = 44100.0;
        
        UInt32 maximumFramesPerSlice = 4096;
        
        UInt32 busCount             = WAVE_NUM + 2;
        //UInt32 samplerBus           = WAVE_NUM;
        UInt32 audioFilePlayerBus   = WAVE_NUM + 1;
        
        //AUGraphをインスタンス化
        err = NewAUGraph(&m_AUGraph);
        if(err){
            NSLog(@"err = %ld", err);
        }
        
        err = AUGraphOpen(m_AUGraph);
        if(err){
            NSLog(@"err = %ld", err);
        }
        
        //RemoteIO AudioUnitのAudioComponatDescriptionを作成
        AudioComponentDescription cd;
        cd.componentType         = kAudioUnitType_Output;
        cd.componentSubType      = kAudioUnitSubType_RemoteIO;
        cd.componentManufacturer = kAudioUnitManufacturer_Apple;
        cd.componentFlags        = 0;
        cd.componentFlagsMask    = 0;
    
        //AUGraphにRemoteIOのノードを追加
        err = AUGraphAddNode(m_AUGraph, &cd, &remoteIONode);
        if(err){
             NSLog(@"AUGraphAddNode failed (remoteIONode) err = %ld", err);
        }
        
        //MultiChannelMixerのAudioComponentDescriptionを用意する
        cd.componentType    = kAudioUnitType_Mixer;
        cd.componentSubType = kAudioUnitSubType_MultiChannelMixer;
    
        //AUGraphにMultiChannelMixerのノードを追加
        err = AUGraphAddNode(m_AUGraph, &cd, &multiChannelMixerNode);
        if(err){
            NSLog(@"AUGraphAddNode failed (multiChannelMixerNode) err = %ld", err);
        }
        
        //audioFilePlayerUnitのAudioComponatDescriptionを作成
        cd.componentType        = kAudioUnitType_Generator;
        cd.componentSubType     = kAudioUnitSubType_AudioFilePlayer;
        
        //AUGraphにaudioFilePlayerのノードを追加
        err = AUGraphAddNode(m_AUGraph, &cd, &audioFilePlayerNode);
        if(err){
            NSLog(@"AUGraphAddNode failed (audioFilePlayerNode) err = %ld", err);
        }
        
        
        //それぞれのAudioUnitを取得
        err = AUGraphNodeInfo(m_AUGraph, remoteIONode, NULL, &remoteIOAudioUnit);
        if(err){
            NSLog(@"AUGraphNodeInfo failed (remoteIONode) err = %ld", err);
        }
        err = AUGraphNodeInfo(m_AUGraph, multiChannelMixerNode, NULL, &multiChannelMixerAudioUnit);
        if(err){
            NSLog(@"AUGraphNodeInfo failed (multiChannelMixerNode) err = %ld", err);
        }
        err = AUGraphNodeInfo(m_AUGraph, audioFilePlayerNode, NULL, &audioFilePlayerUnit);
        if(err){
            NSLog(@"AUGraphNodeInfo failed (audioFilePlayerNode) err = %ld", err);
        }
        
        
        //RemoteIO ← MultiChannelMixer ← AudioFilePlayer
        
        //audioFilePlayerNodeからmultiChannelMixerNodeに繫ぐ
        err = AUGraphConnectNodeInput(m_AUGraph, audioFilePlayerNode, 0, multiChannelMixerNode, audioFilePlayerBus);
        if(err){
            NSLog(@"AUGraphConnectNodeInput failed (audioFilePlayerNode 0 to multiChannelMixerNode 9) err = %ld", err);
        }
        
        //multiChannelMixerNodeからremoteIONodeに繫ぐ
        err = AUGraphConnectNodeInput(m_AUGraph, multiChannelMixerNode, 0, remoteIONode, 0);
        if(err){
            NSLog(@"AUGraphConnectNodeInput failed (multiChannelMixerNode 0 to remoteIONode 0) err = %ld", err);
        }
        
        
        //MultiChannelMixerのコールバックを設定
        for(int i=0; i<WAVE_NUM; i++){
            AURenderCallbackStruct callbackStruct;
            callbackStruct.inputProc       = synthRenderCallback;//呼び出すコールバック関数の設定
            callbackStruct.inputProcRefCon = &m_tWaveDef[i];//コールバック内の参照データのポインタ
            //コールバック関数の設定
            err = AUGraphSetNodeInputCallback(m_AUGraph,
                                              multiChannelMixerNode,
                                              i,
                                              &callbackStruct);
            if(err){
                NSLog(@"AUGraphSetNodeInputCallback failed (multiChannelMixerNode bus %d) err = %ld", i, err);
            }
            
        }
        
        
        
        //AudioUnit正準形
        AudioStreamBasicDescription audioFormat;
        audioFormat.mSampleRate       = sampleRate;
        audioFormat.mFormatID         = kAudioFormatLinearPCM;
        audioFormat.mFormatFlags      = 41;
        audioFormat.mChannelsPerFrame = channel;
        audioFormat.mBytesPerPacket   = sizeof(AudioUnitSampleType);
        audioFormat.mBytesPerFrame    = sizeof(AudioUnitSampleType);
        audioFormat.mFramesPerPacket  = 1;
        audioFormat.mBitsPerChannel   = 8 * sizeof(AudioUnitSampleType);
        audioFormat.mReserved         = 0;

        
    
        //RemoteIO
        
        //remoteIOAudioUnitにASBDを設定
        err = AudioUnitSetProperty(remoteIOAudioUnit,
                                   kAudioUnitProperty_StreamFormat,
                                   kAudioUnitScope_Input,
                                   0,
                                   &audioFormat,
                                   sizeof(audioFormat));
        if(err){
            NSLog(@"AudioUnitSetProperty failed (remoteIOAudioUnit kAudioUnitProperty_StreamFormat kAudioUnitScope_Input) err = %ld", err);
        }
        
        
        
        //MultiChannelMixer
        //multiChannelMixerAudioUnitにASBDを設定
        err = AudioUnitSetProperty(multiChannelMixerAudioUnit,
                                   kAudioUnitProperty_StreamFormat,
                                   kAudioUnitScope_Output,
                                   0,
                                   &audioFormat,
                                   sizeof(audioFormat));
        if(err){
            NSLog(@"AudioUnitSetProperty failed (multiChannelMixerAudioUnit kAudioUnitProperty_StreamFormat kAudioUnitScope_Output) err = %ld", err);
        }
        
        //maximumFramesPerSliceを設定
        err = AudioUnitSetProperty (multiChannelMixerAudioUnit,
                                    kAudioUnitProperty_MaximumFramesPerSlice,
                                    kAudioUnitScope_Global,
                                    0,
                                    &maximumFramesPerSlice,
                                    sizeof (maximumFramesPerSlice)
                                    );
        if(err){
            NSLog(@"AudioUnitSetProperty failed (multiChannelMixerAudioUnit kAudioUnitProperty_MaximumFramesPerSlice kAudioUnitScope_Global) err = %ld", err);
        }
        
        err = AudioUnitSetProperty (multiChannelMixerAudioUnit,
                                    kAudioUnitProperty_ElementCount,
                                    kAudioUnitScope_Input,
                                    0,
                                    &busCount,
                                    sizeof (busCount));
        if(err){
            NSLog(@"AudioUnitSetProperty failed (multiChannelMixerAudioUnit kAudioUnitProperty_ElementCount kAudioUnitScope_Input) err = %ld", err);
        }
        
        //AudioFilePlayer
        //ASBDを設定
        err = AudioUnitSetProperty(audioFilePlayerUnit,
                                   kAudioUnitProperty_StreamFormat,
                                   kAudioUnitScope_Output,
                                   0,
                                   &audioFormat,
                                   sizeof(audioFormat));
        if(err){
            NSLog(@"AudioUnitSetProperty failed (audioFilePlayerUnit kAudioUnitProperty_StreamFormat kAudioUnitScope_Output) err = %ld", err);
        }
        
        //AudioFilePlayerの設定
        err = [self setUPAudioFilePlayer: @"A3" :@"m4a"];
        if(err){
            NSLog(@"setUPAudioFilePlayer failed err = %ld", err);
        }

        CAShow(m_AUGraph);
        
        //AUGraphを初期化
        err = AUGraphInitialize(m_AUGraph);
        if(err){
            NSLog(@"AUGraphInitialize failed err = %ld", err);
        }
    }
    return self;
}


//AudioFilePlayerの設定
-(OSStatus)setUPAudioFilePlayer :(NSString*)pathForResource :(NSString*)ofType{

    OSStatus err = noErr;
    
    NSString *filePath = [[NSBundle mainBundle] pathForResource:pathForResource ofType:ofType];
    CFURLRef audioURL = ( CFURLRef) [NSURL fileURLWithPath:filePath];
    
    //ファイルオープン
    err = AudioFileOpenURL(audioURL, kAudioFileReadPermission, 0, &filePlayerFile);
    if(err){
        NSLog(@"AudioFileOpenURL failed err = %ld", err);
    }
    
    //audioFilePlayerUnitにオーディオファイルをぶっ込む
    err = AudioUnitSetProperty(audioFilePlayerUnit,
                               kAudioUnitProperty_ScheduledFileIDs,
                               kAudioUnitScope_Global,
                               0,
                               &filePlayerFile,
                               sizeof(filePlayerFile));
    if(err){
        NSLog(@"AudioUnitSetProperty failed (audioFilePlayerUnit kAudioUnitProperty_ScheduledFileIDs kAudioUnitScope_Global) err = %ld", err);
    }
    
    UInt64 nPackets;
	UInt32 propsize = sizeof(nPackets);
    
    err = AudioFileGetProperty(filePlayerFile, kAudioFilePropertyAudioDataPacketCount, &propsize, &nPackets);
    if(err){
        NSLog(@"AudioFileGetProperty failed (kAudioFilePropertyAudioDataPacketCount) err = %ld", err);
    }
    
    //ファイルのASBDを取得
    AudioStreamBasicDescription fileASBD;
    UInt32 fileASBDPropSize = sizeof(fileASBD);

    err = AudioFileGetProperty(filePlayerFile, kAudioFilePropertyDataFormat, &fileASBDPropSize, &fileASBD);
    if(err){
        NSLog(@"couldn't get file's data format err = %ld", err);
    }
    
    ScheduledAudioFileRegion rgn;
    
	memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp));
	rgn.mTimeStamp.mFlags       = kAudioTimeStampSampleTimeValid;
	rgn.mTimeStamp.mSampleTime  = 0;
	rgn.mCompletionProc         = NULL;
	rgn.mCompletionProcUserData = NULL;
	rgn.mAudioFile              = filePlayerFile;
	rgn.mLoopCount              = INT_MAX;
	rgn.mStartFrame             = 0;
	rgn.mFramesToPlay           = nPackets * fileASBD.mFramesPerPacket;

//ここでエラーが発生します errの値は-10867
    err = AudioUnitSetProperty(audioFilePlayerUnit, kAudioUnitProperty_ScheduledFileRegion, kAudioUnitScope_Global, 0, &rgn, sizeof(rgn));
    if(err){
        NSLog(@"AudioUnitSetProperty failed (audioFilePlayerUnit kAudioUnitProperty_ScheduledFileRegion kAudioUnitScope_Global) err = %ld", err);
    }
    
    UInt32 defaultVal = 0;
//ここでもエラーが発生します errの値は-10867
    err = AudioUnitSetProperty(audioFilePlayerUnit, kAudioUnitProperty_ScheduledFilePrime, kAudioUnitScope_Global, 0, &defaultVal, sizeof(defaultVal));
    if(err){
        NSLog(@"AudioUnitSetProperty failed (audioFilePlayerUnit kAudioUnitProperty_ScheduledFilePrime kAudioUnitScope_Global) err = %ld", err);
    }
    
    //StartTimeを-1にすることによってループ再生になるらしい
    AudioTimeStamp startTime;
	memset (&startTime, 0, sizeof(startTime));
	startTime.mFlags        = kAudioTimeStampSampleTimeValid;
	startTime.mSampleTime   = rgn.mFramesToPlay;
    err = AudioUnitSetProperty(audioFilePlayerUnit, kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &startTime, sizeof(startTime));
    if(err){
        NSLog(@"AudioUnitSetProperty failed (audioFilePlayerUnit kAudioUnitProperty_ScheduleStartTimeStamp kAudioUnitScope_Global) err = %ld", err);
    }
    
    return noErr;

}


takechan

Re: [iPhone]AUGraph AudioFilePlayerでのエラー

#2

投稿記事 by takechan » 11年前

AUGraphInitializeをしてからsetUPAudioFilePlayerの処理を実行する必要があります。

閉鎖

“C言語何でも質問掲示板” へ戻る