简体   繁体   English

录制声音并以改变的音高播放

[英]Record the sound and play it back with changed pitch

I have to implement a iphone application which will record user's voice as you starts speaking, and change the pitch of the recorded sound and play it back. 我必须实现一个iphone应用程序,它将在你开始讲话时记录用户的声音,并改变录制声音的音高并播放。 I am able to record the audio on the detection of the sound by the help of AVAudiorecorder, and using Dirac library I have changed the pitch of recorded sound. 我能够在AVAudiorecorder的帮助下录制声音检测音频,并使用Dirac库我改变了录制声音的音高。 The problem with this approach is that the output sound is noisy enough. 这种方法的问题是输出声音足够嘈杂。 I got the response for using SoundEngine but I didn't get the way to implement it. 我得到了使用SoundEngine的响应,但我没有得到实现它的方法。 Can anyone please explain me about any other way to implement this? 任何人都可以解释一下其他任何实现方法吗?

my code//
        -(void)initialSetup
    { 
        count=0; 
        silenceTime=0;

    //[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error: nil];
    recordSetting = [[NSMutableDictionary alloc] init];
    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatAppleLossless] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
    recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat: @"%.0f.%@",[NSDate timeIntervalSinceReferenceDate]*1000.0,                  @"caf"]]];
    recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
    //recorder = [[ AVAudioRecorder alloc] init];
    [recorder setDelegate:self];
    [recorder updateMeters];
    [recorder prepareToRecord];
    //[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error: nil];
    //In Order To Move Sound To The Speaker
    //UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    //AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof(audioRouteOverride),&audioRouteOverride);

    NSArray *dirPaths;
    NSString *docsDir;
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = [dirPaths objectAtIndex:0];
    NSString *soundFilePath = [docsDir stringByAppendingPathComponent:@"audio.caf"];
    recordedTmpFile1 =  [NSURL fileURLWithPath:soundFilePath];

    recordSetting1 =   [[NSMutableDictionary alloc] init];
    recordSetting1 =   [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithInt:AVAudioQualityMin],AVEncoderAudioQualityKey,
                        //[NSNumber numberWithInt:kAudioFormatAppleIMA4],AVFormatIDKey,
                        [NSNumber numberWithInt:16], 
                        AVEncoderBitRateKey,
                        [NSNumber numberWithInt: 2], 
                        AVNumberOfChannelsKey,
                        [NSNumber numberWithFloat:44100.0], 
                        AVSampleRateKey,nil];
    recorder1 = [[AVAudioRecorder alloc] initWithURL:recordedTmpFile1 settings:recordSetting1 error:&error];
    [recorder1 prepareToRecord];
    [recorder1 setDelegate:self];
    if(recorder) 
    {
        recorder.meteringEnabled = YES;
        [recorder record];
        double val=[recorder peakPowerForChannel:0];
        NSLog(@"The Very First Value Of The Recorder Is=%f",val);
        levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.4 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
    }
    else
    {
        NSLog(@"error in initilising of the recorder=%@",[error localizedDescription]);
    }
}


-(void)levelTimerCallback:(NSTimer *)timer                      
{ 
    [recorder updateMeters];
    const double ALPHA = 0.05;
    //NOISE FILERATION ALGORITHMS
    double peakPowerForChannel = pow(10,(0.05 *[recorder peakPowerForChannel:0]));
    double audioMonitorResults1 = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * audioMonitorResults1;
    double audioMonitorResults;
    audioMonitorResults= [recorder peakPowerForChannel:0];
    NSLog(@"This time only  frequency is==>%f",audioMonitorResults1);
    //if (audioMonitorResults1 >0.020)
    if(audioMonitorResults1 > .05)//the value of audioMonitorResults may be equal to -10 for device
    {

        [recorder1 updateMeters];
        recorder1.meteringEnabled=YES;
        //recorder.meteringEnabled=YES;
        [recorder1 record];
        NSLog(@"SOUND IS DETECTED");
        NSLog(@"%f",[recorder1 peakPowerForChannel:0]);
        NSLog(@"Recording is going on");
        count=1;
        silenceTime=0;

    }
    else
    {

        NSLog(@"NO SOUND IS DETECTED");
        silenceTime=silenceTime+0.3;
        if(count==1 && silenceTime>1)
        { 

            [levelTimer invalidate];
            [recorder1 stop];

        }

    }

}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
    NSLog(@"Recorder stop delegate is processing");
    if(flag)
    {
        NSLog(@"Player has finished successfully");
        [self playRecording];
    }
    else
    { 
        NSLog(@"problem in recording.......not recorded");
    }
}
  1. How to detect the sound? 如何检测声音?
    I solved my first problem with the help of a tutorial..here is the link for this, link: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/ 我在教程的帮助下解决了我的第一个问题。这里有链接,链接: http//mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/
    Here we can easily understand the recording of the sound on detection of some noise. 在这里,我们可以很容易地理解在检测到一些噪声时的声音记录。

  2. How to change the pitch of the recorded sound and play back. 如何改变录制声音的音高并播放。
    Second problem I faced in changing the pitch of the sound. 我在改变声音音高时面临的第二个问题。 As we can only record the sound with the help of AVAudioRecorder we can't alter the pitch by that. 由于我们只能在AVAudioRecorder的帮助下录制声音,因此无法改变音高。
    For this purpose I used an external library DIRAC . 为此,我使用了外部库DIRAC Here is the link for the Dirac library. 这是Dirac库的链接。
    This comes up with some sample project (for mobile apps as well as desktop apps)about the implementation of the dirac library to the application. 这提供了一些关于应用程序的dirac库实现的示例项目(适用于移动应用程序以及桌面应用程序)。

Another way I found to solve this issue by implementing Cocoas2D, Cocos Denshion with Dirac. 我发现通过使用Dirac实现Cocoas2D,Cocos Denshion来解决这个问题的另一种方法。 Because the above proess was not working well with my application. 因为上述问题与我的应用程序不兼容。 Here is the link for implementing this (a sample project about the changing the pitch and play the recorded sound). 以下是实现此功能的链接 (有关更改音高和播放录制声音的示例项目)。

I found another link related to sound recording. 我找到了另一个与录音有关的链接

Actually there is an easier solution. 实际上有一个更简单的解决方案。 Use the rate feature of the audio player. 使用音频播放器的速率功能。 It ranges between 0.1f - 2.0f where higher number means faster and squeekier pitch and lower number means slow dragged out sound (deep voice) 它的范围在0.1f - 2.0f之间,其中较高的数字意味着更快和更尖锐的音调,更低的数字意味着缓慢的拖出声音(深沉的声音)

player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                  [NSURL fileURLWithPath:path] error:&err];
        player.volume = 0.4f;
        player.enableRate=YES;
        [player prepareToPlay];
        [player setNumberOfLoops:0];
        player.rate=2.0f;
        [player play];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM