From b4ce807c110c4f1b68e355a26a0617c9882c100c Mon Sep 17 00:00:00 2001 From: Igor Khomenko Date: Wed, 19 Dec 2012 19:20:38 +0200 Subject: [PATCH 1/4] now you can set sample Rate --- Novocaine iOS Example/ViewController.mm | 54 ++++++++++++------------- Novocaine/Novocaine.m | 11 ++++- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/Novocaine iOS Example/ViewController.mm b/Novocaine iOS Example/ViewController.mm index 63c0feb..cac174b 100644 --- a/Novocaine iOS Example/ViewController.mm +++ b/Novocaine iOS Example/ViewController.mm @@ -51,16 +51,16 @@ - (void)viewWillAppear:(BOOL)animated // Basic playthru example -// [audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) { -// float volume = 0.5; -// vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels); -// ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels); -// }]; -// -// -// [audioManager setOutputBlock:^(float *outData, UInt32 numFrames, UInt32 numChannels) { -// ringBuffer->FetchInterleavedData(outData, numFrames, numChannels); -// }]; + [audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) { + float volume = 0.5; + vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels); + ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels); + }]; + + + [audioManager setOutputBlock:^(float *outData, UInt32 numFrames, UInt32 numChannels) { + ringBuffer->FetchInterleavedData(outData, numFrames, numChannels); + }]; // MAKE SOME NOOOOO OIIIISSSEEE @@ -165,23 +165,23 @@ - (void)viewWillAppear:(BOOL)animated // }]; - // AUDIO FILE READING OHHH YEAHHHH - // ======================================== - NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"]; - - fileReader = [[AudioFileReader alloc] - initWithAudioFileURL:inputFileURL - samplingRate:audioManager.samplingRate - numChannels:audioManager.numOutputChannels]; - - [fileReader play]; - fileReader.currentTime = 30.0; - - [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) - { - [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; - NSLog(@"Time: %f", fileReader.currentTime); - }]; +// // AUDIO FILE READING OHHH YEAHHHH +// // ======================================== +// NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"]; +// +// fileReader = [[AudioFileReader alloc] +// initWithAudioFileURL:inputFileURL +// samplingRate:audioManager.samplingRate +// numChannels:audioManager.numOutputChannels]; +// +// [fileReader play]; +// fileReader.currentTime = 30.0; +// +// [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) +// { +// [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; +// NSLog(@"Time: %f", fileReader.currentTime); +// }]; // AUDIO FILE WRITING YEAH! diff --git a/Novocaine/Novocaine.m b/Novocaine/Novocaine.m index 8a45b06..e9add18 100644 --- a/Novocaine/Novocaine.m +++ b/Novocaine/Novocaine.m @@ -39,6 +39,10 @@ #define kOutputBus 0 #define kDefaultDevice 999999 +#define sampleRateT 8000.0 +//#define sampleRateT 22050.0 +//#define sampleRateT 44100.0 + #import "TargetConditionals.h" static Novocaine *audioManager = nil; @@ -237,6 +241,9 @@ - (void)setupAudio CheckError( AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize), "Couldn't set the preferred buffer duration"); #endif + Float64 F64sampleRate = sampleRateT; + CheckError( AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(F64sampleRate), &F64sampleRate), "Couldn't set the preferred sample rate"); + // Set the audio session active CheckError( AudioSessionSetActive(YES), "Couldn't activate the audio session"); @@ -351,8 +358,8 @@ - (void)setupAudio "Couldn't get the hardware output stream format"); // TODO: check this works on iOS! - inputFormat.mSampleRate = 44100.0; - outputFormat.mSampleRate = 44100.0; + inputFormat.mSampleRate = sampleRateT; + outputFormat.mSampleRate = sampleRateT; self.samplingRate = inputFormat.mSampleRate; self.numBytesPerSample = inputFormat.mBitsPerChannel / 8; From 15a0bffedcb8ea5441e7b8150d3f168a2e3ff247 Mon Sep 17 00:00:00 2001 From: Igor Khomenko Date: Wed, 26 Dec 2012 10:50:53 +0200 Subject: [PATCH 2/4] fixed crash after End interuption --- Novocaine iOS Example/ViewController.mm | 26 +++++++++++++++++++++++-- Novocaine/Novocaine.m | 5 +++-- Novocaine/RingBuffer.mm | 4 ++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Novocaine iOS Example/ViewController.mm b/Novocaine iOS Example/ViewController.mm index cac174b..de56c09 100644 --- a/Novocaine iOS Example/ViewController.mm +++ b/Novocaine iOS Example/ViewController.mm @@ -49,18 +49,40 @@ - (void)viewWillAppear:(BOOL)animated ringBuffer = new RingBuffer(32768, 2); audioManager = [Novocaine audioManager]; + static int lastsecond = [[NSDate date] timeIntervalSince1970]; + static float speed = 0; // Basic playthru example [audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) { - float volume = 0.5; - vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels); +// float volume = 0.5; +// vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels); ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels); + + + // Get KB/sec +// NSLog(@"numFrames %ld", numFrames); + speed += (numFrames * sizeof(float)); + int cursec = (int)[[NSDate date] timeIntervalSince1970]; + if(cursec > lastsecond){ + NSLog(@"numFrames %ld", numFrames); + NSLog(@"%f KB/s", speed/1024); + speed = 0; + } + lastsecond = cursec; }]; + + [audioManager setOutputBlock:^(float *outData, UInt32 numFrames, UInt32 numChannels) { ringBuffer->FetchInterleavedData(outData, numFrames, numChannels); }]; + + + + + + // MAKE SOME NOOOOO OIIIISSSEEE diff --git a/Novocaine/Novocaine.m b/Novocaine/Novocaine.m index e9add18..c9f4b6b 100644 --- a/Novocaine/Novocaine.m +++ b/Novocaine/Novocaine.m @@ -40,6 +40,7 @@ #define kDefaultDevice 999999 #define sampleRateT 8000.0 +#define IOBufferDuration 0.0232*2 //#define sampleRateT 22050.0 //#define sampleRateT 44100.0 @@ -237,7 +238,7 @@ - (void)setupAudio // Set the buffer size, this will affect the number of samples that get rendered every time the audio callback is fired // A small number will get you lower latency audio, but will make your processor work harder #if !TARGET_IPHONE_SIMULATOR - Float32 preferredBufferSize = 0.0232; + Float32 preferredBufferSize = IOBufferDuration; CheckError( AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize), "Couldn't set the preferred buffer duration"); #endif @@ -864,13 +865,13 @@ void sessionInterruptionListener(void *inClientData, UInt32 inInterruption) { if (inInterruption == kAudioSessionBeginInterruption) { NSLog(@"Begin interuption"); sm.inputAvailable = NO; + [sm pause]; } else if (inInterruption == kAudioSessionEndInterruption) { NSLog(@"End interuption"); sm.inputAvailable = YES; [sm play]; } - } #endif diff --git a/Novocaine/RingBuffer.mm b/Novocaine/RingBuffer.mm index 753d6d6..7e7423e 100644 --- a/Novocaine/RingBuffer.mm +++ b/Novocaine/RingBuffer.mm @@ -156,6 +156,10 @@ mLastWrittenIndex[iChannel] = (mLastWrittenIndex[iChannel] + numFrames) % (mSizeOfBuffer); mNumUnreadFrames[iChannel] = (mNumUnreadFrames[iChannel] + numFrames); if (mNumUnreadFrames[iChannel] >= mSizeOfBuffer) mNumUnreadFrames[iChannel] = mSizeOfBuffer; + + +// NSLog(@"mLastWrittenIndex[iChannel] %lld", mLastWrittenIndex[iChannel]); + } From c1032f8f095227b709fc69403d78e6376de75855 Mon Sep 17 00:00:00 2001 From: Igor Khomenko Date: Fri, 28 Dec 2012 12:20:57 +0200 Subject: [PATCH 3/4] add route to speaker methods; set component subtype to kAudioUnitSubType_VoiceProcessingIO --- Novocaine/Novocaine.h | 4 ++++ Novocaine/Novocaine.m | 46 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Novocaine/Novocaine.h b/Novocaine/Novocaine.h index b2465ab..9157494 100644 --- a/Novocaine/Novocaine.h +++ b/Novocaine/Novocaine.h @@ -180,5 +180,9 @@ typedef void (^InputBlock)(float *data, UInt32 numFrames, UInt32 numChannels); - (void)checkAudioSource; #endif +- (void)routeToSpeaker; +- (void)routeToHeadphone; +-(void) routeSpeaker; +-(void) routeToDefaultSpeaker; @end diff --git a/Novocaine/Novocaine.m b/Novocaine/Novocaine.m index c9f4b6b..0851e4e 100644 --- a/Novocaine/Novocaine.m +++ b/Novocaine/Novocaine.m @@ -279,7 +279,7 @@ - (void)setupAudio #elif defined (USING_IOS) AudioComponentDescription inputDescription = {0}; inputDescription.componentType = kAudioUnitType_Output; - inputDescription.componentSubType = kAudioUnitSubType_RemoteIO; + inputDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO; inputDescription.componentManufacturer = kAudioUnitManufacturer_Apple; #endif @@ -895,6 +895,50 @@ - (void)selectAudioDevice:(AudioDeviceID)deviceID #endif + +-(void)routeToSpeaker +{ + UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; // 1 + + CheckError( AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, + sizeof(kAudioSessionCategory_PlayAndRecord), + &audioRouteOverride + ), "err1 - speaker"); +} +-(void)routeToHeadphone +{ + UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; + + CheckError( AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, + sizeof(kAudioSessionCategory_PlayAndRecord), + &audioRouteOverride + ), "err2 - headphone"); +} + +-(void)routeSpeaker +{ + UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; // 1 + + AudioSessionSetProperty ( + kAudioSessionProperty_OverrideAudioRoute, // 2 + sizeof (audioRouteOverride), // 3 + &audioRouteOverride // 4 + ); + +} + +-(void)routeToDefaultSpeaker +{ + UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; // 1 + + AudioSessionSetProperty ( + kAudioSessionProperty_OverrideAudioRoute, // 2 + sizeof (audioRouteOverride), // 3 + &audioRouteOverride // 4 + ); +} + + #pragma mark - Convenience Methods - (NSString *)applicationDocumentsDirectory { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; From 76a474103808b0d3ed2c28f2c94d04cd8ab1c099 Mon Sep 17 00:00:00 2001 From: Igor Khomenko Date: Sat, 2 Nov 2013 10:37:11 +0200 Subject: [PATCH 4/4] cleanup --- Novocaine iOS Example/ViewController.mm | 37 +++++++++---------------- Novocaine/Novocaine.m | 8 ++---- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/Novocaine iOS Example/ViewController.mm b/Novocaine iOS Example/ViewController.mm index de56c09..b53f732 100644 --- a/Novocaine iOS Example/ViewController.mm +++ b/Novocaine iOS Example/ViewController.mm @@ -48,43 +48,32 @@ - (void)viewWillAppear:(BOOL)animated ringBuffer = new RingBuffer(32768, 2); audioManager = [Novocaine audioManager]; +// [audioManager routeToSpeaker]; - static int lastsecond = [[NSDate date] timeIntervalSince1970]; - static float speed = 0; - // Basic playthru example + + // Basic IO example [audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) { -// float volume = 0.5; -// vDSP_vsmul(data, 1, &volume, data, 1, numFrames*numChannels); - ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels); + // *data - data from microphone - - // Get KB/sec -// NSLog(@"numFrames %ld", numFrames); - speed += (numFrames * sizeof(float)); - int cursec = (int)[[NSDate date] timeIntervalSince1970]; - if(cursec > lastsecond){ - NSLog(@"numFrames %ld", numFrames); - NSLog(@"%f KB/s", speed/1024); - speed = 0; - } - lastsecond = cursec; + // STEP 1. Convert *data from PCM format to iLBC + // ... + + // STEP 2. Convert back to PCM + // ... + + // save data to queue + ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels); }]; - - - [audioManager setOutputBlock:^(float *outData, UInt32 numFrames, UInt32 numChannels) { + // Play data ringBuffer->FetchInterleavedData(outData, numFrames, numChannels); }]; - - - - // MAKE SOME NOOOOO OIIIISSSEEE // ================================================== // [audioManager setOutputBlock:^(float *newdata, UInt32 numFrames, UInt32 thisNumChannels) diff --git a/Novocaine/Novocaine.m b/Novocaine/Novocaine.m index 0851e4e..64cb763 100644 --- a/Novocaine/Novocaine.m +++ b/Novocaine/Novocaine.m @@ -563,8 +563,6 @@ - (void)setupAudio #if defined ( USING_OSX ) CheckError(AudioUnitInitialize(outputUnit), "Couldn't initialize the output unit"); #endif - - } @@ -837,18 +835,18 @@ - (void)checkSessionProperties UInt32 newNumChannels; CheckError( AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &newNumChannels), "Checking number of input channels"); self.numInputChannels = newNumChannels; - // self.numInputChannels = 1; NSLog(@"We've got %lu input channels", self.numInputChannels); + if(self.numInputChannels > 1){ + self.numInputChannels = 1; + } // Check the number of input channels. // Find the number of channels CheckError( AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &size, &newNumChannels), "Checking number of output channels"); self.numOutputChannels = newNumChannels; - // self.numOutputChannels = 1; NSLog(@"We've got %lu output channels", self.numOutputChannels); - // Get the hardware sampling rate. This is settable, but here we're only reading. Float64 currentSamplingRate; size = sizeof(currentSamplingRate);