将音频文件保存在后台

时间:2016-02-26 19:52:43

标签: ios audio avaudioplayer avaudioengine

我有一个应用程序,当选择音高按钮时会改变音频的音高,现在我使用installTapOnBus来保存文件,但这个方法在我按下音高按钮后被调用,因此只有部分保存音频,我想保存整个音频,无论何时选择音高按钮,有什么办法

此方法用于播放音频

-(void)playAudio
{
    NSError *err = nil;

    audioEngine = [[AVAudioEngine alloc] init];
    AudioFileplayer = [[AVAudioPlayerNode alloc] init];
    pitch = [[AVAudioUnitTimePitch alloc] init];
    reverb = [[AVAudioUnitReverb alloc] init];
    [audioEngine stop];
    [AudioFileplayer stop];
    [audioEngine reset];

    file = [[AVAudioFile alloc] initForReading:[NSURL URLWithString:[self filePath]] error:&err];


    [audioEngine attachNode:AudioFileplayer];

    [audioEngine attachNode:pitch];
    [audioEngine attachNode:reverb];

    [audioEngine connect:AudioFileplayer to:reverb format:nil];
    [audioEngine connect:reverb to:pitch format:nil];
    [audioEngine connect:pitch to:audioEngine.outputNode format:nil];
    [reverb loadFactoryPreset:AVAudioUnitReverbPresetLargeRoom2];

 [AudioFileplayer scheduleFile:file atTime:nil completionHandler:^{
        AudioFileplayer = nil;
    }];

    [audioEngine prepare];
    [audioEngine startAndReturnError:&err];

    if (err != nil) {
        NSLog(@"An error occured");
    }

    [AudioFileplayer play];



}

此方法可以保存音调影响音频

-(void)saveEffectedAudioToFolder
{
NSError *error;
if (audioEngine) {


     pitchEffect.pitch = 1000;

    AVAudioFormat  * commonFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32 sampleRate:44100 channels:2 interleaved:NO];

    //
    AVAudioFile *outputFile = [[AVAudioFile alloc] initForWriting:[NSURL URLWithString:[self filePath1]] settings:commonFormat.settings error:&error];
    //


    if (error) {
        NSLog(@"Error is 1 %@",[error localizedDescription]);


    }
    [pitchEffect  installTapOnBus:0 bufferSize:4096 format:commonFormat block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when)
     {

         if (outputFile.length < file.length)
         {//Let us know when to stop saving the file, otherwise saving infinitely
             NSError *error;

             NSAssert([outputFile writeFromBuffer:buffer error:&error], @"error writing buffer data to file, %@", [error localizedDescription]);

         }else{
             audioEngine = nil;
             [pitchEffect removeTapOnBus:0];//if we dont remove it, will keep on tapping infinitely

         }

     }


     ];
}

}

任何解决方法都是有帮助的

1 个答案:

答案 0 :(得分:3)

实际上我们在输出音频文件的设置中犯了错误。输出音频文件处理格式应与输入文件(放置效果或音高)相同。

输出文件格式应为wav或caf格式。此格式仅保存到输出音频文件。

 - (IBAction)save_it_after_changes:(id)sender
    {

             engine = [[AVAudioEngine alloc] init];
             audio_player_node= [[AVAudioPlayerNode alloc] init];
            [engine attachNode:audio_player_node];
            [self setupEQ];

            AVAudioMixerNode *mixerNode = [engine mainMixerNode];
            [engine connect:audio_player_node to:unitEq format:audioFile.processingFormat];
            [engine connect:unitEq to:mixerNode format:audioFile.processingFormat];

            NSError *error12;
            [engine startAndReturnError:&error12];
            if (!error12)
            {
                  NSLog(@"Engine = %@",engine);
                 [audio_player_node scheduleFile:audioFile atTime:nil completionHandler:nil];
                 NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

                  [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
                  [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
                  [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

                  [recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
                  [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
                  [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];


                  NSError *error;
                 outputFile = [[AVAudioFile alloc] initForWriting:[self testFilePathURL] settings:recordSetting error:&error];
                  NSLog(@"outputfile = %@",outputFile);
                  if (error)
                  {
                         NSLog(@"outputFile error = %@",error);
                  }
                  else
                  { //(AVAudioFrameCount)audioFile.length
                        [audio_player_node installTapOnBus:0 bufferSize:8192  format:audioFile.processingFormat block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
                              NSLog(@"Buffer Size = %@",buffer);
                              NSLog(@"when = %lld",when.sampleTime);
                              NSLog(@"outputfile length = %lli",outputFile.length);
                              NSLog(@"input file length = %lld",audioFile.length);
                              if (outputFile.length<audioFile.length)
                              {
                                    NSError *error;
                                    [outputFile writeFromBuffer:buffer error:&error];
                                    if (error)
                                    {
                                          NSLog(@"writebuffererror =%@",error);
                                    }
                              }
                              else
                              {
                                    [audio_player_node removeTapOnBus:0];
                                     NSError *error2;
                                   // player2 = [[AVAudioPlayer alloc] initWithContentsOfURL:[self testFilePathURL] error:&error2];
                                    //player2.delegate = self;
                                    NSLog(@"Pathththt = %@",[self testFilePathURL]);
                                    NSLog(@"error = %@",error2);
                                   // [audio_player_node scheduleFile:outputFile atTime:nil completionHandler:nil];
                                    //[audio_player_node play];
                                   // [self toMp3];
                              }

                        }];
                  }
            }
            else
            {
                  NSLog(@"error12 =%@",error12);
            }

    }





- (void)setupEQ
{
      NSLog(@"setupEQ");

      unitEq = [[AVAudioUnitEQ alloc] initWithNumberOfBands:12];
      unitEq.globalGain = 3.0;
      AVAudioUnitEQFilterParameters *filterParameters;
      filterParameters = unitEq.bands[0];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 31;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[1];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 63;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[2];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 125;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[3];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 250;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[4];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 500;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[5];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 1000;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[6];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 2000;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[7];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 4000;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain =-20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[8];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 8000;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain = -20;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[9];
      filterParameters.filterType = AVAudioUnitEQFilterTypeParametric;
      filterParameters.frequency = 16000;
      filterParameters.bandwidth = 1.0;
      filterParameters.gain =-20;
      filterParameters.bypass = FALSE;


      filterParameters = unitEq.bands[10];
      filterParameters.filterType = AVAudioUnitEQFilterTypeLowPass;
      filterParameters.frequency = 16857;
      filterParameters.bypass = FALSE;

      filterParameters = unitEq.bands[11];
      filterParameters.filterType = AVAudioUnitEQFilterTypeHighPass;
      filterParameters.frequency = 205;
      filterParameters.bypass = FALSE;
      [engine attachNode:unitEq];
}




- (NSString *)applicationDocumentsDirectory
{
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
      return basePath;
}

//------------------------------------------------------------------------------

- (NSURL *)testFilePathURL
{
      return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/test.caf",
                                     [self applicationDocumentsDirectory]]];
}

成功保存后请播放该文件。这个对我有用。看看吧。

请参阅以下链接,我从这里获得更多信息,Can I use AVAudioEngine to read from a file, process with an audio unit and write to a file, faster than real-time?

参考此示例项目。这是我们正在寻找的 https://github.com/VladimirKravchenko/AVAudioEngineOfflineRender

相关问题