wav_parser.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "wav_parser.h"
  2. #define TAG "WavParser"
  3. const char* format_text(FormatTag tag) {
  4. switch(tag) {
  5. case FormatTagPCM:
  6. return "PCM";
  7. case FormatTagIEEE_FLOAT:
  8. return "IEEE FLOAT";
  9. default:
  10. return "Unknown";
  11. }
  12. };
  13. struct WavParser {
  14. WavHeaderChunk header;
  15. WavFormatChunk format;
  16. WavDataChunk data;
  17. size_t wav_data_start;
  18. size_t wav_data_end;
  19. };
  20. WavParser* wav_parser_alloc() {
  21. return malloc(sizeof(WavParser));
  22. }
  23. void wav_parser_free(WavParser* parser) {
  24. free(parser);
  25. }
  26. bool wav_parser_parse(WavParser* parser, Stream* stream, WavPlayerApp* app) {
  27. stream_read(stream, (uint8_t*)&parser->header, sizeof(WavHeaderChunk));
  28. stream_read(stream, (uint8_t*)&parser->format, sizeof(WavFormatChunk));
  29. stream_read(stream, (uint8_t*)&parser->data, sizeof(WavDataChunk));
  30. if(memcmp(parser->header.riff, "RIFF", 4) != 0 ||
  31. memcmp(parser->header.wave, "WAVE", 4) != 0) {
  32. FURI_LOG_E(TAG, "WAV: wrong header");
  33. return false;
  34. }
  35. if(memcmp(parser->format.fmt, "fmt ", 4) != 0) {
  36. FURI_LOG_E(TAG, "WAV: wrong format");
  37. return false;
  38. }
  39. if(parser->format.tag != FormatTagPCM || memcmp(parser->data.data, "data", 4) != 0) {
  40. FURI_LOG_E(
  41. TAG,
  42. "WAV: non-PCM format %u, next '%lu'",
  43. parser->format.tag,
  44. (uint32_t)parser->data.data);
  45. return false;
  46. }
  47. FURI_LOG_I(
  48. TAG,
  49. "Format tag: %s, ch: %u, smplrate: %lu, bps: %lu, bits: %u",
  50. format_text(parser->format.tag),
  51. parser->format.channels,
  52. parser->format.sample_rate,
  53. parser->format.byte_per_sec,
  54. parser->format.bits_per_sample);
  55. app->sample_rate = parser->format.sample_rate;
  56. app->num_channels = parser->format.channels;
  57. app->bits_per_sample = parser->format.bits_per_sample;
  58. parser->wav_data_start = stream_tell(stream);
  59. parser->wav_data_end = parser->wav_data_start + parser->data.size;
  60. FURI_LOG_I(TAG, "data: %u - %u", parser->wav_data_start, parser->wav_data_end);
  61. return true;
  62. }
  63. size_t wav_parser_get_data_start(WavParser* parser) {
  64. return parser->wav_data_start;
  65. }
  66. size_t wav_parser_get_data_end(WavParser* parser) {
  67. return parser->wav_data_end;
  68. }
  69. size_t wav_parser_get_data_len(WavParser* parser) {
  70. return parser->wav_data_end - parser->wav_data_start;
  71. }