4

AndroidのAudioRecordクラスを使用して作成したpcmファイルをmp3に変換するためにSimpleLameLibForAndroidを使用しています。pcm ファイルを読み込んで mp3 にエンコードし、ファイルに書き込みます。結果のmp3ファイルですが、正しくなく、ノイズが多く、pcmファイルで録音されたことが本当にわかりにくいです。これらは録音されたオーディオ仕様 (pcm ファイル) です。

    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);

これは、mp3 をエンコードしてファイルに書き込むために liblame を使用する私のコードです。

//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;
}

このコードを修正するにはどうすればよいですか? bufferSizes は true ですか? BufferedInputStream の使用は正しいですか? と...

4

1 に答える 1

6

昨日、lame を使用して自分のアプリケーション用に PCM から MP3 へのエンコーダーを実装しました。SimpleLameLibForAndroid を使用せず、代わりにラメを自分でプロジェクトに追加することをお勧めします。Android Studio を使用している場合、これまでに NDK を使用したことがない場合は、このガイドを参考にしてください。

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

lame 自体の実装に関しては、以下は、アプリケーションを起動して実行するために従った非常に優れたガイドです。wrapper.cページ上部の .zip からを使用します。これにより、便利なメソッドが公開されるため、厄介なことをすべて回避できStreamますBuffer

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

結局のところ、ラメエンコーダーへの実際の呼び出しは次のように非常に簡単です。

初期化の場合(好きな設定を使用してください):

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);

エンコードの場合 (非常に簡単):

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

もちろん、終了したらエンコーダーを破棄しdestroyEncoder()ます。

于 2015-12-16T21:47:56.490 に答える