6

The application that I am trying to develop for andriod, records frames at 48Khz (PCM 16bits & mono) and sends them to the network. Also, there is an incoming stream of audio at 8Khz. So, I receive 8Khz sampled frames and play them (my AudioTrack object is set to 8Khz), but when playing them, everything works but the latency is HUGE. It takes like around 3 seconds until you hear something.

I think that if I upsample the received frames from 8Khz to 48Khz and play them, there won't be such a huge playing latency. In fact when I record and play frames at the same rate, the latency is really low. The bad thing is that I am forced to do it this way: send to 48Khz and receive to 8Khz.

As explained before, I'm trying to upsample a sound frame (16bits PCM) from 8Khz to 48Khz. Does anybody know any routine/library/API in Java that does this???

I know the basics about upsampling a discreet signal, but I consider that to design and implement my own FIR filter and convolute it with the audio stream ....is way too much. Also, it is over my knowledge.

So...does anybody can help me with this?? Does anybody know any library/routine in Java that I can use?? Any suggestions or alternatives??

AstroCB
  • 12,337
  • 20
  • 57
  • 73
arakn0
  • 499
  • 5
  • 11
  • 15
  • 4
    @juergen, if you're going to bump an old question to fix typos in "thanks in advanced", *at least* remove the phrase entirely, as it is of no value, and fix the other spelling errors. – Nathan Tuggy Apr 17 '15 at 01:22

4 Answers4

5

A quick and dirty solution would be linear interpolation. Since you're always sampling up by a factor of six this is really easy to do:

It works somewhat like this (C-code, and untested, and I don't handle the last iteration properly, but it shows the idea I think).

void resample (short * output, short * input, int n)
{
  // output ought to be 6 times as large as input (48000/8000).

  int i;
  for (i=0; i<n-1; i++)
  {
    output[i*6+0] = input[i]*6/6 + input[i+1]*0/6;
    output[i*6+1] = input[i]*5/6 + input[i+1]*1/6;
    output[i*6+2] = input[i]*4/6 + input[i+1]*2/6;
    output[i*6+3] = input[i]*3/6 + input[i+1]*3/6;
    output[i*6+4] = input[i]*2/6 + input[i+1]*4/6;
    output[i*6+5] = input[i]*1/6 + input[i+1]*5/6;
  }

Linear interpolation won't give you great sound quality but it is cheap and fast. You can improve this using cubic interpolation if you want to.

If you want a fast and high quality resampling I suggest that you compile a c resampling library like libresample using the Android-NDK and call it from java using JNI. That will be a lot faster. Writing the JNI code is something most people shy away from, but it's quite easy.. The NDK has lots of examples for this.

http://www.mega-nerd.com/SRC/index.html

Nils Pipenbrinck
  • 83,631
  • 31
  • 151
  • 221
2

Linear interpolation introduces artifacts. There is nice java library with high-quality resampling - JSSRC (http://jssrc.khadkevich.org/).

The code is now available on Github: https://github.com/hutm/JSSRC

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • 1
    You saved me allot of headache. The site you linked to is down, here is the Archive https://web.archive.org/web/20130902203226/http://jssrc.khadkevich.org and here is the github repository.. https://github.com/hutm/JSSRC – kc ochibili Oct 21 '14 at 21:05
1

I was unable to make most libraries work (https://github.com/hutm/JSSRC, https://github.com/simingweng/android-pcm-resample, https://github.com/ashqal/android-libresample). They all have problems either in the resulting audio or just failed to convert from 48000Hz to 44100Hz (that's what I needed).

This one though works perfectly: https://github.com/JorenSix/TarsosDSP

That's a big pure-Java library that works on Android (no javax.sound dependencies) and that is capable of many things, but if you just take the FilterKit, Resampler and SampelBuffers classes in package be.tarsos.dsp.resample, it works extremely well and is easy to use.

Stéphane
  • 1,518
  • 1
  • 18
  • 31
0

The TarsosDPS library was too heavy for my needs, but I found out that the resampling tools were first published as a lighter 3-class library: https://github.com/dnault/libresample4j

As for TarsosDPS no need of javax