title: Android Lame - convert from RAW to MP3
body: <p>I'm trying to convert 3gp to MP3 using Lame. I've got byte buffer after decoding file by built-in Android decoder. After this I put it into RAW file with OutputStream and then create MP3 using Lame. But it doesn't work. There are only noises in the file. Here is my code. Thank's for any help in advance.</p>
  
  <pre><code>public class MainActivityLame extends Activity {
  
  static {
      System.loadLibrary("mp3lame");
  }
  
  private native void initEncoder(int numChannels, int sampleRate, int bitRate, int mode, int quality);
  
  private native void destroyEncoder();
  
  private native int encodeFile(String sourcePath, String targetPath);
  
  public static final int NUM_CHANNELS = 1;
  public static final int SAMPLE_RATE = 44100;
  public static final int BITRATE = 128;
  public static final int MODE = 1;
  public static final int QUALITY = 2;
  private AudioRecord mRecorder;
  private short[] mBuffer;
  private File mRawFile;
  private File mEncodedFile;
  private TextView mTextViewFile;
  private String strFile;
  private AudioTrack audioTrack;
  private int mChannels;
  private ShortBuffer mDecodedSamples;
  private ByteBuffer mDecodedBytes;
  private int mFileSize;
  private int bufferSize;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      mTextViewFile = (TextView) findViewById(R.id.textViewFile);
  
      initRecorder();
      initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY);
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();
      if (id == R.id.action_settings) {
          return true;
      }
      return super.onOptionsItemSelected(item);
  }
  
  public void onClickFolder(View view) throws IOException {
      Intent questionIntent = new Intent(MainActivityLame.this, MyListActivity.class);
      startActivityForResult(questionIntent, 1);
  }
  
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (resultCode == RESULT_OK) {
          String itemName = data.getStringExtra(MyListActivity.ITEM);
          mTextViewFile.setText(itemName);
      } else {
          mTextViewFile.setText("");
      }
  }
  
  @Override
  public void onDestroy() {
      mRecorder.release();
      destroyEncoder();
      super.onDestroy();
  }
  
  private void initRecorder() {
      bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
              AudioFormat.ENCODING_PCM_16BIT);
      mBuffer = new short[bufferSize];
      mRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
              AudioFormat.ENCODING_PCM_16BIT, bufferSize);
  }
  
  private File getFile(final String suffix) {
      Time time = new Time();
      time.setToNow();
      return new File(Environment.getExternalStorageDirectory(), time.format("%Y%m%d%H%M%S") + "." + suffix);
  }
  
  public void onClickExample(View view) {
      strFile = mTextViewFile.getText().toString().trim();
      MediaExtractor extractor = new MediaExtractor();
      MediaFormat format = null;
      extractor.setDataSource(strFile);
  
      int numTracks = extractor.getTrackCount();
      for (int i = 0; i &lt; numTracks; ++i) {
          format = extractor.getTrackFormat(i);
          String mime = format.getString(MediaFormat.KEY_MIME);
          if (mime.startsWith("audio/")) {
              extractor.selectTrack(i);
              break;
          }
      }
  
      MediaCodec codec = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME));
      codec.configure(format, null, null, 0);
      codec.start();
  
      int decodedSamplesSize = 0;
      byte[] decodedSamples = null;
      ByteBuffer[] inputBuffers = codec.getInputBuffers();
      ByteBuffer[] outputBuffers = codec.getOutputBuffers();
      int sample_size;
      MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
      long presentation_time;
      int tot_size_read = 0;
      boolean done_reading = false;
  
      mDecodedBytes = ByteBuffer.allocate(1 &lt;&lt; 20);
      while (true) {
          int inputBufferId = codec.dequeueInputBuffer(100);
          if (!done_reading &amp;&amp; inputBufferId &gt;= 0) {
              sample_size = extractor.readSampleData(inputBuffers[inputBufferId], 0);
              if (sample_size &lt; 0) {
                  codec.queueInputBuffer(inputBufferId, 0, 0, -1, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                  done_reading = true;
              } else {
                  presentation_time = extractor.getSampleTime();
                  codec.queueInputBuffer(inputBufferId, 0, sample_size, presentation_time, 0);
                  extractor.advance();
                  tot_size_read += sample_size;
              }
          }
  
          int outputBufferId = codec.dequeueOutputBuffer(info, 100);
          if (outputBufferId &gt;= 0 &amp;&amp; info.size &gt; 0) {
              if (decodedSamplesSize &lt; info.size) {
                  decodedSamplesSize = info.size;
                  decodedSamples = new byte[decodedSamplesSize];
              }
              outputBuffers[outputBufferId].get(decodedSamples, 0, info.size);
              outputBuffers[outputBufferId].clear();
              if (mDecodedBytes.remaining() &lt; info.size) {
                  int position = mDecodedBytes.position();
                  int newSize = (int) ((position * (1.0 * mFileSize / tot_size_read)) * 1.2);
                  if (newSize - position &lt; info.size + 5 * (1 &lt;&lt; 20)) {
                      newSize = position + info.size + 5 * (1 &lt;&lt; 20);
                  }
                  ByteBuffer newDecodedBytes = null;
                  int retry = 10;
                  while (retry &gt; 0) {
                      try {
                          newDecodedBytes = ByteBuffer.allocate(newSize);
                          break;
                      } catch (OutOfMemoryError oome) {
                          retry--;
                      }
                  }
                  if (retry == 0) {
                      break;
                  }
                  mDecodedBytes.rewind();
                  newDecodedBytes.put(mDecodedBytes);
                  mDecodedBytes = newDecodedBytes;
                  mDecodedBytes.position(position);
              }
              mDecodedBytes.put(decodedSamples, 0, info.size);
              codec.releaseOutputBuffer(outputBufferId, false);
          } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
              outputBuffers = codec.getOutputBuffers();
          } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
              // Subsequent data will conform to new format.
              format = codec.getOutputFormat();
          }
          if ((info.flags &amp; MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
              break;
          }
      }
  
      extractor.release();
      extractor = null;
      codec.stop();
      codec.release();
      codec = null;
  
      mDecodedBytes.rewind();
      mDecodedBytes.order(ByteOrder.LITTLE_ENDIAN);
      mDecodedSamples = mDecodedBytes.asShortBuffer();
  
      mRawFile = getFile("raw");  
      OutputStream output = null;
      try {
          output = new BufferedOutputStream(new FileOutputStream(mRawFile));
          try {
              output.write(mDecodedBytes.array());
          } catch (IOException e) {
              e.printStackTrace();
          }
      } catch (IOException e) {
          Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
      } finally {
          if (output != null) {
              try {
                  output.flush();
              } catch (IOException e) {
                  Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
              } finally {
                  try {
                      output.close();
                  } catch (IOException e) {
                      Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                  }
              }
          }
      }
  
      mEncodedFile = getFile("mp3");
      int result = encodeFile(mRawFile.getAbsolutePath(), mEncodedFile.getAbsolutePath());
      if (result == 0) {
          Toast.makeText(MainActivityLame.this, "Encoded to " + mEncodedFile.getName(), Toast.LENGTH_SHORT).show();
      }
  }
  }
  </code></pre>