converting pcm file to mp3 using liblame in android

旧时模样 提交于 2020-01-10 03:07:08

问题


I am using SimpleLameLibForAndroid to convert a pcm file that created using AudioRecord class in android,to mp3. I read the pcm file and encoded it into mp3 and then I write it in the file. the result mp3 file but is not correct and it has a lot of noise on it and really hard to understand that it was recorded pcm file. these are recorded audio specifications(pcm file):

    private static final int RECORDER_SAMPLERATE = 8000;
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;    
    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
    int BytesPerElement = 2; // 2 bytes in 16bit format
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
    RECORDER_SAMPLERATE, RECORDER_CHANNELS,
    RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);

and this is my code that uses liblame for encode mp3 and write it to file:

//Encoder.Builder(int inSamplerate,int outChannel,int outSampleRate,int outBitrate)
Encoder en = new Encoder.Builder(8000, 1,8000,128).quality(7).create();
private int PCM_BUF_SIZE = 8192;
private int MP3_SIZE = 8192;
private void readFile()  {
    File pcm = new File("/sdcard/voice8K16bitmono.pcm");
    File mp3 = new File("/sdcard/BOOOB.mp3");
    pcm.setReadable(true);
    mp3.setWritable(true);
    try {
        InputStream is = new FileInputStream(pcm);
        BufferedInputStream bis = new BufferedInputStream(is);
        bis.skip(44);//skip pcm header
        OutputStream os = new FileOutputStream(mp3);
        FileOutputStream fos = new FileOutputStream(mp3);
        int n_bytes_read ;
        int n_bytes_write;
        int i;

        byte mp3_buffer[] = new byte[MP3_SIZE];
        byte pcm_buffer1[] = new byte[PCM_BUF_SIZE * 2];

        do {
            n_bytes_read = bis.read(pcm_buffer1 , 0 , PCM_BUF_SIZE);
            if (n_bytes_read == 0){
                n_bytes_write = en.flush(mp3_buffer);
            }
            else{
                n_bytes_write = en.encodeBufferInterleaved(byte2short(pcm_buffer1) ,n_bytes_read , mp3_buffer);
            }

            bof.write(mp3_buffer, 0, PCM_BUF_SIZE);

        } while (n_bytes_read > 0);
        bis.close();
        fos.close();
        is.close();
        en.close();

    }catch (IOException e) {
        e.printStackTrace();
    }
}
private short[] byte2short(byte[] pcm_buffer1) {
    short[] shorts = new short[pcm_buffer1.length/2];
   ByteBuffer.wrap(pcm_buffer1).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
    return shorts;
}

how can i fix this code, is the bufferSizes true? using BufferedInputStream is correct? and...


回答1:


I implemented a PCM to MP3 encoder just yesterday for my application using lame. I suggest not using SimpleLameLibForAndroid and instead adding lame to your project yourself. If you are using Android Studio, here is a good guide to get you started on that if you haven't done NDK before.

http://www.shaneenishry.com/blog/2014/08/17/ndk-with-android-studio/

As for implementing lame itself, below is a really good guide that I followed to get my application up and running. Use the wrapper.c from the .zip at the top of the page. This exposes useful methods so that you can avoid all the nasty Stream and Buffer stuff.

http://developer.samsung.com/technical-doc/view.do?v=T000000090

When all is said and done, the actual calls to the lame encoder are super simple as follows.

For initializing (use whatever settings you like):

public static final int NUM_CHANNELS = 1;
public static final int SAMPLE_RATE = 16000;
public static final int BITRATE = 64;
public static final int MODE = 1;
public static final int QUALITY = 7;
...

initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY);

For encoding (very easy):

int result = encodeFile(pcm.getPath(), mp3.getPath());
if (result == 0) {
    //success
}

And of course destroy the encoder when done with destroyEncoder().



来源:https://stackoverflow.com/questions/33717403/converting-pcm-file-to-mp3-using-liblame-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!