Products > Programming

Resampling PCM S16LE @ 9.6 kHz to 11025 Hz or 48000 Hz on the fly

(1/3) > >>

Phaseseeker:
Like the title says, I need to resample PCM audio in the S16LE format (signed 16-bit integer, little endian) sampled at 9.6KHz ideally up to 48  kHz on the fly. This is because I'm trying to interface to some old software that is partially closed source; I have the code that interfaces with the audio card (it just uses standard ALSA functions like snd_pcm_writei() and snd_pcm_readi() to write the data to the card) but the DSP code is proprietary and refuses to work at any sample rate that is not 9.6 KHz and I have no audio card that natively supports such rate.  Ideally I'd want to resample it to 48 kHz (since every card I have seems to support it) but both the nearest AC97 standard rates of 8 kHz and 11.025 kHz would be fine. I tried using libsamplerate but the problem is that I need to convert the audio coming from the DSP software on the fly and if the resampling introduces too much delay I start getting overruns on the soundcard buffers; even the fastest converter mode in the library is still too slow. I suspect some of it has to do with the fact that the library only works with PCM data in float format and the back and forth conversion adds a lot of delay but I don't have a lot of experience with PCM audio so I don't have any ideas on how to fix this (my first idea was to simply delete a sample every n to downsample from 9.6 kHz to 8 kHz but I've learnt that it's a bad idea...), so any suggestion is welcome.
Thanks in advance

Kalvin:
Conversion from 9.6kHz to 48kHz should be pretty straight forward, depending of how good results you want. The ratio of 48kHz / 9.6kHz = 5, which is a nice integer value. A brute-force method would be using just a simple linear interpolation, but the result may not be as good as you might want. Using zero stuffing and an interpolating FIR filter may be something that you want to try out: https://en.wikipedia.org/wiki/Upsampling#Upsampling_by_an_integer_factor

Ed.Kloonk:
What card is it?

Phaseseeker:

--- Quote from: Ed.Kloonk on November 30, 2021, 03:32:36 pm ---What card is it?

--- End quote ---
My soundcard? I'm simply using my laptop's integrated sound card (ALSA calls it "CX8070 analog").

@Kalvin
Thanks for the link, I'll look into it. Though, thinking about it, the problem with 48 kHz might be that there's no way the sound can buffer can take all the data in one transfer (since I also need to transfer 2x the data because the sound card doesn't support mono output).

SiliconWizard:

--- Quote from: Kalvin on November 30, 2021, 03:08:29 pm ---Conversion from 9.6kHz to 48kHz should be pretty straight forward, depending of how good results you want. The ratio of 48kHz / 9.6kHz = 5, which is a nice integer value. A brute-force method would be using just a simple linear interpolation, but the result may not be as good as you might want.

--- End quote ---

Well. We dont know much about the OP's requirements and the kind of "audio" they deal with, but as a general thought, if you're using audio sampled at 9.6 kHz, you're probably not expecting Hi-Fi.

Anyway, a common and nice alternative to linear interpolation is using an higher-order interpolation. Cubic interpolation works quite well for audio - take a look at Catmull-Rom splines. I've used that almost exclusively for real-time sample rate conversion. Still more efficient than using a large FIR filter.

And that said, I'm a bit surprised that libsamplerate would be too "slow" here. But we may also need to know what kind of hardware this all runs on. Maybe it's a pretty old machine. And libsamplerate is not the most efficient thing on earth either (and I think it has various modes, so maybe the OP is using one of the "highest quality" but most taxing mode.)


Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version