2016-04-28 49 views
12

我在目的C.創建一個音樂應用程序,我需要同時播放多個聲音,我能夠通過使用DiracLE音頻播放器來實現這一目標。的Objective-C:如何控制的多個音頻播放器的音量在DiracLE

但是這個庫的音量控制方法- (void)setVolume:(float)volume;似乎沒有工作。

我的代碼初始化DiracAudioPlayer:

DiracAudioPlayer *player1,*player2; 
NSURL *url1,*url2; 
NSError *error = nil; 

url1 = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"song1" ofType:@"mp3"]]; 
url2 = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"song2" ofType:@"mp3"]]; 

player1 = [[DiracAudioPlayer alloc] initWithContentsOfURL:mainURL channels:1 error:&error]; 
[player1 setDelegate:self]; 
player2 = [[DiracAudioPlayer alloc] initWithContentsOfURL:mainURL channels:1 error:&error]; 
[player2 setDelegate:self]; 

方法來設置播放器的體積:

-(void)setPlayerVolume 
{ 
    [player1 setVolume:0.5]; 
    [player2 setVolume:0.2]; 
} 

setVolume:甚至沒有爲單人工作,沒有拋出異常。

如何解決這個問題?

+0

您是否試試我的解決方案它有用嗎? – Coder1000

+0

對不起。它沒有 –

+0

@Elly_Philip太糟糕了:/ – Coder1000

回答

3

您還可以通過初始化2 AVAudioPlayers順序,以及控制與[self.player setVolume:volumeFloat];

... 

    NSString *songA = [[NSBundle mainBundle] pathForResource:@"songA" ofType:@"mp3"]; 
    NSError *soundError = nil; 
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:songA] error:&soundError]; 
    if(self.player == nil) 
     NSLog(@"%@",soundError); 
    else 
    { 
     [self.player setDelegate:self]; 
     [self.player setVolume:0.75]; 
     [self.player play]; 
    } 

    NSString *songB = [[NSBundle mainBundle] pathForResource:@"songB" ofType:@"mp3"]; 
    soundError = nil; 
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:songB] error:&soundError]; 
    if(self.player == nil) 
     NSLog(@"%@",soundError); 
    else 
    { 
     [self.player setDelegate:self]; 
     [self.player setVolume:0.25]; 
     [self.player play]; 
    } 

... 

如果你有決心使用DiracAudioPlayer,你可以用你自己的方法與正確的重新初始化AudioUnit體積達到這個在DiracAudioPlayerBase.mm體積參數:

