4

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. 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. 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. 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");
    }
}
rptwsthi
  • 10,094
  • 10
  • 68
  • 109
Sishu
  • 1,510
  • 1
  • 21
  • 48
  • y not u use Dirac player to play that changed pitch sound??/ – Nikhil Bansal May 11 '12 at 10:15
  • i have already used the Dirac Player in this. – Sishu May 11 '12 at 10:18
  • 1
    can u tell me Is Dirac player not efficient to play that changed pitch sound?? – Nikhil Bansal May 11 '12 at 10:20
  • No,Dirac Player is good enough to change the pitch of sound .my problem is that the output sound which is played after the recording is noisy enough.is there any other way to record th enoise free audio on detection of sound.thanks for your responce.... – Sishu May 11 '12 at 10:25
  • 1
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err]; r u using this?? – Nikhil Bansal May 11 '12 at 10:30
  • i m using AVAudioRecorder to record the sound – Sishu May 11 '12 at 12:36
  • 2
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err]; use this line too while recording audio – Nikhil Bansal May 11 '12 at 12:40
  • i tried, but it doesn't effect the sound....still noisy.... – Sishu May 14 '12 at 09:57
  • @NikhilBansal plz help me if u have knowledge about this...... – Sishu May 29 '12 at 07:59
  • u still stuck with it??? – Nikhil Bansal May 29 '12 at 10:51
  • coz the problem is still unsolved......how can i resolved the problem of noise.......hoping help from your side.. – Sishu May 29 '12 at 11:14
  • i still not understanding which kind of noise is there?? – Nikhil Bansal May 29 '12 at 11:27
  • actually i m using avaudiorecorder to record the sound on detection of the noise and once when the sound is recorded i m using diracplayer to change the pitch of the recorded sound .after doing the oputput sound i get is noisy. – Sishu May 29 '12 at 11:38
  • kis type ki noise aa ri hai bhai?? – Nikhil Bansal May 29 '12 at 11:43
  • khrrrrr......khrrrrr aa rahi hai awaz ke sath..... – Sishu May 29 '12 at 11:45
  • i have edited my question plz see it once.......@nikhil – Sishu May 29 '12 at 12:00
  • in playRecording i m just playing the recorded sound file which is stored in document directory by dirac player mDiracAudioPlayer = [[DiracAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile1 channels:1 error:&error]; [mDiracAudioPlayer setDelegate:self]; [mDiracAudioPlayer setNumberOfLoops:0]; [mDiracAudioPlayer changePitch:1.8]; [mDiracAudioPlayer prepareToPlay]; [mDiracAudioPlayer play]; – Sishu May 29 '12 at 12:02
  • 1
    when u recording sound,then is that recorded sound also consist of that noisy sound? – Nikhil Bansal May 29 '12 at 12:04
  • yes! it is the main problem, i want to solve – Sishu May 29 '12 at 12:06
  • 1
    bas thats the reason recorded sound should not have noise khrrr khrrr – Nikhil Bansal May 29 '12 at 12:07
  • mera matlab ki agar mai noise free sound record karta hu to uski pitch change krne ke bad sound noise-free hogi.kya yeh sahi approach hai? – Sishu May 29 '12 at 12:09
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11874/discussion-between-alok-sinha-and-nikhil-bansal) – Sishu May 29 '12 at 12:12

2 Answers2

2
  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/
    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.
    For this purpose I used an external library DIRAC. Here is the link for the Dirac library.
    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.

Another way I found to solve this issue by implementing Cocoas2D, Cocos Denshion with Dirac. 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.

Sishu
  • 1,510
  • 1
  • 21
  • 48
  • How did you mangage to detect the sound and record without a delay at the start of the record ? – Ryan Heitner May 28 '13 at 19:10
  • 1
    link: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/ it will detect the frequency and then start recording.and plz upvote the question so that other can also see it – Sishu Jun 01 '13 at 06:48
  • I got I slight lag cutting off the first part of the first letter. I solved it by running two recorders and alternating, so that when the monitor detected the required sound it was already recording. – Ryan Heitner Jun 01 '13 at 16:49
1

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)

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];
Sam B
  • 27,273
  • 15
  • 84
  • 121