MPG123 PCM

I've been trying to use MPG123 to convert mp3 data to pcm. I've seen solution's related to this right here on stack overflow. However there is one major issue I can't seem to get around. No matter what changes I make to the code below the PCM data always produces heavily distorted audio. Why does this specific piece of code below always produce distorted audio when used in audacity. Thank you in advance to anyone who decides to reply.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <string>
#include <mpg123.h>
using namespace std;

int decodeMp3(string filename, string outString)
{
    mpg123_handle *mh;
    //unsigned char *buffer;
    unsigned char *buffer;
    size_t buffer_size;
    size_t done;
    int err;

    int channels, encoding;
    long rate;

    mpg123_init();
    mh = mpg123_new(NULL, &err);
    buffer_size = mpg123_outblock(mh);
    buffer = (unsigned char*)malloc(buffer_size * sizeof(unsigned char));

    /* open the file and get the decoding format */
    mpg123_open(mh, filename.c_str());
    mpg123_getformat(mh, &rate, &channels, &encoding);

    /* set the output format and open the output device */
    int m_bits = mpg123_encsize(encoding);
    int m_rate = rate;
    int m_channels = channels;
    std::ofstream out(outString.c_str());
    /* decode and play */
    for (int totalBtyes = 0; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK; ) 
    {
        char *data = new char[done + 1];
        for (int i = 0; i != done; i++)
        {
            char tst = static_cast<char>(buffer[i]);
            //cout << done << " " << sizeof(data) << endl;
            out << tst;
        }

        totalBtyes += done;
    }
    //out << buffer[i];

    cout << "Buffer size " << buffer_size << endl;
    cout << "Done " << done << endl;
    cout << "err " << err << endl;
    cout << "channels " << channels << endl;
    cout << "encoding " << encoding << endl;
    cout << "Rate " << rate << endl;
    cout << "m_bits " << m_bits << endl;
    cout << "m_rate " << m_rate << endl;
    cout << "m_channels " << m_channels << endl;
    cout << "The size of buffer " << sizeof(buffer) << endl;
    /* clean up */
    free(buffer);
    out.close();
    mpg123_close(mh);
    mpg123_delete(mh);
    mpg123_exit();
    return 0;
}
Hi Atton,

Haven't really examined your code closely, but I have a funny feeling it has to do with line 31 of your snippet.
Depending on your operating system, this line could produce different results. I know that on windows, by default, unless the file is a binary file (which yours is not), a byte with the value of 10 (newline on the ascii table) will be immediately followed by a byte with a value of 13 (carriage return), because this is what windows expects for non-binary files. In other words, the file writing operation appends a byte with a value of 13 after any instance of a byte whose value happens to be 10. This could result in the corruption of PCM audio data or even file header meta data (samplerate, bitdepth, etc), producing definite distortion. I know, because I've had this exact problem some time ago, a simple oversight.

To fix this, simply change line 31 to:
std::ofstream out(outString.c_str(), std::ios::binary);

This flag will signify that the file is a binary file.
Last edited on
Topic archived. No new replies allowed.