1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_COMMON_AUDIO_WAV_FILE_H_
12 #define WEBRTC_COMMON_AUDIO_WAV_FILE_H_
13 
14 #ifdef __cplusplus
15 
16 #include <stdint.h>
17 #include <cstddef>
18 #include <string>
19 
20 #include "webrtc/base/constructormagic.h"
21 
22 namespace webrtc {
23 
24 // Interface to provide access to WAV file parameters.
25 class WavFile {
26  public:
~WavFile()27   virtual ~WavFile() {}
28 
29   virtual int sample_rate() const = 0;
30   virtual size_t num_channels() const = 0;
31   virtual size_t num_samples() const = 0;
32 
33   // Returns a human-readable string containing the audio format.
34   std::string FormatAsString() const;
35 };
36 
37 // Simple C++ class for writing 16-bit PCM WAV files. All error handling is
38 // by calls to RTC_CHECK(), making it unsuitable for anything but debug code.
39 class WavWriter final : public WavFile {
40  public:
41   // Open a new WAV file for writing.
42   WavWriter(const std::string& filename, int sample_rate, size_t num_channels);
43 
44   // Close the WAV file, after writing its header.
45   ~WavWriter();
46 
47   // Write additional samples to the file. Each sample is in the range
48   // [-32768,32767], and there must be the previously specified number of
49   // interleaved channels.
50   void WriteSamples(const float* samples, size_t num_samples);
51   void WriteSamples(const int16_t* samples, size_t num_samples);
52 
sample_rate()53   int sample_rate() const override { return sample_rate_; }
num_channels()54   size_t num_channels() const override { return num_channels_; }
num_samples()55   size_t num_samples() const override { return num_samples_; }
56 
57  private:
58   void Close();
59   const int sample_rate_;
60   const size_t num_channels_;
61   size_t num_samples_;  // Total number of samples written to file.
62   FILE* file_handle_;  // Output file, owned by this class
63 
64   RTC_DISALLOW_COPY_AND_ASSIGN(WavWriter);
65 };
66 
67 // Follows the conventions of WavWriter.
68 class WavReader final : public WavFile {
69  public:
70   // Opens an existing WAV file for reading.
71   explicit WavReader(const std::string& filename);
72 
73   // Close the WAV file.
74   ~WavReader();
75 
76   // Returns the number of samples read. If this is less than requested,
77   // verifies that the end of the file was reached.
78   size_t ReadSamples(size_t num_samples, float* samples);
79   size_t ReadSamples(size_t num_samples, int16_t* samples);
80 
sample_rate()81   int sample_rate() const override { return sample_rate_; }
num_channels()82   size_t num_channels() const override { return num_channels_; }
num_samples()83   size_t num_samples() const override { return num_samples_; }
84 
85  private:
86   void Close();
87   int sample_rate_;
88   size_t num_channels_;
89   size_t num_samples_;  // Total number of samples in the file.
90   size_t num_samples_remaining_;
91   FILE* file_handle_;  // Input file, owned by this class.
92 
93   RTC_DISALLOW_COPY_AND_ASSIGN(WavReader);
94 };
95 
96 }  // namespace webrtc
97 
98 extern "C" {
99 #endif  // __cplusplus
100 
101 // C wrappers for the WavWriter class.
102 typedef struct rtc_WavWriter rtc_WavWriter;
103 rtc_WavWriter* rtc_WavOpen(const char* filename,
104                            int sample_rate,
105                            size_t num_channels);
106 void rtc_WavClose(rtc_WavWriter* wf);
107 void rtc_WavWriteSamples(rtc_WavWriter* wf,
108                          const float* samples,
109                          size_t num_samples);
110 int rtc_WavSampleRate(const rtc_WavWriter* wf);
111 size_t rtc_WavNumChannels(const rtc_WavWriter* wf);
112 size_t rtc_WavNumSamples(const rtc_WavWriter* wf);
113 
114 #ifdef __cplusplus
115 }  // extern "C"
116 #endif
117 
118 #endif  // WEBRTC_COMMON_AUDIO_WAV_FILE_H_
119