blob: c55b53ef99a0e8f4f0fc0df5d8b69d83152f091d [file] [log] [blame]
andrew@webrtc.org60730cf2014-01-07 17:45:09 +00001/*
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
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000011#include "webrtc/audio_processing/debug.pb.h"
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000012#include "webrtc/modules/audio_processing/include/audio_processing.h"
13#include "webrtc/modules/interface/module_common_types.h"
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000014#include "webrtc/system_wrappers/interface/scoped_ptr.h"
15
16namespace webrtc {
17
18static const AudioProcessing::Error kNoErr = AudioProcessing::kNoError;
19#define EXPECT_NOERR(expr) EXPECT_EQ(kNoErr, (expr))
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000020
21static const int kChunkSizeMs = 10;
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000022
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000023// Helper to encapsulate a contiguous data buffer with access to a pointer
24// array of the deinterleaved channels.
25template <typename T>
26class ChannelBuffer {
27 public:
28 ChannelBuffer(int samples_per_channel, int num_channels)
29 : data_(new T[samples_per_channel * num_channels]),
30 channels_(new T*[num_channels]),
31 samples_per_channel_(samples_per_channel) {
32 memset(data_.get(), 0, sizeof(T) * samples_per_channel * num_channels);
33 for (int i = 0; i < num_channels; ++i)
34 channels_[i] = &data_[i * samples_per_channel];
35 }
36 ~ChannelBuffer() {}
37
38 void CopyFrom(const void* channel_ptr, int index) {
39 memcpy(channels_[index], channel_ptr, samples_per_channel_ * sizeof(T));
40 }
41
42 T* data() { return data_.get(); }
43 T* channel(int index) { return channels_[index]; }
44 T** channels() { return channels_.get(); }
45
46 private:
47 scoped_ptr<T[]> data_;
48 scoped_ptr<T*[]> channels_;
49 int samples_per_channel_;
50};
51
52// Exits on failure; do not use in unit tests.
53static inline FILE* OpenFile(const std::string& filename, const char* mode) {
54 FILE* file = fopen(filename.c_str(), mode);
55 if (!file) {
56 printf("Unable to open file %s\n", filename.c_str());
57 exit(1);
58 }
59 return file;
60}
61
62static inline void SetFrameSampleRate(AudioFrame* frame,
63 int sample_rate_hz) {
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000064 frame->sample_rate_hz_ = sample_rate_hz;
65 frame->samples_per_channel_ = kChunkSizeMs * sample_rate_hz / 1000;
66}
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000067
68template <typename T>
69void SetContainerFormat(int sample_rate_hz,
70 int num_channels,
71 AudioFrame* frame,
72 scoped_ptr<ChannelBuffer<T> >* cb) {
73 SetFrameSampleRate(frame, sample_rate_hz);
74 frame->num_channels_ = num_channels;
75 cb->reset(new ChannelBuffer<T>(frame->samples_per_channel_, num_channels));
76}
77
78static inline AudioProcessing::ChannelLayout LayoutFromChannels(
79 int num_channels) {
80 switch (num_channels) {
81 case 1:
82 return AudioProcessing::kMono;
83 case 2:
84 return AudioProcessing::kStereo;
85 default:
86 assert(false);
87 return AudioProcessing::kMono;
88 }
89}
90
91// Allocates new memory in the scoped_ptr to fit the raw message and returns the
92// number of bytes read.
93static inline size_t ReadMessageBytesFromFile(FILE* file,
94 scoped_ptr<uint8_t[]>* bytes) {
95 // The "wire format" for the size is little-endian. Assume we're running on
96 // a little-endian machine.
97 int32_t size = 0;
98 if (fread(&size, sizeof(size), 1, file) != 1)
99 return 0;
100 if (size <= 0)
101 return 0;
102
103 bytes->reset(new uint8_t[size]);
104 return fread(bytes->get(), sizeof((*bytes)[0]), size, file);
105}
106
107// Returns true on success, false on error or end-of-file.
108static inline bool ReadMessageFromFile(FILE* file,
109 ::google::protobuf::MessageLite* msg) {
110 scoped_ptr<uint8_t[]> bytes;
111 size_t size = ReadMessageBytesFromFile(file, &bytes);
112 if (!size)
113 return false;
114
115 msg->Clear();
116 return msg->ParseFromArray(bytes.get(), size);
117}
118
119} // namespace webrtc