2016-04-28 13 views
12

sto creando un'applicazione musicale Objective C. ho bisogno di giocare più suoni contemporaneamente e sono in grado di raggiungere questo obiettivo utilizzando DiracLE lettori audio .Objective-C: Come controllare il volume di più lettori audio in DiracLE

Ma il metodo di controllo del volume di questa libreria - (void) setVolume: volume (float); non sembra funzionare.

mio codice per l'inizializzazione 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]; 

metodo per impostare i volumi giocatore:

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

setVolume: non funziona anche per i single player e non ci sono eccezioni lanciate.

Come risolvere questo?

+0

avete fatto prova la mia soluzione? Ha funzionato ? – Coder1000

+0

Siamo spiacenti .. Non è stato –

+0

@ Elly_Philip Peccato:/ – Coder1000

risposta

3

Si potrebbe anche raggiungere questo obiettivo l'inizializzazione 2 AVAudioPlayers in sequenza, ed il controllo del volume con [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]; 
    } 

... 

Nel caso in cui si sono decisi a utilizzare DiracAudioPlayer, è possibile utilizzare il proprio metodo per reinizializzare l'AudioUnit con la destra parametro del volume in 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]; 

} 

doppio controllo che il volume è stato impostato per la registrazione:

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

Inoltre è anche possibile controllare il volume di uscita del mix, con lo stesso metodo usato dai pulsanti del volume hardware: (Questo lancerà l'interfaccia utente di un cambiamento di volume 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

Vorrei un motivo per un downvote se possibile. Forse posso fornire una soluzione migliore o modificare la mia risposta per renderla più comprensibile. Grazie –