Reputation: 3036
I have a 48 kHz PCM stream and want to stream it to a 44.1 kHz compatible player (Apple's AirPlay).
Someone knows if this "just works because some bytes would get lost", or do I have to do a conversion/down-sampling before?
If it not "just works", any tips to do this in java?
EDIT:
It won't just work because the sound will be stuttering ("information-overflow"). I have to resample/down-sample the pcm-stream.
Because this is not so trivial in this case (48 kHz to 44.1 kHz) I should use a library for doing this:
I think I will try libresample. Because I'm on Android, I could use the native implementation or the java implementation.
Do you think the java-implementation is performant enought?
Upvotes: 1
Views: 934
Reputation: 9512
Ok, the easiest approach is to take every 48/44.1
th sample (which is equal to kick out every 12th sample). You will eventually have to do this.
The problem with that is aliasing. If your downsampling, you are actually mirroring the spectrum outside of your downsampling rate into your samples (see this wiki page for a good explanation), which is called aliasing. You obviously don't want that (you can try it out and see, what happens with your audio).
So how can we prevent that? The most common way is to reduce the spectrum amplitude of those mirrored frequency chunks somehow. This way, they are mirrored, but it doesn't matter so much anymore, because their amplitude is very low. This can be done by using a lowpass filter with a cutoff frequency around your sampling ratio. So the steps would be:
So what are the requirements for that filter? One of the important requirements is that the frequency amplitudes below your cutoff frequency should not be touched, so a very low passband ripple and a passband gain of 1 would be nice. Then the stoppband should be dampened as much as possible. This obviously depends on your data. I don't know about audio processing in special, but usually in DSP, the lowpass filter that are used are FIR
or IIR
. There are many other of course, but these are very easy to implement and are to a certain extend even able to handle realtime constraints.
So I suggest you read into thos two filter implementations (or just focus on FIR
). If you are really confused about what I just wrote, then maybe it's even better to just use a given library that has some sort of lowpass filtering ability. But if you are working with that stuff a lot, then I suggest reading into the matter, it really helps to understand, what is going on... ;)
Upvotes: 1
Reputation: 1896
You need to apply decimation to your input signal. First, you need to pass the input through the low-pass filter (consider this an anti-aliasing).
Then you need to do downsampling by a rational factor. There are many many articles in internet about these two processes. So if you really up to this task, go do some research.
E.g. one simple low-pass filter approach is to use average of two samples as an output sample. That is, y(n)=(x(n)+x(n-1))/2; where y - is output and x - input, n - current sample position.
Upvotes: 0
Reputation: 2707
The process needed in your case is called "downsampling by a rational factor". It is not a trivial problem, so I suggest you use a library to do that - implementing this by yourself requires a lot of DSP-knowledge. You could instead use libresample, a C library, for which you would have to write JNI bindings.
To do a very rough approximation, you could just create a new buffer, in which you copy most of the old samples, but dropping every 10th sample. It will not be exactly 44.1 kHZ, but better than playing it as it is.
Upvotes: 1