1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #ifndef COMMON_AUDIO_WAV_HEADER_H_
12*d9f75844SAndroid Build Coastguard Worker #define COMMON_AUDIO_WAV_HEADER_H_
13*d9f75844SAndroid Build Coastguard Worker
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
19*d9f75844SAndroid Build Coastguard Worker
20*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker // Interface providing header reading functionality.
23*d9f75844SAndroid Build Coastguard Worker class WavHeaderReader {
24*d9f75844SAndroid Build Coastguard Worker public:
25*d9f75844SAndroid Build Coastguard Worker // Returns the number of bytes read.
26*d9f75844SAndroid Build Coastguard Worker virtual size_t Read(void* buf, size_t num_bytes) = 0;
27*d9f75844SAndroid Build Coastguard Worker virtual bool SeekForward(uint32_t num_bytes) = 0;
28*d9f75844SAndroid Build Coastguard Worker virtual ~WavHeaderReader() = default;
29*d9f75844SAndroid Build Coastguard Worker virtual int64_t GetPosition() = 0;
30*d9f75844SAndroid Build Coastguard Worker };
31*d9f75844SAndroid Build Coastguard Worker
32*d9f75844SAndroid Build Coastguard Worker // Possible WAV formats.
33*d9f75844SAndroid Build Coastguard Worker enum class WavFormat {
34*d9f75844SAndroid Build Coastguard Worker kWavFormatPcm = 1, // PCM, each sample of size bytes_per_sample.
35*d9f75844SAndroid Build Coastguard Worker kWavFormatIeeeFloat = 3, // IEEE float.
36*d9f75844SAndroid Build Coastguard Worker kWavFormatALaw = 6, // 8-bit ITU-T G.711 A-law.
37*d9f75844SAndroid Build Coastguard Worker kWavFormatMuLaw = 7, // 8-bit ITU-T G.711 mu-law.
38*d9f75844SAndroid Build Coastguard Worker };
39*d9f75844SAndroid Build Coastguard Worker
40*d9f75844SAndroid Build Coastguard Worker // Header sizes for supported WAV formats.
41*d9f75844SAndroid Build Coastguard Worker constexpr size_t kPcmWavHeaderSize = 44;
42*d9f75844SAndroid Build Coastguard Worker constexpr size_t kIeeeFloatWavHeaderSize = 58;
43*d9f75844SAndroid Build Coastguard Worker
44*d9f75844SAndroid Build Coastguard Worker // Returns the size of the WAV header for the specified format.
WavHeaderSize(WavFormat format)45*d9f75844SAndroid Build Coastguard Worker constexpr size_t WavHeaderSize(WavFormat format) {
46*d9f75844SAndroid Build Coastguard Worker if (format == WavFormat::kWavFormatPcm) {
47*d9f75844SAndroid Build Coastguard Worker return kPcmWavHeaderSize;
48*d9f75844SAndroid Build Coastguard Worker }
49*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_EQ(format, WavFormat::kWavFormatIeeeFloat);
50*d9f75844SAndroid Build Coastguard Worker return kIeeeFloatWavHeaderSize;
51*d9f75844SAndroid Build Coastguard Worker }
52*d9f75844SAndroid Build Coastguard Worker
53*d9f75844SAndroid Build Coastguard Worker // Returns the maximum size of the supported WAV formats.
MaxWavHeaderSize()54*d9f75844SAndroid Build Coastguard Worker constexpr size_t MaxWavHeaderSize() {
55*d9f75844SAndroid Build Coastguard Worker return std::max(WavHeaderSize(WavFormat::kWavFormatPcm),
56*d9f75844SAndroid Build Coastguard Worker WavHeaderSize(WavFormat::kWavFormatIeeeFloat));
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker
59*d9f75844SAndroid Build Coastguard Worker // Return true if the given parameters will make a well-formed WAV header.
60*d9f75844SAndroid Build Coastguard Worker bool CheckWavParameters(size_t num_channels,
61*d9f75844SAndroid Build Coastguard Worker int sample_rate,
62*d9f75844SAndroid Build Coastguard Worker WavFormat format,
63*d9f75844SAndroid Build Coastguard Worker size_t num_samples);
64*d9f75844SAndroid Build Coastguard Worker
65*d9f75844SAndroid Build Coastguard Worker // Write a kWavHeaderSize bytes long WAV header to buf. The payload that
66*d9f75844SAndroid Build Coastguard Worker // follows the header is supposed to have the specified number of interleaved
67*d9f75844SAndroid Build Coastguard Worker // channels and contain the specified total number of samples of the specified
68*d9f75844SAndroid Build Coastguard Worker // type. The size of the header is returned in header_size. CHECKs the input
69*d9f75844SAndroid Build Coastguard Worker // parameters for validity.
70*d9f75844SAndroid Build Coastguard Worker void WriteWavHeader(size_t num_channels,
71*d9f75844SAndroid Build Coastguard Worker int sample_rate,
72*d9f75844SAndroid Build Coastguard Worker WavFormat format,
73*d9f75844SAndroid Build Coastguard Worker size_t num_samples,
74*d9f75844SAndroid Build Coastguard Worker uint8_t* buf,
75*d9f75844SAndroid Build Coastguard Worker size_t* header_size);
76*d9f75844SAndroid Build Coastguard Worker
77*d9f75844SAndroid Build Coastguard Worker // Read a WAV header from an implemented WavHeaderReader and parse the values
78*d9f75844SAndroid Build Coastguard Worker // into the provided output parameters. WavHeaderReader is used because the
79*d9f75844SAndroid Build Coastguard Worker // header can be variably sized. Returns false if the header is invalid.
80*d9f75844SAndroid Build Coastguard Worker bool ReadWavHeader(WavHeaderReader* readable,
81*d9f75844SAndroid Build Coastguard Worker size_t* num_channels,
82*d9f75844SAndroid Build Coastguard Worker int* sample_rate,
83*d9f75844SAndroid Build Coastguard Worker WavFormat* format,
84*d9f75844SAndroid Build Coastguard Worker size_t* bytes_per_sample,
85*d9f75844SAndroid Build Coastguard Worker size_t* num_samples,
86*d9f75844SAndroid Build Coastguard Worker int64_t* data_start_pos);
87*d9f75844SAndroid Build Coastguard Worker
88*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
89*d9f75844SAndroid Build Coastguard Worker
90*d9f75844SAndroid Build Coastguard Worker #endif // COMMON_AUDIO_WAV_HEADER_H_
91