mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-29 08:56:18 +02:00
decoder gets sample format from header
This commit is contained in:
parent
1d1ef239b2
commit
eed7f287fb
10 changed files with 216 additions and 114 deletions
|
@ -16,8 +16,42 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "common/snapException.h"
|
||||
#include "common/log.h"
|
||||
#include "pcmDecoder.h"
|
||||
|
||||
|
||||
#define ID_RIFF 0x46464952
|
||||
#define ID_WAVE 0x45564157
|
||||
#define ID_FMT 0x20746d66
|
||||
#define ID_DATA 0x61746164
|
||||
|
||||
struct riff_wave_header
|
||||
{
|
||||
uint32_t riff_id;
|
||||
uint32_t riff_sz;
|
||||
uint32_t wave_id;
|
||||
};
|
||||
|
||||
|
||||
struct chunk_header
|
||||
{
|
||||
uint32_t id;
|
||||
uint32_t sz;
|
||||
};
|
||||
|
||||
|
||||
struct chunk_fmt
|
||||
{
|
||||
uint16_t audio_format;
|
||||
uint16_t num_channels;
|
||||
uint32_t sample_rate;
|
||||
uint32_t byte_rate;
|
||||
uint16_t block_align;
|
||||
uint16_t bits_per_sample;
|
||||
};
|
||||
|
||||
|
||||
PcmDecoder::PcmDecoder() : Decoder()
|
||||
{
|
||||
}
|
||||
|
@ -29,9 +63,61 @@ bool PcmDecoder::decode(msg::PcmChunk* chunk)
|
|||
}
|
||||
|
||||
|
||||
bool PcmDecoder::setHeader(msg::Header* chunk)
|
||||
msg::SampleFormat PcmDecoder::setHeader(msg::Header* chunk)
|
||||
{
|
||||
return true;
|
||||
if (chunk->payloadSize < 44)
|
||||
throw SnapException("PCM header too small");
|
||||
|
||||
struct riff_wave_header riff_wave_header;
|
||||
struct chunk_header chunk_header;
|
||||
struct chunk_fmt chunk_fmt;
|
||||
chunk_fmt.sample_rate = 0;
|
||||
|
||||
size_t pos(0);
|
||||
memcpy(&riff_wave_header, chunk->payload + pos, sizeof(riff_wave_header));
|
||||
pos += sizeof(riff_wave_header);
|
||||
if ((riff_wave_header.riff_id != ID_RIFF) || (riff_wave_header.wave_id != ID_WAVE))
|
||||
throw SnapException("Not a riff/wave header");
|
||||
|
||||
bool moreChunks(true);
|
||||
do
|
||||
{
|
||||
if (pos + sizeof(chunk_header) > chunk->payloadSize)
|
||||
throw SnapException("riff/wave header incomplete");
|
||||
memcpy(&chunk_header, chunk->payload + pos, sizeof(chunk_header));
|
||||
pos += sizeof(chunk_header);
|
||||
switch (chunk_header.id)
|
||||
{
|
||||
case ID_FMT:
|
||||
if (pos + sizeof(chunk_fmt) > chunk->payloadSize)
|
||||
throw SnapException("riff/wave header incomplete");
|
||||
memcpy(&chunk_fmt, chunk->payload + pos, sizeof(chunk_fmt));
|
||||
pos += sizeof(chunk_fmt);
|
||||
/// If the format header is larger, skip the rest
|
||||
if (chunk_header.sz > sizeof(chunk_fmt))
|
||||
pos += (chunk_header.sz - sizeof(chunk_fmt));
|
||||
break;
|
||||
case ID_DATA:
|
||||
/// Stop looking for chunks
|
||||
moreChunks = false;
|
||||
break;
|
||||
default:
|
||||
/// Unknown chunk, skip bytes
|
||||
pos += chunk_header.sz;
|
||||
}
|
||||
}
|
||||
while (moreChunks);
|
||||
|
||||
|
||||
if (chunk_fmt.sample_rate == 0)
|
||||
throw SnapException("Sample format not found");
|
||||
|
||||
msg::SampleFormat sampleFormat(
|
||||
chunk_fmt.sample_rate,
|
||||
chunk_fmt.bits_per_sample,
|
||||
chunk_fmt.num_channels);
|
||||
|
||||
return sampleFormat;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue