2012-05-11 19 views
5

Muszę zaimplementować aplikację iPhone, która będzie rejestrować głos użytkownika, gdy zaczniesz mówić, i zmienić wysokość nagrywanego dźwięku i odtworzyć go. Jestem w stanie nagrać dźwięk po wykryciu dźwięku za pomocą AVAudiorecorder, a przy użyciu biblioteki Dirac zmieniłem wysokość nagrywanego dźwięku. Problem z tym podejściem polega na tym, że dźwięk wyjściowy jest wystarczająco głośny. Dostałem odpowiedź na użycie SoundEngine, ale nie udało mi się go wdrożyć. Czy ktokolwiek może mi wyjaśnić, w jaki inny sposób to wdrożyć?Nagraj dźwięk i odtwórz go ze zmienionym skokiem.

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"); 
    } 
} 
+0

y nie u użyć odtwarzacza Diraca grać, że dźwięk zmieniony pitch ??/ –

+0

Użyłem już w tym odtwarzaczu Diraca. –

+1

Czy możesz mi powiedzieć Czy odtwarzacz Diraca nie jest wydajny do odtwarzania tego zmienionego dźwięku pitch? –

Odpowiedz

2
  1. Jak wykryć dźwięk?
    Rozwiązałem mój pierwszy problem za pomocą samouczka. Oto link do tego, link: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/
    Tutaj możemy łatwo zrozumieć zapis dźwięku po wykryciu hałasu.

  2. Zmiana tonacji nagranego dźwięku i odtwarzanie.
    Drugi problem, w obliczu którego zmieniłem wysokość dźwięku. Ponieważ możemy nagrywać dźwięk tylko przy pomocy AVAudioRecorder, nie możemy zmienić tego tonu.
    W tym celu użyłem zewnętrznej biblioteki DIRAC. Here is the link for the Dirac library.
    Pojawi się przykładowy projekt (dla aplikacji mobilnych i aplikacji komputerowych) na temat implementacji biblioteki dirac w aplikacji.

Innym sposobem na rozwiązanie tego problemu było wdrożenie Cocoas2D, Cocos Denshion z Dirac. Ponieważ powyższa proess nie działa dobrze z moją aplikacją. Here is the link for implementing this (przykładowy projekt dotyczący zmiany wysokości i odtwarzania nagranego dźwięku).

Znalazłem another link związane z nagrywaniem dźwięku.

+0

W jaki sposób udało ci się wykryć dźwięk i nagrywać? bez opóźnień na początku zapisu? –

+1

link: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/ wykryje częstotliwość, a następnie rozpocznie nagrywanie. I plz odpowie na pytanie, aby inni mogli również zobaczyć it –

+0

Mam niewielkie opóźnienie przecinania pierwszej części pierwszej litery. Rozwiązałem go, uruchamiając dwa nagrywarek i na przemian, tak aby po wykryciu przez monitor wymaganego dźwięku był on już nagrywany. –

1

W rzeczywistości istnieje łatwiejsze rozwiązanie. Użyj funkcji szybkości odtwarzacza audio. Waha się ona między 0.1f - 2.0f gdzie wyższa liczba oznacza szybsze i pitch squeekier i mniejsza liczba oznacza powolny wyciągnęli dźwięk (głęboki głos)

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]; 
+1

Szybkość różni się od wysokości tonu ... – Idan

+0

Ten kod jest używany do zwiększenia szybkości mowy nie dla wysokości dźwięku (np. Karoke) –

Powiązane problemy