I want to use this code for VoIP service.
i'm using web-socket and sending with it: let data = self.toNSData(PCMBuffer: buffer)
and playback:let audioBuffer = self.toPCMBuffer(data: data)
in another device)
I'm used: https://github.com/Lkember/IntercomTest and worked it but the size of data is big. I'm feeling 41100 rates is a very big size for send data, I want to reduce buffer size with the lower rate to 8000.
but I do not know how to reduce sample rate without according error!
my failing code is below:
@IBAction func start(_ sender: Any) {
var engine = AVAudioEngine()
let input = engine.inputNode
let bus = 0
let localAudioPlayer: AVAudioPlayerNode = AVAudioPlayerNode()
let mixer = AVAudioMixerNode()
let fmt = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false)
engine.attach(mixer)
engine.connect(input, to: mixer, format: input.outputFormat(forBus: 0))
mixer.volume = 0
engine.connect(mixer, to: localAudioPlayer, format: fmt)
localAudioPlayer.installTap(onBus: bus, bufferSize: 512, format: fmt) { (buffer, time) -> Void in
// 8kHz buffers!
print(buffer.format)
localAudioPlayer.scheduleBuffer(buffer)
}
let data = self.toNSData(PCMBuffer: buffer)
let audioBuffer = self.toPCMBuffer(data: data)
localAudioPlayer.scheduleBuffer(audioBuffer)
if (!localAudioPlayer.isPlaying) {
localAudioPlayer.play()
try! engine.start()
}
}
func toNSData(PCMBuffer: AVAudioPCMBuffer) -> NSData {
let channelCount = 1 // given PCMBuffer channel count is 1
let channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: channelCount)
let ch0Data = NSData(bytes: channels[0], length:Int(PCMBuffer.frameCapacity * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame))
return ch0Data
}
func toPCMBuffer(data: NSData) -> AVAudioPCMBuffer {
let audioFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false) // given NSData audio format
let PCMBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: UInt32(data.length) / audioFormat.streamDescription.pointee.mBytesPerFrame)
PCMBuffer.frameLength = PCMBuffer.frameCapacity
let channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: Int(PCMBuffer.format.channelCount))
data.getBytes(UnsafeMutableRawPointer(channels[0]) , length: data.length)
return PCMBuffer
}
Today, with the introduction of computing, PCM audio recording equipment no longer uses tapes but computer hard drives to record from 1 to multiple channels, using hardware such as sound cards, high-quality microphones. and mixing consoles along with commercial or free software components for audio recording, editing, and mastering.
The conversion from analog to digital PCM audio is done through a process called sampling ( 5 ). In the process of sampling, we will consider the sampling rate ( 7) and the bit depth ( 6 ). First, we will define PCM audio, then we will explain how we go from analog to digital. We will also compare it with Dolby Digital and Bitstream. Let´s go.
AVR's high speed PWM is used to play the audio. It almost sound fine and can be used for simple projects that require sound effects. The code is compiled in winavr GCC compiler. The microcontroller used is ATmega32, though any AVR processor can be used for the purpose.
In the United Kingdom, the British corporation BBC also experimented with the use of PCM audio technology with the development of a 13-channel audio system, made in 1972 to improve the audio of its television broadcasts. This system continued to be used until 10 years later.
You can use below code to convert as you want.
let inputNode = audioEngine.inputNode
let downMixer = AVAudioMixerNode()
let main = audioEngine.mainMixerNode
let format = inputNode.inputFormat(forBus: 0)
let format16KHzMono = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 8000, channels: 1, interleaved: true)
audioEngine.attach(downMixer)
downMixer.installTap(onBus: 0, bufferSize: 640, format: format16KHzMono) { (buffer, time) -> Void in
do{
print(buffer.description)
if let channel1Buffer = buffer.int16ChannelData?[0] {
// print(channel1Buffer[0])
for i in 0 ... Int(buffer.frameLength-1) {
print((channel1Buffer[i]))
}
}
}
}
audioEngine.connect(inputNode, to: downMixer, format: format)
audioEngine.connect(downMixer, to: main, format: format16KHzMono)
audioEngine.prepare()
try! audioEngine.start()
In Addition
you can use commonFormat
instead settings
parameter.
let format16KHzMono = AVAudioFormat(settings: [AVFormatIDKey: AVAudioCommonFormat.pcmFormatInt16,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
AVEncoderBitRateKey: 16,
AVNumberOfChannelsKey: 1,
AVSampleRateKey: 8000.0] as [String : AnyObject])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With