blob: 9f1a4691d24ffb870e4533da61f7c7902fffe3a5 [file] [log] [blame]
Andrew MacDonaldcb05b722015-05-07 22:17:51 -07001/*
2 * Copyright (c) 2015 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
kwiberg0eb15ed2015-12-17 03:04:15 -080011#include <utility>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_processing/test/test_utils.h"
14#include "rtc_base/checks.h"
Niels Möllera12c42a2018-07-25 16:05:48 +020015#include "rtc_base/system/arch.h"
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070016
17namespace webrtc {
18
19RawFile::RawFile(const std::string& filename)
20 : file_handle_(fopen(filename.c_str(), "wb")) {}
21
22RawFile::~RawFile() {
23 fclose(file_handle_);
24}
25
26void RawFile::WriteSamples(const int16_t* samples, size_t num_samples) {
27#ifndef WEBRTC_ARCH_LITTLE_ENDIAN
28#error "Need to convert samples to little-endian when writing to PCM file"
29#endif
30 fwrite(samples, sizeof(*samples), num_samples, file_handle_);
31}
32
33void RawFile::WriteSamples(const float* samples, size_t num_samples) {
34 fwrite(samples, sizeof(*samples), num_samples, file_handle_);
35}
36
kwiberg62eaacf2016-02-17 06:39:05 -080037ChannelBufferWavReader::ChannelBufferWavReader(std::unique_ptr<WavReader> file)
kwiberg0eb15ed2015-12-17 03:04:15 -080038 : file_(std::move(file)) {}
aluebsb0ad43b2015-11-20 00:11:53 -080039
kwiberg942c8512016-08-29 13:10:29 -070040ChannelBufferWavReader::~ChannelBufferWavReader() = default;
41
aluebsb0ad43b2015-11-20 00:11:53 -080042bool ChannelBufferWavReader::Read(ChannelBuffer<float>* buffer) {
43 RTC_CHECK_EQ(file_->num_channels(), buffer->num_channels());
44 interleaved_.resize(buffer->size());
45 if (file_->ReadSamples(interleaved_.size(), &interleaved_[0]) !=
46 interleaved_.size()) {
47 return false;
48 }
49
50 FloatS16ToFloat(&interleaved_[0], interleaved_.size(), &interleaved_[0]);
51 Deinterleave(&interleaved_[0], buffer->num_frames(), buffer->num_channels(),
52 buffer->channels());
53 return true;
54}
55
kwiberg62eaacf2016-02-17 06:39:05 -080056ChannelBufferWavWriter::ChannelBufferWavWriter(std::unique_ptr<WavWriter> file)
kwiberg0eb15ed2015-12-17 03:04:15 -080057 : file_(std::move(file)) {}
aluebsb0ad43b2015-11-20 00:11:53 -080058
kwiberg942c8512016-08-29 13:10:29 -070059ChannelBufferWavWriter::~ChannelBufferWavWriter() = default;
60
aluebsb0ad43b2015-11-20 00:11:53 -080061void ChannelBufferWavWriter::Write(const ChannelBuffer<float>& buffer) {
62 RTC_CHECK_EQ(file_->num_channels(), buffer.num_channels());
63 interleaved_.resize(buffer.size());
64 Interleave(buffer.channels(), buffer.num_frames(), buffer.num_channels(),
65 &interleaved_[0]);
66 FloatToFloatS16(&interleaved_[0], interleaved_.size(), &interleaved_[0]);
67 file_->WriteSamples(&interleaved_[0], interleaved_.size());
68}
69
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070070void WriteIntData(const int16_t* data,
71 size_t length,
72 WavWriter* wav_file,
73 RawFile* raw_file) {
74 if (wav_file) {
75 wav_file->WriteSamples(data, length);
76 }
77 if (raw_file) {
78 raw_file->WriteSamples(data, length);
79 }
80}
81
82void WriteFloatData(const float* const* data,
pkasting25702cb2016-01-08 13:50:27 -080083 size_t samples_per_channel,
Peter Kasting69558702016-01-12 16:26:35 -080084 size_t num_channels,
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070085 WavWriter* wav_file,
86 RawFile* raw_file) {
87 size_t length = num_channels * samples_per_channel;
kwiberg62eaacf2016-02-17 06:39:05 -080088 std::unique_ptr<float[]> buffer(new float[length]);
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070089 Interleave(data, samples_per_channel, num_channels, buffer.get());
90 if (raw_file) {
91 raw_file->WriteSamples(buffer.get(), length);
92 }
93 // TODO(aluebs): Use ScaleToInt16Range() from audio_util
94 for (size_t i = 0; i < length; ++i) {
Yves Gerey665174f2018-06-19 15:03:05 +020095 buffer[i] = buffer[i] > 0
96 ? buffer[i] * std::numeric_limits<int16_t>::max()
97 : -buffer[i] * std::numeric_limits<int16_t>::min();
Andrew MacDonaldcb05b722015-05-07 22:17:51 -070098 }
99 if (wav_file) {
100 wav_file->WriteSamples(buffer.get(), length);
101 }
102}
103
104FILE* OpenFile(const std::string& filename, const char* mode) {
105 FILE* file = fopen(filename.c_str(), mode);
106 if (!file) {
107 printf("Unable to open file %s\n", filename.c_str());
108 exit(1);
109 }
110 return file;
111}
112
pkasting25702cb2016-01-08 13:50:27 -0800113size_t SamplesFromRate(int rate) {
114 return static_cast<size_t>(AudioProcessing::kChunkSizeMs * rate / 1000);
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700115}
116
Yves Gerey665174f2018-06-19 15:03:05 +0200117void SetFrameSampleRate(AudioFrame* frame, int sample_rate_hz) {
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700118 frame->sample_rate_hz_ = sample_rate_hz;
Yves Gerey665174f2018-06-19 15:03:05 +0200119 frame->samples_per_channel_ =
120 AudioProcessing::kChunkSizeMs * sample_rate_hz / 1000;
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700121}
122
Peter Kasting69558702016-01-12 16:26:35 -0800123AudioProcessing::ChannelLayout LayoutFromChannels(size_t num_channels) {
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700124 switch (num_channels) {
125 case 1:
126 return AudioProcessing::kMono;
127 case 2:
128 return AudioProcessing::kStereo;
129 default:
aluebsb0ad43b2015-11-20 00:11:53 -0800130 RTC_CHECK(false);
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700131 return AudioProcessing::kMono;
132 }
133}
134
Andrew MacDonaldcb05b722015-05-07 22:17:51 -0700135} // namespace webrtc