Sub StartRecording
''check if its already running or not
If AudioEngine.IsInitialized Then
If AudioEngine.GetField("isRunning").AsBoolean = True Then
Return
End If
End If
''Initialize AudioEngine
AudioEngine.Initialize("AVAudioEngine")
AudioEngine = AudioEngine.RunMethod("alloc",Null).RunMethod("init",Null)
''Intall a tap on the microphone, the buffer will be available in the AudioNodeTap_Event
Dim AudioInputNode As NativeObject = AudioEngine.GetField("inputNode")
AudioInputNode.RunMethodWithBlocks("installTapOnBus:bufferSize:format:block:",Array(0,1024,AudioInputNode.RunMethod("outputFormatForBus:",Array(0)),AudioEngine.CreateBlock("AudioNodeTap",2,False)))
''Initailize the output format (iOS default sample rate is 44100 so we have multiply it by 2)
Dim toformat As NativeObject
toformat.Initialize("AVAudioFormat")
toformat=toformat.RunMethod("alloc",Null).RunMethod("initWithCommonFormat:sampleRate:channels:interleaved:",Array(3,88200.0,1,False))
''Initialize the AudioConverter
AudioConverter.Initialize("AVAudioConverter")
AudioConverter=AudioConverter.RunMethod("alloc",Null).RunMethod("initFromFormat:toFormat:",Array(AudioInputNode.RunMethod("outputFormatForBus:",Array(0)),toformat))
''Run the AudioEngine
AudioEngine.RunMethod("prepare",Null)
If AudioEngine.RunMethod("startAndReturnError:",Null).AsBoolean = False Then
Msgbox("Cannot start audio engine","")
End If
End Sub
Sub AudioNodeTap_Event(args() As Object)
Dim no As NativeObject = Me
''The first object is the uncompressed raw PCM buffer
''The Objective C code is converting the Float32 buffer to Int16
''And returning the buffer bytes as NSData
Dim data As Object = no.RunMethod("PCMtoNSData::",Array(args(0),AudioConverter))
''We have to convert it to B4IArray to be able to send over internet
Dim buffer() As Byte = no.NSDataToArray(data)
''Reseting the AudioConverter so that it can process the next buffer
AudioConverter.RunMethod("reset",Null)
''Send the byte array to the server
socket.emit("audio_received",buffer)
End Sub
Sub StopRecording
''If its runing then first removing the microphone tap and then stopping the AudioEngine
If AudioEngine.IsInitialized And AudioEngine.GetField("isRunning").AsBoolean Then
Dim AudioInputNode As NativeObject = AudioEngine.GetField("inputNode")
AudioInputNode.RunMethod("removeTapOnBus:",Array(0))
AudioEngine.RunMethod("stop",Null)
End If
End Sub
#if objc
-(NSData*) PCMtoNSData:(AVAudioPCMBuffer*) buffer :(AVAudioConverter*) converter{
//Initalizing a Int16 empty buffer with the scaled frame capacity
AVAudioPCMBuffer *outputBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:converter.outputFormat frameCapacity:(converter.outputFormat.sampleRate * buffer.frameLength / buffer.format.sampleRate)];
outputBuffer.frameLength = outputBuffer.frameCapacity;
//Converting the buffer
AVAudioConverterOutputStatus oStatus = [converter convertToBuffer:outputBuffer error:nil withInputFromBlock:^(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus){
*outStatus = AVAudioConverterInputStatus_HaveData;
return buffer;
}];
//Storing inner raw buffer byte array to NSData
NSData *values = [[NSData alloc] initWithBytes:outputBuffer.int16ChannelData[0] length:(outputBuffer.frameCapacity * outputBuffer.format.streamDescription->mBytesPerFrame)];
return values;
}
#End If