2015-11-15 2 views
4

J'utilise SimpleLameLibForAndroid pour convertir un fichier pcm qui a créé en utilisant la classe AudioRecord dans android, en mp3. J'ai lu le fichier pcm et l'ai encodé en mp3, puis je l'ai écrit dans le fichier. le résultat du fichier mp3 mais n'est pas correct et il y a beaucoup de bruit dessus et vraiment dur à comprendre qu'il a été enregistré au format pcm. ceux-ci sont enregistrées spécifications audio (fichier pcm):convertir le fichier pcm en mp3 en utilisant liblame en android

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

ce qui est mon code qui utilise liblame pour mp3 encode et l'écrire dans le fichier:

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

Comment puis-je résoudre ce code, est le bufferSizes vrai? utilisant BufferedInputStream est correct? et ...

Répondre

5

J'ai implémenté un encodeur PCM vers MP3 juste hier pour mon application en utilisant lame. Je suggère de ne pas utiliser SimpleLameLibForAndroid et d'ajouter plutôt boiteux à votre projet vous-même. Si vous utilisez Android Studio, voici un bon guide pour vous aider à démarrer si vous n'avez pas encore utilisé NDK.

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

En ce qui concerne la mise en œuvre lui-même boiteux, ci-dessous est un guide vraiment bon que j'ai suivi pour obtenir ma demande et en cours d'exécution. Utilisez le wrapper.c à partir du fichier .zip en haut de la page. Cela expose des méthodes utiles afin que vous puissiez éviter toutes les mauvaises choses Stream et Buffer.

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

Quand tout est dit et fait, les appels réels au codeur boiteux sont super simples comme suit.

Pour initialiser (utiliser tous les réglages que vous aimez):

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

Pour le codage (très facile):

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

Et bien sûr détruire l'encodeur lorsque vous avez terminé avec destroyEncoder().