C, or C++ code for using LAME API to convert an M4A (MPEG-4 audio) to MP3
Asked Answered
C

1

0

I'm using native LAME code for a part of my Android application. This code is supposed to take a string pointing to the input file (M4A) and a string to the output file (MP3). I found some code that seems, from what I can gather, to do such a thing. However, when I play back the MP3 files, all I hear is a ZIP! sound. No matter how long the recording is, I get the same sound.

I was thinking that this had something to do with the sample rate, so I've tried all of the standard ones, and get nearly the same result (some zips are less... zippy).

Here is the the only C code that I've been able to find, however, I'm open to using a C++ solution, as well.

#include <jni.h>  
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include "lame.h"

#define DEBUG_TAG "WBA"  

void Java_net_smartnotes_media_RawAudioRecorder_transcode(JNIEnv * env, jobject this, jstring from, jstring to) {
    jboolean isCopy;  
    const char * szFrom = (*env)->GetStringUTFChars(env, from, &isCopy);
    const char * szTo = (*env)->GetStringUTFChars(env, to, &isCopy);

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szFrom);
    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szTo);

    int read, write;

    FILE *pcm = fopen(szFrom, "rb");
    FILE *mp3 = fopen(szTo, "wb");

    const int PCM_SIZE = 8192;
    const int MP3_SIZE = 8192;

    short int pcm_buffer[PCM_SIZE*2];
    unsigned char mp3_buffer[MP3_SIZE];

    lame_t lame = lame_init();
    lame_set_in_samplerate(lame, 44100);
    lame_set_VBR(lame, vbr_default);
    lame_init_params(lame);

    do {
        read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
        if (read == 0)
            write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
        else
            write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
        fwrite(mp3_buffer, write, 1, mp3);
    } while (read != 0);

    lame_close(lame);
    fclose(mp3);
    fclose(pcm);

    (*env)->ReleaseStringUTFChars(env, from, szFrom);
    (*env)->ReleaseStringUTFChars(env, to, szTo); 
 }
Clywd answered 4/2, 2012 at 6:48 Comment(0)
E
3

You are not decoding the M4A audio into raw audio data before sending it into LAME.

"PCM audio" means no compression.

Eruptive answered 4/2, 2012 at 7:7 Comment(4)
I understand that it looks that way from the variables that are being set, however I'm sure there is a way to tell LAME to take an MPEG-4 encoded audio file and convert it to an MP3. I simply just didn't change any of the variable names, so I can understand how you see the PCM part as the problem.Clywd
No there isn't such way. LAME will never ever understand MPEG-4 encoded audio data. You can't expect for LAME to support decoding every possible format (OGG, FLAC, AAC, etc...), right? Or else it will be huge library. It accepts only PCM audio data. You must decode your MPEG-4 data before feeding it to LAME using some other library.Melody
Thanks for your answers, guys. I had to change the recording method from a MediaRecorder to an AudioRecord in my Android app. The AudioRecord method allows the output of raw PCM, which LAME was finally able to convert to an MP3! The problem that I'm having now is that I sound like a chipmunk, but I suspect that's something to do with the way that I'm putting together the PCM file, and I'll get that sorted out. Thanks again!Clywd
That's usually because the sample rate is wrong--e.g. you recorded 22KHz and told LAME it was 44KHz.Eruptive

© 2022 - 2024 — McMap. All rights reserved.