1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #pragma once
6
7 #include <endian.h>
8 #include <zircon/compiler.h>
9 #include <zircon/types.h>
10
11 namespace internal {
make_fourcc(uint8_t a,uint8_t b,uint8_t c,uint8_t d)12 static inline constexpr uint32_t make_fourcc(uint8_t a, uint8_t b,
13 uint8_t c, uint8_t d) {
14 return (static_cast<uint32_t>(d) << 24) |
15 (static_cast<uint32_t>(c) << 16) |
16 (static_cast<uint32_t>(b) << 8) |
17 static_cast<uint32_t>(a);
18 }
19 }
20
21 class WAVCommon {
22 public:
WAVCommon()23 WAVCommon() { }
~WAVCommon()24 virtual ~WAVCommon() { Close(); }
25
26 protected:
27 struct __PACKED RIFFChunkHeader {
28 uint32_t four_cc;
29 uint32_t length;
30
FixupEndianRIFFChunkHeader31 void FixupEndian() {
32 four_cc = htole32(four_cc);
33 length = htole32(length);
34 }
35 };
36
37 struct __PACKED WAVHeader {
38 uint32_t wave_four_cc;
39 uint32_t fmt_four_cc;
40 uint32_t fmt_chunk_len;
41 uint16_t format;
42 uint16_t channel_count;
43 uint32_t frame_rate;
44 uint32_t average_byte_rate;
45 uint16_t frame_size;
46 uint16_t bits_per_sample;
47
FixupEndianWAVHeader48 void FixupEndian() {
49 wave_four_cc = htole32(wave_four_cc);
50 fmt_four_cc = htole32(fmt_four_cc);
51 fmt_chunk_len = htole32(fmt_chunk_len);
52 format = htole16(format);
53 channel_count = htole16(channel_count);
54 frame_rate = htole32(frame_rate);
55 average_byte_rate = htole32(average_byte_rate);
56 frame_size = htole16(frame_size);
57 bits_per_sample = htole16(bits_per_sample);
58 }
59 };
60
61 enum class InitMode { SOURCE, SINK };
62 zx_status_t Initialize(const char* filename, InitMode mode);
63
64 static constexpr uint32_t RIFF_FOUR_CC = internal::make_fourcc('R', 'I', 'F', 'F');
65 static constexpr uint32_t WAVE_FOUR_CC = internal::make_fourcc('W', 'A', 'V', 'E');
66 static constexpr uint32_t FMT_FOUR_CC = internal::make_fourcc('f', 'm', 't', ' ');
67 static constexpr uint32_t DATA_FOUR_CC = internal::make_fourcc('d', 'a', 't', 'a');
68
69 // WAV/AVI format codes are defined in RFC 2361. Also, the list goes on for
70 // 55 pages, so we don't list the vast majority of them here.
71 static constexpr uint16_t FORMAT_UNKNOWN = 0x0000;
72 static constexpr uint16_t FORMAT_LPCM = 0x0001;
73 static constexpr uint16_t FORMAT_MSFT_ADPCM = 0x0002;
74 static constexpr uint16_t FORMAT_IEEE_FLOAT = 0x0003;
75 static constexpr uint16_t FORMAT_MSFT_ALAW = 0x0006;
76 static constexpr uint16_t FORMAT_MSFT_MULAW = 0x0007;
77
78 void Close();
79 zx_status_t Read(void* buf, size_t len);
80 zx_status_t Write(const void* buf, size_t len);
81 zx_status_t Seek(off_t abs_pos);
82
83 int fd_ = -1;
84 };
85
86