blob: b82378b8ec436578a072dcad1b333faaeeed0af1 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
leozwang@webrtc.org91b359e2012-02-28 17:26:14 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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#include <stdio.h>
12#include <string.h>
13
14#include <math.h>
15
niklase@google.com470e71d2011-07-07 08:21:25 +000016#include "common_types.h"
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000017#include "SpatialAudio.h"
18#include "trace.h"
kjellander@webrtc.org5490c712011-12-21 13:34:18 +000019#include "utility.h"
pbos@webrtc.org2ab209e2013-08-09 08:49:48 +000020#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000022namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000023
24#define NUM_PANN_COEFFS 10
25
andrew@webrtc.org89df0922013-09-12 01:27:43 +000026SpatialAudio::SpatialAudio(int testMode)
27 : _acmLeft(AudioCodingModule::Create(1)),
28 _acmRight(AudioCodingModule::Create(2)),
29 _acmReceiver(AudioCodingModule::Create(3)),
30 _testMode(testMode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000031}
32
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000033SpatialAudio::~SpatialAudio() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000034 delete _channel;
35 _inFile.Close();
36 _outFile.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +000037}
38
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000039int16_t SpatialAudio::Setup() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000040 _channel = new Channel;
niklase@google.com470e71d2011-07-07 08:21:25 +000041
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000042 // Register callback for the sender side.
43 CHECK_ERROR(_acmLeft->RegisterTransportCallback(_channel));
44 CHECK_ERROR(_acmRight->RegisterTransportCallback(_channel));
45 // Register the receiver ACM in channel
andrew@webrtc.org89df0922013-09-12 01:27:43 +000046 _channel->RegisterReceiverACM(_acmReceiver.get());
niklase@google.com470e71d2011-07-07 08:21:25 +000047
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000048 uint16_t sampFreqHz = 32000;
niklase@google.com470e71d2011-07-07 08:21:25 +000049
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000050 const std::string file_name = webrtc::test::ResourcePath(
51 "audio_coding/testfile32kHz", "pcm");
52 _inFile.Open(file_name, sampFreqHz, "rb", false);
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +000053
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000054 std::string output_file = webrtc::test::OutputPath()
55 + "out_spatial_autotest.pcm";
56 if (_testMode == 1) {
57 output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
58 printf("\n");
59 printf("Enter the output file [%s]: ", output_file.c_str());
60 PCMFile::ChooseFile(&output_file, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
61 } else {
62 output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
63 }
64 _outFile.Open(output_file, sampFreqHz, "wb", false);
65 _outFile.SaveStereo(true);
66
67 // Register all available codes as receiving codecs.
68 CodecInst codecInst;
69 int status;
70 uint8_t num_encoders = _acmReceiver->NumberOfCodecs();
71 // Register all available codes as receiving codecs once more.
72 for (uint8_t n = 0; n < num_encoders; n++) {
73 status = _acmReceiver->Codec(n, &codecInst);
74 if (status < 0) {
75 printf("Error in Codec(), no matching codec found");
niklase@google.com470e71d2011-07-07 08:21:25 +000076 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000077 status = _acmReceiver->RegisterReceiveCodec(codecInst);
78 if (status < 0) {
79 printf("Error in RegisterReceiveCodec() for payload type %d",
80 codecInst.pltype);
niklase@google.com470e71d2011-07-07 08:21:25 +000081 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000082 }
niklase@google.com470e71d2011-07-07 08:21:25 +000083
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000084 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000085}
86
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000087void SpatialAudio::Perform() {
88 if (_testMode == 0) {
89 printf("Running SpatialAudio Test");
90 WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
91 "---------- SpatialAudio ----------");
92 }
niklase@google.com470e71d2011-07-07 08:21:25 +000093
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000094 Setup();
niklase@google.com470e71d2011-07-07 08:21:25 +000095
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000096 CodecInst codecInst;
97 _acmLeft->Codec((uint8_t) 1, &codecInst);
98 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
99 EncodeDecode();
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000101 int16_t pannCntr = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000103 double leftPanning[NUM_PANN_COEFFS] = { 1.00, 0.95, 0.90, 0.85, 0.80, 0.75,
104 0.70, 0.60, 0.55, 0.50 };
105 double rightPanning[NUM_PANN_COEFFS] = { 0.50, 0.55, 0.60, 0.70, 0.75, 0.80,
106 0.85, 0.90, 0.95, 1.00 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000108 while ((pannCntr + 1) < NUM_PANN_COEFFS) {
109 _acmLeft->Codec((uint8_t) 0, &codecInst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 codecInst.pacsize = 480;
111 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
112 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000113
114 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
115 pannCntr++;
116
117 // Change codec
118 _acmLeft->Codec((uint8_t) 3, &codecInst);
119 codecInst.pacsize = 320;
120 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
121 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
122
123 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
124 pannCntr++;
125 if (_testMode == 0) {
126 printf(".");
niklase@google.com470e71d2011-07-07 08:21:25 +0000127 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000128 }
129
130 _acmLeft->Codec((uint8_t) 4, &codecInst);
131 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
132 EncodeDecode();
133
134 _acmLeft->Codec((uint8_t) 0, &codecInst);
135 codecInst.pacsize = 480;
136 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
137 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
138 pannCntr = NUM_PANN_COEFFS - 1;
139 while (pannCntr >= 0) {
140 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
141 pannCntr--;
142 if (_testMode == 0) {
143 printf(".");
niklase@google.com470e71d2011-07-07 08:21:25 +0000144 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000145 }
146 if (_testMode == 0) {
147 printf("Done!\n");
148 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000149}
150
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000151void SpatialAudio::EncodeDecode(const double leftPanning,
152 const double rightPanning) {
153 AudioFrame audioFrame;
154 int32_t outFileSampFreq = _outFile.SamplingFrequency();
niklase@google.com470e71d2011-07-07 08:21:25 +0000155
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000156 const double rightToLeftRatio = rightPanning / leftPanning;
niklase@google.com470e71d2011-07-07 08:21:25 +0000157
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000158 _channel->SetIsStereo(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000160 while (!_inFile.EndOfFile()) {
161 _inFile.Read10MsData(audioFrame);
162 for (int n = 0; n < audioFrame.samples_per_channel_; n++) {
163 audioFrame.data_[n] = (int16_t) floor(
164 audioFrame.data_[n] * leftPanning + 0.5);
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000166 CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
167
168 for (int n = 0; n < audioFrame.samples_per_channel_; n++) {
169 audioFrame.data_[n] = (int16_t) floor(
170 audioFrame.data_[n] * rightToLeftRatio + 0.5);
171 }
172 CHECK_ERROR(_acmRight->Add10MsData(audioFrame));
173
174 CHECK_ERROR(_acmLeft->Process());
175 CHECK_ERROR(_acmRight->Process());
176
177 CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
178 _outFile.Write10MsData(audioFrame);
179 }
180 _inFile.Rewind();
niklase@google.com470e71d2011-07-07 08:21:25 +0000181}
182
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000183void SpatialAudio::EncodeDecode() {
184 AudioFrame audioFrame;
185 int32_t outFileSampFreq = _outFile.SamplingFrequency();
niklase@google.com470e71d2011-07-07 08:21:25 +0000186
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000187 _channel->SetIsStereo(false);
niklase@google.com470e71d2011-07-07 08:21:25 +0000188
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000189 while (!_inFile.EndOfFile()) {
190 _inFile.Read10MsData(audioFrame);
191 CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
niklase@google.com470e71d2011-07-07 08:21:25 +0000192
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000193 CHECK_ERROR(_acmLeft->Process());
niklase@google.com470e71d2011-07-07 08:21:25 +0000194
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000195 CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
196 _outFile.Write10MsData(audioFrame);
197 }
198 _inFile.Rewind();
niklase@google.com470e71d2011-07-07 08:21:25 +0000199}
200
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000201} // namespace webrtc