blob: e4a19cf98158e31e4ad2175ed871b77056b310e7 [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"
19#include "testsupport/fileutils.h"
20#include "utility.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
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000026SpatialAudio::SpatialAudio(int testMode) {
27 _testMode = testMode;
niklase@google.com470e71d2011-07-07 08:21:25 +000028}
29
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000030SpatialAudio::~SpatialAudio() {
31 AudioCodingModule::Destroy(_acmLeft);
32 AudioCodingModule::Destroy(_acmRight);
33 AudioCodingModule::Destroy(_acmReceiver);
34 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() {
40 // Create ACMs and the Channel;
41 _acmLeft = AudioCodingModule::Create(1);
42 _acmRight = AudioCodingModule::Create(2);
43 _acmReceiver = AudioCodingModule::Create(3);
44 _channel = new Channel;
niklase@google.com470e71d2011-07-07 08:21:25 +000045
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000046 // Register callback for the sender side.
47 CHECK_ERROR(_acmLeft->RegisterTransportCallback(_channel));
48 CHECK_ERROR(_acmRight->RegisterTransportCallback(_channel));
49 // Register the receiver ACM in channel
50 _channel->RegisterReceiverACM(_acmReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +000051
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000052 uint16_t sampFreqHz = 32000;
niklase@google.com470e71d2011-07-07 08:21:25 +000053
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000054 const std::string file_name = webrtc::test::ResourcePath(
55 "audio_coding/testfile32kHz", "pcm");
56 _inFile.Open(file_name, sampFreqHz, "rb", false);
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +000057
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000058 std::string output_file = webrtc::test::OutputPath()
59 + "out_spatial_autotest.pcm";
60 if (_testMode == 1) {
61 output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
62 printf("\n");
63 printf("Enter the output file [%s]: ", output_file.c_str());
64 PCMFile::ChooseFile(&output_file, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
65 } else {
66 output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
67 }
68 _outFile.Open(output_file, sampFreqHz, "wb", false);
69 _outFile.SaveStereo(true);
70
71 // Register all available codes as receiving codecs.
72 CodecInst codecInst;
73 int status;
74 uint8_t num_encoders = _acmReceiver->NumberOfCodecs();
75 // Register all available codes as receiving codecs once more.
76 for (uint8_t n = 0; n < num_encoders; n++) {
77 status = _acmReceiver->Codec(n, &codecInst);
78 if (status < 0) {
79 printf("Error in Codec(), no matching codec found");
niklase@google.com470e71d2011-07-07 08:21:25 +000080 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000081 status = _acmReceiver->RegisterReceiveCodec(codecInst);
82 if (status < 0) {
83 printf("Error in RegisterReceiveCodec() for payload type %d",
84 codecInst.pltype);
niklase@google.com470e71d2011-07-07 08:21:25 +000085 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000086 }
niklase@google.com470e71d2011-07-07 08:21:25 +000087
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000088 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000089}
90
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000091void SpatialAudio::Perform() {
92 if (_testMode == 0) {
93 printf("Running SpatialAudio Test");
94 WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
95 "---------- SpatialAudio ----------");
96 }
niklase@google.com470e71d2011-07-07 08:21:25 +000097
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000098 Setup();
niklase@google.com470e71d2011-07-07 08:21:25 +000099
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000100 CodecInst codecInst;
101 _acmLeft->Codec((uint8_t) 1, &codecInst);
102 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
103 EncodeDecode();
niklase@google.com470e71d2011-07-07 08:21:25 +0000104
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000105 int16_t pannCntr = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000106
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000107 double leftPanning[NUM_PANN_COEFFS] = { 1.00, 0.95, 0.90, 0.85, 0.80, 0.75,
108 0.70, 0.60, 0.55, 0.50 };
109 double rightPanning[NUM_PANN_COEFFS] = { 0.50, 0.55, 0.60, 0.70, 0.75, 0.80,
110 0.85, 0.90, 0.95, 1.00 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000112 while ((pannCntr + 1) < NUM_PANN_COEFFS) {
113 _acmLeft->Codec((uint8_t) 0, &codecInst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000114 codecInst.pacsize = 480;
115 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
116 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000117
118 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
119 pannCntr++;
120
121 // Change codec
122 _acmLeft->Codec((uint8_t) 3, &codecInst);
123 codecInst.pacsize = 320;
124 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
125 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
126
127 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
128 pannCntr++;
129 if (_testMode == 0) {
130 printf(".");
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000132 }
133
134 _acmLeft->Codec((uint8_t) 4, &codecInst);
135 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
136 EncodeDecode();
137
138 _acmLeft->Codec((uint8_t) 0, &codecInst);
139 codecInst.pacsize = 480;
140 CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
141 CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
142 pannCntr = NUM_PANN_COEFFS - 1;
143 while (pannCntr >= 0) {
144 EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
145 pannCntr--;
146 if (_testMode == 0) {
147 printf(".");
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000149 }
150 if (_testMode == 0) {
151 printf("Done!\n");
152 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000153}
154
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000155void SpatialAudio::EncodeDecode(const double leftPanning,
156 const double rightPanning) {
157 AudioFrame audioFrame;
158 int32_t outFileSampFreq = _outFile.SamplingFrequency();
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000160 const double rightToLeftRatio = rightPanning / leftPanning;
niklase@google.com470e71d2011-07-07 08:21:25 +0000161
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000162 _channel->SetIsStereo(true);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000164 while (!_inFile.EndOfFile()) {
165 _inFile.Read10MsData(audioFrame);
166 for (int n = 0; n < audioFrame.samples_per_channel_; n++) {
167 audioFrame.data_[n] = (int16_t) floor(
168 audioFrame.data_[n] * leftPanning + 0.5);
niklase@google.com470e71d2011-07-07 08:21:25 +0000169 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000170 CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
171
172 for (int n = 0; n < audioFrame.samples_per_channel_; n++) {
173 audioFrame.data_[n] = (int16_t) floor(
174 audioFrame.data_[n] * rightToLeftRatio + 0.5);
175 }
176 CHECK_ERROR(_acmRight->Add10MsData(audioFrame));
177
178 CHECK_ERROR(_acmLeft->Process());
179 CHECK_ERROR(_acmRight->Process());
180
181 CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
182 _outFile.Write10MsData(audioFrame);
183 }
184 _inFile.Rewind();
niklase@google.com470e71d2011-07-07 08:21:25 +0000185}
186
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000187void SpatialAudio::EncodeDecode() {
188 AudioFrame audioFrame;
189 int32_t outFileSampFreq = _outFile.SamplingFrequency();
niklase@google.com470e71d2011-07-07 08:21:25 +0000190
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000191 _channel->SetIsStereo(false);
niklase@google.com470e71d2011-07-07 08:21:25 +0000192
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000193 while (!_inFile.EndOfFile()) {
194 _inFile.Read10MsData(audioFrame);
195 CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000197 CHECK_ERROR(_acmLeft->Process());
niklase@google.com470e71d2011-07-07 08:21:25 +0000198
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000199 CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
200 _outFile.Write10MsData(audioFrame);
201 }
202 _inFile.Rewind();
niklase@google.com470e71d2011-07-07 08:21:25 +0000203}
204
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000205} // namespace webrtc