Skip to main content
Topic: raw mulaw to mp3  (Read 210 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

raw mulaw to mp3

I looked through the forums and found this topic asked many times but with very few responses
I'm having the same issue .. has this ever been resolved in code ?
I attached input and output images (notice the output is really distorted)

I could not figure out how to let lame to go from raw to mp3 so I employed sox
The image of the input represents the sox output wav file
Please don't be fooled by that .. if you know a practice to just use lame please kindly share.
The goal is to convert mulaw encoded raw data to mp3 (it comes from a telephony device)

My platform is C on ubuntu 1804LTS .. this is the conversion code

//compile with
//gcc -v example0.c -lmp3lame -lsox -o ./build/example0
//call as
//./example0 raw_ULaw_8000Hz_1CH.raw 1.mp3
#ifdef NDEBUG /* N.B. assert used with active statements so enable always. */
#undef NDEBUG /* Must undef above assert.h or other that might include it. */
#endif

#include "sox.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <lame/lame.h>

/**
 * @brief lame error reporting function
 *
 * @param format
 * @param ap
 */
void my_debugf(const char *format, va_list ap)
{
    (void) vfprintf(stdout, format, ap);
}
   
int main(int argc, char * argv[])
{
    static sox_format_t * in, * out; /* input and output files */
    sox_effects_chain_t * chain;
    sox_effect_t * e;
    char * args[10];

    //assert(argc == 3);
    char  infile [50];
    char  infileType [50];
    char  outfile [50];
    strcpy(infile, argv[1]);//"raw_ULaw_8000Hz_1CH.raw");
    strcpy(infileType,"raw");

    sox_encodinginfo_t encondingInfo;
    encondingInfo.encoding = SOX_ENCODING_ULAW;
    encondingInfo.bits_per_sample = 8;   
    sox_signalinfo_t signalinfo;   
    signalinfo.rate = 8000;   
    signalinfo.precision = 14;
    signalinfo.channels = 1;
    signalinfo.length = SOX_UNSPEC;
    //signalinfo.mult = 1;//<-------------------------------
    sox_signalinfo_t signalinfoWrite;
    signalinfoWrite.length = SOX_UNSPEC;
    signalinfoWrite.channels = 1;
    sox_encodinginfo_t encondingInfoWrite;
    encondingInfoWrite.encoding = SOX_ENCODING_UNKNOWN;
    encondingInfoWrite.bits_per_sample = 32;   

    /* All libSoX applications must start by initialising the SoX library */
    assert(sox_init() == SOX_SUCCESS);

    /* Open the input file (with default parameters) */
    //assert(in = sox_open_read(argv[1], NULL, NULL, NULL));
    assert(in = sox_open_read(infile, &signalinfo, &encondingInfo, infileType));

    /* Open the output file; we must specify the output signal characteristics.
     * Since we are using only simple effects, they are the same as the input
     * file characteristics */
    strcpy(outfile,"./output.wav");
    assert(out = sox_open_write(outfile, &in->signal, NULL, NULL, NULL, NULL));

    /* Create an effects chain; some effects need to know about the input
     * or output file encoding so we provide that information here */
    chain = sox_create_effects_chain(&in->encoding, &out->encoding);

    /* The first effect in the effect chain must be something that can source
     * samples; in this case, we use the built-in handler that inputs
     * data from an audio file */
    e = sox_create_effect(sox_find_effect("input"));
    args[0] = (char *)in, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
    /* This becomes the first `effect' in the chain */
    assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
    free(e);




    /* The last effect in the effect chain must be something that only consumes
     * samples; in this case, we use the built-in handler that outputs
     * data to an audio file */
    e = sox_create_effect(sox_find_effect("output"));
    args[0] = (char *)out, assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
    assert(sox_add_effect(chain, e, &in->signal, &in->signal) == SOX_SUCCESS);
    free(e);

    /* Flow samples through the effects processing chain until EOF is reached */
    sox_flow_effects(chain, NULL, NULL);

    /* All done; tidy up: */
    sox_delete_effects_chain(chain);
    sox_close(out);
    sox_close(in);
    sox_quit();

    int read, write;
    FILE *pcm = fopen("./output.wav", "rb");
    FILE *mp3 = fopen("./convertedFile.mp3", "wb");
    int n_bytes_read;
    int n_bytes_write;
    int i;
#define PCM_BUF_SIZE 1024
#define MP3_SIZE 8192

    short pcm_buffer_s[PCM_BUF_SIZE];
    unsigned char pcm_buffer[PCM_BUF_SIZE];   
    unsigned char mp3_buffer[MP3_SIZE];

    lame_global_flags *lame;
    //lame_t lame = lame_init();
    lame = lame_init();
    lame_set_num_channels(lame, 1);
    lame_set_in_samplerate(lame, 8000);
    lame_set_analysis(lame, 1);// debug .. get statistics data
    lame_set_errorf(lame, my_debugf);// debug .. get logging out of lame
    lame_set_msgf(lame, my_debugf);// debug .. get logging out of lame
    // from audacity
    lame_set_error_protection(lame, 0);
    lame_set_out_samplerate(lame,8000);
    lame_set_disable_reservoir(lame,0);
    lame_set_bWriteVbrTag(lame,1);
    lame_set_preset(lame, 1007);//standard quality and fast
    lame_set_VBR(lame, vbr_off);
    // end from audacity

    //lame_set_brate(lame, 128);   
    lame_set_mode(lame,MONO);
    int ret = lame_init_params(lame);
    if (ret >=0)
    {
        // print configuration
        lame_print_config(lame);

        do {
            n_bytes_read = fread(pcm_buffer, sizeof(char), PCM_BUF_SIZE, pcm);

           // TODO .. is this conversion right ? (it's done all over the internet unsigned char to unsigned short)
            for (i = 0; i < n_bytes_read; i++) {
                pcm_buffer_s = (short)(pcm_buffer - 0x80) << 8;
            }
            if (n_bytes_read == 0) {
                n_bytes_write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
               
            } else {
                n_bytes_write = lame_encode_buffer(lame, pcm_buffer_s, NULL, n_bytes_read, mp3_buffer, MP3_SIZE);
                //n_bytes_write = lame_encode_buffer(lame, pcm_buffer, NULL, n_bytes_read, mp3_buffer, MP3_SIZE);
            }
            fwrite(mp3_buffer, sizeof(char), n_bytes_write, mp3);
        } while (n_bytes_read > 0);
       
       
       
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);

        return 0;
    } else { printf("failed to initialize lame\n"); }
}

Re: raw mulaw to mp3

Reply #1
mu-Law and a-Law are not just 8 bit PCM. They are a specially encoded 12 bit PCM, with a sort of logarithmic scale. I'd advise researching a proper decoder for it, or even just using libsndfile with the correct raw input parameters.

Re: raw mulaw to mp3

Reply #2
Quote
I attached input and output images (notice the output is really distorted)
That's Audacity, right?   Since it's opening and decoding OK in Audacity you can simply export to MP3 from Audacity.
 

 
SimplePortal 1.0.0 RC1 © 2008-2020