c++portaudioopus

Encoded Sound loses data when encoding Opus


I'm trying to encode with Opus some data recorded via PortAudio, so whenever I try to encode data, the written data is lost because the unsigned char vector ends up being empty for every iteration of the vector, the original data is recorded from PortAudio

here are my structures :

typedef struct {
    int size;
    std::vector<unsigned char> *sound;
} AudioEnc;

typedef struct {
    int size;
    std::vector<float> sound;
} AudioData;

here is my encode code :

#define SAMPLE_RATE (48000)
#define FRAMES_PER_BUFFER (1920)
#define NUM_SECONDS (1)

    AudioEnc Opus::Encode(AudioData data)
    {
        AudioEnc enc = {.size = 0, .sound = new std::vector<unsigned char>};
        unsigned int max_size =  NUM_SECONDS * SAMPLE_RATE;
        float sound[max_size];
    
        enc.sound->resize(max_size);
        if (data.size == 0)
            enc.size = opus_encode_float(_encode, sound, FRAMES_PER_BUFFER, enc.sound->data(), max_size);
        else
            enc.size = opus_encode_float(_encode, data.sound.data(), FRAMES_PER_BUFFER, enc.sound->data(), max_size);
        return (enc);
    }
    
    AudioData Opus::Decode(AudioEnc data)
    {
        AudioData dec;
        dec.sound.resize(NUM_SECONDS * SAMPLE_RATE * 2);
        dec.size = opus_decode_float(_decode, data.sound->data(), data.size, dec.sound.data(), FRAMES_PER_BUFFER, 0) * 2;
        return (dec);
    } 

when i iterate through enc after the opus_encode_float method, all the values of sound are empty.

Do you guys have any idea on what's wrong ?


Solution

  • It looks like the problem is that you're keeping two sizes. You're mixing C and C++ style, which probably explains the std::vector<unsigned char> *. But more importantly, std::vector<unsigned char> stores its own size, yet you also store a seprate size. And it looks like they don't agree.

    The fix is easy. Don't store that .size in AudioEnc and AudioData. Instead, call .resize on the vectors to remember the size returned from Opus. This will discard the unused entries.