xref: /aosp_15_r20/external/webrtc/common_audio/wav_header.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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