resample / upsample sound frames from 8Khz to 48Khz (Java/Android)

后端 未结 4 2077
被撕碎了的回忆
被撕碎了的回忆 2021-01-18 15:30

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

相关标签:
4条回答
  • 2021-01-18 15:56

    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

    0 讨论(0)
  • 2021-01-18 16:03

    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.

    0 讨论(0)
  • 2021-01-18 16:07

    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

    0 讨论(0)
  • 2021-01-18 16:14

    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

    0 讨论(0)
提交回复
热议问题