xref: /aosp_15_r20/external/webrtc/common_audio/wav_file.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_FILE_H_
12*d9f75844SAndroid Build Coastguard Worker #define COMMON_AUDIO_WAV_FILE_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include <cstddef>
17*d9f75844SAndroid Build Coastguard Worker #include <string>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "common_audio/wav_header.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/file_wrapper.h"
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker // Interface to provide access WAV file parameters.
25*d9f75844SAndroid Build Coastguard Worker class WavFile {
26*d9f75844SAndroid Build Coastguard Worker  public:
27*d9f75844SAndroid Build Coastguard Worker   enum class SampleFormat { kInt16, kFloat };
28*d9f75844SAndroid Build Coastguard Worker 
~WavFile()29*d9f75844SAndroid Build Coastguard Worker   virtual ~WavFile() {}
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker   virtual int sample_rate() const = 0;
32*d9f75844SAndroid Build Coastguard Worker   virtual size_t num_channels() const = 0;
33*d9f75844SAndroid Build Coastguard Worker   virtual size_t num_samples() const = 0;
34*d9f75844SAndroid Build Coastguard Worker };
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker // Simple C++ class for writing 16-bit integer and 32 bit floating point PCM WAV
37*d9f75844SAndroid Build Coastguard Worker // files. All error handling is by calls to RTC_CHECK(), making it unsuitable
38*d9f75844SAndroid Build Coastguard Worker // for anything but debug code.
39*d9f75844SAndroid Build Coastguard Worker class WavWriter final : public WavFile {
40*d9f75844SAndroid Build Coastguard Worker  public:
41*d9f75844SAndroid Build Coastguard Worker   // Opens a new WAV file for writing.
42*d9f75844SAndroid Build Coastguard Worker   WavWriter(absl::string_view filename,
43*d9f75844SAndroid Build Coastguard Worker             int sample_rate,
44*d9f75844SAndroid Build Coastguard Worker             size_t num_channels,
45*d9f75844SAndroid Build Coastguard Worker             SampleFormat sample_format = SampleFormat::kInt16);
46*d9f75844SAndroid Build Coastguard Worker   WavWriter(FileWrapper file,
47*d9f75844SAndroid Build Coastguard Worker             int sample_rate,
48*d9f75844SAndroid Build Coastguard Worker             size_t num_channels,
49*d9f75844SAndroid Build Coastguard Worker             SampleFormat sample_format = SampleFormat::kInt16);
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker   // Closes the WAV file, after writing its header.
~WavWriter()52*d9f75844SAndroid Build Coastguard Worker   ~WavWriter() { Close(); }
53*d9f75844SAndroid Build Coastguard Worker 
54*d9f75844SAndroid Build Coastguard Worker   WavWriter(const WavWriter&) = delete;
55*d9f75844SAndroid Build Coastguard Worker   WavWriter& operator=(const WavWriter&) = delete;
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker   // Write additional samples to the file. Each sample is in the range
58*d9f75844SAndroid Build Coastguard Worker   // [-32768.0,32767.0], and there must be the previously specified number of
59*d9f75844SAndroid Build Coastguard Worker   // interleaved channels.
60*d9f75844SAndroid Build Coastguard Worker   void WriteSamples(const float* samples, size_t num_samples);
61*d9f75844SAndroid Build Coastguard Worker   void WriteSamples(const int16_t* samples, size_t num_samples);
62*d9f75844SAndroid Build Coastguard Worker 
sample_rate()63*d9f75844SAndroid Build Coastguard Worker   int sample_rate() const override { return sample_rate_; }
num_channels()64*d9f75844SAndroid Build Coastguard Worker   size_t num_channels() const override { return num_channels_; }
num_samples()65*d9f75844SAndroid Build Coastguard Worker   size_t num_samples() const override { return num_samples_written_; }
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker  private:
68*d9f75844SAndroid Build Coastguard Worker   void Close();
69*d9f75844SAndroid Build Coastguard Worker   const int sample_rate_;
70*d9f75844SAndroid Build Coastguard Worker   const size_t num_channels_;
71*d9f75844SAndroid Build Coastguard Worker   size_t num_samples_written_;
72*d9f75844SAndroid Build Coastguard Worker   WavFormat format_;
73*d9f75844SAndroid Build Coastguard Worker   FileWrapper file_;
74*d9f75844SAndroid Build Coastguard Worker };
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker // Follows the conventions of WavWriter.
77*d9f75844SAndroid Build Coastguard Worker class WavReader final : public WavFile {
78*d9f75844SAndroid Build Coastguard Worker  public:
79*d9f75844SAndroid Build Coastguard Worker   // Opens an existing WAV file for reading.
80*d9f75844SAndroid Build Coastguard Worker   explicit WavReader(absl::string_view filename);
81*d9f75844SAndroid Build Coastguard Worker   explicit WavReader(FileWrapper file);
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   // Close the WAV file.
~WavReader()84*d9f75844SAndroid Build Coastguard Worker   ~WavReader() { Close(); }
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   WavReader(const WavReader&) = delete;
87*d9f75844SAndroid Build Coastguard Worker   WavReader& operator=(const WavReader&) = delete;
88*d9f75844SAndroid Build Coastguard Worker 
89*d9f75844SAndroid Build Coastguard Worker   // Resets position to the beginning of the file.
90*d9f75844SAndroid Build Coastguard Worker   void Reset();
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   // Returns the number of samples read. If this is less than requested,
93*d9f75844SAndroid Build Coastguard Worker   // verifies that the end of the file was reached.
94*d9f75844SAndroid Build Coastguard Worker   size_t ReadSamples(size_t num_samples, float* samples);
95*d9f75844SAndroid Build Coastguard Worker   size_t ReadSamples(size_t num_samples, int16_t* samples);
96*d9f75844SAndroid Build Coastguard Worker 
sample_rate()97*d9f75844SAndroid Build Coastguard Worker   int sample_rate() const override { return sample_rate_; }
num_channels()98*d9f75844SAndroid Build Coastguard Worker   size_t num_channels() const override { return num_channels_; }
num_samples()99*d9f75844SAndroid Build Coastguard Worker   size_t num_samples() const override { return num_samples_in_file_; }
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker  private:
102*d9f75844SAndroid Build Coastguard Worker   void Close();
103*d9f75844SAndroid Build Coastguard Worker   int sample_rate_;
104*d9f75844SAndroid Build Coastguard Worker   size_t num_channels_;
105*d9f75844SAndroid Build Coastguard Worker   WavFormat format_;
106*d9f75844SAndroid Build Coastguard Worker   size_t num_samples_in_file_;
107*d9f75844SAndroid Build Coastguard Worker   size_t num_unread_samples_;
108*d9f75844SAndroid Build Coastguard Worker   FileWrapper file_;
109*d9f75844SAndroid Build Coastguard Worker   int64_t
110*d9f75844SAndroid Build Coastguard Worker       data_start_pos_;  // Position in the file immediately after WAV header.
111*d9f75844SAndroid Build Coastguard Worker };
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker #endif  // COMMON_AUDIO_WAV_FILE_H_
116