-(void)setupInstanceWithUrl:(NSURL*)inUrl numChannels:(int)channels volume:(float)volume 
{ 
    mDelegate = nil; 
    mInUrl = [inUrl copy]; 
    mIsPrepared = NO; 
    mIsProcessing = NO; 
    mWorkerThread = nil; 
    mTotalFramesInFile = 0; 
    mIsRunning = NO; 
    mVolume = volume; 
    mLoopCount = mNumberOfLoops = 0; 
    mHasFinishedPlaying = YES; 

    if (channels < 1) channels = 1; 
    else if (channels > 2) channels = 2; 
    mNumChannels = channels; 

    mPeak = new SInt16[mNumChannels]; 
    mPeakOut = new SInt16[mNumChannels]; 

    for (long v = 0; v < mNumChannels; v++) { 
     mPeakOut[v] = 0; 
     mPeak[v] = -1; 
    } 

    OSStatus status = noErr; 
    mTimeFactor = 1./kOversample; 
    mPitchFactor = kOversample; 
    // This is boilerplate code to set up CoreAudio on iOS in order to play audio via its default output 

    // Desired audio component 
    AudioComponentDescription desc; 
    desc.componentType = kAudioUnitType_Output; 
#if TARGET_OS_IPHONE 
    desc.componentSubType = kAudioUnitSubType_RemoteIO; 
#else 
    desc.componentSubType = kAudioUnitSubType_HALOutput; 
#endif 
    desc.componentManufacturer = kAudioUnitManufacturer_Apple; 
    desc.componentFlags = 0; 
    desc.componentFlagsMask = 0; 

    // Get ref to component 
    AudioComponent defaultOutput = AudioComponentFindNext(NULL, &desc); 

    // Get matching audio unit 
    status = AudioComponentInstanceNew(defaultOutput, &mAudioUnit); 
    checkStatus(status); 

    // this is the format we want 
    AudioStreamBasicDescription audioFormat; 
    mSampleRate=audioFormat.mSampleRate   = 44100.00; 
    audioFormat.mFormatID   = kAudioFormatLinearPCM; 
    audioFormat.mFormatFlags  = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
    audioFormat.mFramesPerPacket = 1; 
    audioFormat.mChannelsPerFrame = mNumChannels; 
    audioFormat.mBitsPerChannel  = 16; 
    audioFormat.mBytesPerPacket  = sizeof(short)*mNumChannels; 
    audioFormat.mBytesPerFrame  = sizeof(short)*mNumChannels; 

    status = AudioUnitSetProperty(mAudioUnit, 
            kAudioUnitProperty_StreamFormat, 
            kAudioUnitScope_Input, 
            kOutputBus, 
            &audioFormat, 
            sizeof(audioFormat)); 
    checkStatus(status); 

    // here we set up CoreAudio in order to call our PlaybackCallback 
    AURenderCallbackStruct callbackStruct; 
    callbackStruct.inputProc = PlaybackCallback; 
    callbackStruct.inputProcRefCon = (__bridge void*) self; 
    status = AudioUnitSetProperty(mAudioUnit, 
            kAudioUnitProperty_SetRenderCallback, 
            kAudioUnitScope_Input, 
            kOutputBus, 
            &callbackStruct, 
            sizeof(callbackStruct)); 
    checkStatus(status); 


    // Initialize unit 
    status = AudioUnitInitialize(mAudioUnit); 
    checkStatus(status); 

    // here we allocate our audio cache 
    mAudioBuffer = AllocateAudioBufferSInt16(mNumChannels, kAudioBufferNumFrames); 

    // Avoid delay when hitting play by making sure the graph is pre-initialized 
    AudioOutputUnitStart(mAudioUnit); 
    AudioOutputUnitStop(mAudioUnit); 

    [self prepareToPlay]; 

} 

仔細檢查你的音量的方式記錄設置:

NSLog(@"Volume P1: %f", [player1 volume]); 
NSLog(@"Volume P2: %f", [player2 volume]); 

此外還可以控制混合物的輸出音量,由硬件音量按鈕使用的相同的方法,包括:(這將啓動的iOS體積變化的UI)

-(void)addVolumeObserver { 

    MPVolumeView *volumeView = [MPVolumeView new]; 
    volumeView.showsRouteButton = NO; 
    volumeView.showsVolumeSlider = NO; 
    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; 
    [appDelegate.window.rootViewController.view addSubview:volumeView]; 


    __weak __typeof(self)weakSelf = self; 
    [[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     if ([obj isKindOfClass:[UISlider class]]) { 
      __strong __typeof(weakSelf)strongSelf = weakSelf; 
      strongSelf->volumeSlider = obj; 
      [obj addTarget:strongSelf action:@selector(handleVolumeChanged:) forControlEvents:UIControlEventValueChanged]; 
      *stop = YES; 
     } 
    }]; 
} 

- (void)handleVolumeChanged:(id)sender 
{ 
    NSLog(@"Volume: %f", volumeSlider.value); 
} 

- (void)setVolumeHandlerTo:(float)volume 
{ 
    volumeSlider.value = volume; 
} 
+0

我想如果可能的話downvote的原因。也許我可以提供更好的解決方案,或編輯我的答案,使其更容易理解。謝謝 –

相關問題