alexbw / novocaine

Painless high-performance audio on iOS and Mac OS X
http://alexbw.github.com/novocaine/
MIT License
2.23k stars 273 forks source link

AudioFileWriter appends noise to float *data during write process #90

Open ghost opened 10 years ago

ghost commented 10 years ago

Hi I am working on a sample project that involves audio filtering using Novocaine and NVDSP. You can have a look at the project at github.

The basic flow of the project is to convert an mp4 file into an m4a file and then play this m4a file using Novocaine. After that apply some NVDSP filters to this audio stream and save the modified stream to a new m4a file.

There is one big problem that there is too much noise in the filtered file. The problem is not with the NVDSP filters. I have tried commenting the filtration code and gave the same float *data to AudioFileWriter that was coming from

[wself.fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]

without applying filters to it. But the result was the same. There is too much noise in the new m4a file that is created via AudioFileWriter and the volume is low as well in the output file.

My guess is that AudioFileWriter adds the noise bits on its own due to some bug. Can you please review my ViewController.mm code and let me know if there is something that I am not doing right? I am running a few workarounds on hit and trial basis. Will keep you posted if something comes up.

ghost commented 10 years ago

Hi I have been reading Novocaine in order to find out the root cause for this noise related issue but I was unable to find the root cause. For your convenience I have made changes in Novocaine's sample code in order to keep my explanation simple.

    NSArray *pathComponents = [NSArray arrayWithObjects:
    [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
     @"My Recording.m4a",
      nil];
    NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
    NSLog(@"URL: %@", outputFileURL);

    self.fileWriter = [[AudioFileWriter alloc]
                   initWithAudioFileURL:outputFileURL
                   samplingRate:self.audioManager.samplingRate
                   numChannels:self.audioManager.numInputChannels];

    NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"];

    self.fileReader = [[AudioFileReader alloc]
                   initWithAudioFileURL:inputFileURL
                   samplingRate:self.audioManager.samplingRate
                   numChannels:self.audioManager.numOutputChannels];

    [self.fileReader play];
    self.fileReader.currentTime = 0.0;

 [self.audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
    if (!wself.fileReader.playing) {
        wself.audioManager.outputBlock = nil;
        dispatch_async(dispatch_get_main_queue(), ^{
            [wself.fileWriter stop];
            [wself.audioManager pause];
        });
    }
    else {
        [wself.fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels];
        [wself.fileWriter writeNewAudio:data numFrames:numFrames numChannels:numChannels];
    }
}];

  [self.audioManager play];

This code will read from TLC.mp3 and will save the audio in my recording.m4a You can play TLC.mp3 from the project itself and you can play my recording.m4a from this soundcloud link

kindly make your comments on this issue

PS I have made public -(void) stop; method of AudioFileWriter