| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #include "wav_parser.h"
- #define TAG "WavParser"
- const char* format_text(FormatTag tag) {
- switch(tag) {
- case FormatTagPCM:
- return "PCM";
- case FormatTagIEEE_FLOAT:
- return "IEEE FLOAT";
- default:
- return "Unknown";
- }
- };
- struct WavParser {
- WavHeaderChunk header;
- WavFormatChunk format;
- WavDataChunk data;
- size_t wav_data_start;
- size_t wav_data_end;
- };
- WavParser* wav_parser_alloc() {
- return malloc(sizeof(WavParser));
- }
- void wav_parser_free(WavParser* parser) {
- free(parser);
- }
- bool wav_parser_parse(WavParser* parser, Stream* stream, WavPlayerApp* app) {
- stream_read(stream, (uint8_t*)&parser->header, sizeof(WavHeaderChunk));
- stream_read(stream, (uint8_t*)&parser->format, sizeof(WavFormatChunk));
- stream_read(stream, (uint8_t*)&parser->data, sizeof(WavDataChunk));
- char segment_name[5];
- if(memcmp(parser->header.riff, "RIFF", 4) != 0) {
- strlcpy(segment_name, (char*)&parser->header.riff, sizeof(segment_name));
- FURI_LOG_E(TAG, "WAV: wrong RIFF header: '%s'", segment_name);
- return false;
- }
- if(memcmp(parser->header.wave, "WAVE", 4) != 0) {
- strlcpy(segment_name, (char*)&parser->header.wave, sizeof(segment_name));
- FURI_LOG_E(TAG, "WAV: wrong WAVE header: '%s'", segment_name);
- return false;
- }
- if(memcmp(parser->format.fmt, "fmt ", 4) != 0) {
- strlcpy(segment_name, (char*)&parser->format.fmt, sizeof(segment_name));
- FURI_LOG_E(TAG, "WAV: wrong fmt segment: '%s'", segment_name);
- return false;
- }
- if(parser->format.tag != FormatTagPCM) {
- FURI_LOG_E(
- TAG,
- "WAV: non-PCM format: %u (%s)",
- parser->format.tag,
- format_text(parser->format.tag));
- return false;
- }
- if(memcmp(parser->data.data, "LIST", 4) == 0) {
- FURI_LOG_D(TAG, "WAV: skipping LIST segment");
- stream_seek(stream, parser->data.size, StreamOffsetFromCurrent);
- stream_read(stream, (uint8_t*)&parser->data, sizeof(WavDataChunk));
- }
- if(memcmp(parser->data.data, "data", 4) != 0) {
- strlcpy(segment_name, (char*)&parser->data.data, sizeof(segment_name));
- FURI_LOG_E(TAG, "WAV: wrong data segment: '%s'", segment_name);
- return false;
- }
- FURI_LOG_I(
- TAG,
- "Format tag: %s, ch: %u, smplrate: %lu, bps: %lu, bits: %u",
- format_text(parser->format.tag),
- parser->format.channels,
- parser->format.sample_rate,
- parser->format.byte_per_sec,
- parser->format.bits_per_sample);
- app->sample_rate = parser->format.sample_rate;
- app->num_channels = parser->format.channels;
- app->bits_per_sample = parser->format.bits_per_sample;
- parser->wav_data_start = stream_tell(stream);
- parser->wav_data_end = parser->wav_data_start + parser->data.size;
- FURI_LOG_I(TAG, "data: %u - %u", parser->wav_data_start, parser->wav_data_end);
- return true;
- }
- size_t wav_parser_get_data_start(WavParser* parser) {
- return parser->wav_data_start;
- }
- size_t wav_parser_get_data_end(WavParser* parser) {
- return parser->wav_data_end;
- }
- size_t wav_parser_get_data_len(WavParser* parser) {
- return parser->wav_data_end - parser->wav_data_start;
- }
|