编码 Opus 时,Encoded Sound 会丢失数据
Posted
技术标签:
【中文标题】编码 Opus 时,Encoded Sound 会丢失数据【英文标题】:Encoded Sound loses data when encoding Opus 【发布时间】:2021-12-02 16:40:33 【问题描述】:我正在尝试使用 Opus 对通过 PortAudio 记录的一些数据进行编码,因此每当我尝试对数据进行编码时,写入的数据都会丢失,因为 unsigned char 向量对于向量的每次迭代最终都是空的,原始数据是从 PortAudio 录制
这是我的结构:
typedef struct
int size;
std::vector<unsigned char> *sound;
AudioEnc;
typedef struct
int size;
std::vector<float> sound;
AudioData;
这是我的编码:
#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);
在 opus_encode_float 方法之后遍历 enc 时,sound 的所有值都是空的。
你们有什么想法吗?
【问题讨论】:
通常不需要动态分配std::vector
s。在内部,它已经动态分配存储。还通过引用而不是副本传递您的变量 - 这实际上甚至可能导致问题,即AudioEnc Opus::Encode(const AudioData& data) ...
float sound[max_size];
在技术上是非法的 - 只需将 max_size
设为 const 即可修复它。
另外,AudioEnc enc = .size = 0, .sound = new std::vector<unsigned char>;
正在混合 C 和 C++ 代码。
好的,所以根据大家的 cmets,我会尝试删除我的结构,所以我只能保留我的向量,我也会尝试通过引用传递所有内容。
【参考方案1】:
看起来问题在于您保留了两种尺寸。您正在混合 C 和 C++ 风格,这可能解释了 std::vector<unsigned char> *
。但更重要的是,std::vector<unsigned char>
存储自己的大小,但您也存储单独的大小。而且看起来他们不同意。
修复很简单。不要将 .size
存储在 AudioEnc 和 AudioData 中。相反,请在向量上调用 .resize
以记住从 Opus 返回的大小。这将丢弃未使用的条目。
【讨论】:
所以它应该看起来像这样:enc.sound->resize(opus_encode_float(_encode, data.sound.data(), FRAMES_PER_BUFFER, enc.sound->data(), max_size));
?
@Diamonddedo:我觉得不错。以上是关于编码 Opus 时,Encoded Sound 会丢失数据的主要内容,如果未能解决你的问题,请参考以下文章