2016-04-28 14 views
12

tôi đang tạo ra một ứng dụng âm nhạc trong Objective C. tôi cần phải chơi nhiều âm thanh cùng một lúc và tôi có thể đạt được điều này bằng cách sử dụng DiracLE người chơi âm thanh .Objective-C: Làm thế nào để điều khiển âm lượng của nhiều người chơi âm thanh trong DiracLE

Nhưng phương pháp điều khiển âm lượng của Thư viện này - (void) setVolume: (float); dường như không hoạt động.

Mã của tôi cho khởi 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]; 

Phương pháp để thiết lập số lượng người chơi:

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

setVolume: không hoạt động ngay cả đối với người chơi duy nhất và không có ngoại lệ bị ném.

Cách giải quyết vấn đề này?

+0

Bạn có thử giải pháp của tôi? Nó có hoạt động không? – Coder1000

+0

Xin lỗi .. Nó không phải là –

+0

@Elly_Philip Quá xấu:/ – Coder1000

Trả lời

3

Bạn cũng có thể đạt được điều này bằng cách khởi tạo 2 AVAudioPlayers tuần tự, và điều khiển âm lượng với [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]; 
    } 

... 

Trong trường hợp bạn được xác định để sử dụng DiracAudioPlayer, bạn có thể sử dụng phương pháp của riêng bạn để khởi tạo lại các AudioUnit với quyền tham số khối lượng trong 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]; 

} 

đúp kiểm tra rằng khối lượng của bạn đang được thiết lập bằng cách đăng nhập:

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

Ngoài ra bạn cũng có thể điều khiển âm lượng đầu ra của sự pha trộn, bởi cùng một phương pháp được sử dụng bởi các nút âm lượng phần cứng: (Điều này sẽ khởi động giao diện người dùng của một sự thay đổi khối lượng iOS)

-(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

Tôi muốn có lý do cho một downvote nếu có thể. Có lẽ tôi có thể cung cấp một giải pháp tốt hơn, hoặc chỉnh sửa câu trả lời của tôi để làm cho nó dễ hiểu hơn. Cảm ơn –

Các vấn đề liên quan