media: Ed25519-подписи блоков, local_attrs, MediaBlockReader, файловые вложения
This commit is contained in:
1 parent
6b765de5cc
commit
d4a396f888
20 files changed
+851
-70
No files matched your search
@@ -1,5 +1,6 @@
|
||||
#include "voiceplayback.h"
|
||||
#include "sound_manager.h"
|
||||
#include "media_blocks.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../../../lib/opus_codec.h"
|
||||
@@ -89,3 +90,63 @@ void VoicePlayer::playOpusFile(const QString& filePath) {
|
||||
pcm.size(), sampleRate, channels, duration);
|
||||
SoundManager::instance()->playRawPcm(pcm.data(), pcm.size() / channels, sampleRate, channels);
|
||||
}
|
||||
|
||||
void VoicePlayer::playOpusFromReader(MediaBlockReader& reader) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "VoicePlayer::playOpusFromReader: %s", qPrintable(reader.debugPath()));
|
||||
std::vector<int16_t> pcm;
|
||||
int sampleRate, channels;
|
||||
float duration;
|
||||
if (decodeOpusFromReader(reader, pcm, sampleRate, channels, duration) <= 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "VoicePlayer::playOpusFromReader: decode failed");
|
||||
return;
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "VoicePlayer::playOpusFromReader: decoded %zu samples %dHz %dch %.1fs",
|
||||
pcm.size(), sampleRate, channels, duration);
|
||||
SoundManager::instance()->playRawPcm(pcm.data(), pcm.size() / channels, sampleRate, channels);
|
||||
}
|
||||
|
||||
int VoicePlayer::decodeOpusFromReader(MediaBlockReader& reader, std::vector<int16_t>& outPcm,
|
||||
int& outSampleRate, int& outChannels, float& outDurationSec) {
|
||||
QByteArray data = reader.readAll();
|
||||
if (data.isEmpty()) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "VoicePlayer::decodeOpusFromReader: empty data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t* ptr = (const uint8_t*)data.constData();
|
||||
size_t len = (size_t)data.size();
|
||||
size_t off = 0;
|
||||
|
||||
if (off + 12 > len) { DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "VoicePlayer: header truncated"); return -1; }
|
||||
uint32_t magic; memcpy(&magic, ptr + off, 4); off += 4;
|
||||
if (magic != OPUS_MAGIC) { DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "VoicePlayer: bad magic %08x", magic); return -1; }
|
||||
uint32_t sr32; memcpy(&sr32, ptr + off, 4); off += 4;
|
||||
uint16_t ch16; memcpy(&ch16, ptr + off, 2); off += 2;
|
||||
uint16_t frameSamples; memcpy(&frameSamples, ptr + off, 2); off += 2;
|
||||
int sampleRate = (int)sr32, channels = (int)ch16;
|
||||
outSampleRate = sampleRate; outChannels = channels;
|
||||
|
||||
opus_codec_decoder_t* dec = opus_codec_decoder_create(sampleRate, channels);
|
||||
if (!dec) { DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "VoicePlayer: decoder create failed"); return -1; }
|
||||
|
||||
outPcm.clear();
|
||||
int frameCount = 0;
|
||||
while (off + 2 <= len) {
|
||||
uint16_t plen; memcpy(&plen, ptr + off, 2); off += 2;
|
||||
if (plen == 0) break;
|
||||
if (off + plen > len) break;
|
||||
std::vector<int16_t> frameBuf(frameSamples * channels);
|
||||
int decoded = opus_codec_decode(dec, ptr + off, plen, frameBuf.data(), frameSamples);
|
||||
off += plen;
|
||||
if (decoded > 0) {
|
||||
size_t cur = outPcm.size();
|
||||
outPcm.resize(cur + decoded * channels);
|
||||
memcpy(outPcm.data() + cur, frameBuf.data(), decoded * channels * sizeof(int16_t));
|
||||
frameCount++;
|
||||
}
|
||||
}
|
||||
outDurationSec = (float)frameCount * 20.0f / 1000.0f;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "VoicePlayer: decoded %d frames (%.1fs)", frameCount, outDurationSec);
|
||||
opus_codec_decoder_destroy(dec);
|
||||
return frameCount;
|
||||
}
|
||||
Reference in new issue
Block a user