niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
leozwang@webrtc.org | 91b359e | 2012-02-28 17:26:14 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 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 | #include <stdio.h> |
| 12 | #include <string.h> |
| 13 | |
| 14 | #include <math.h> |
| 15 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 16 | #include "common_types.h" |
kjellander@webrtc.org | 5490c71 | 2011-12-21 13:34:18 +0000 | [diff] [blame] | 17 | #include "SpatialAudio.h" |
| 18 | #include "trace.h" |
kjellander@webrtc.org | 5490c71 | 2011-12-21 13:34:18 +0000 | [diff] [blame] | 19 | #include "utility.h" |
pbos@webrtc.org | 2ab209e | 2013-08-09 08:49:48 +0000 | [diff] [blame] | 20 | #include "webrtc/test/testsupport/fileutils.h" |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 21 | |
tina.legrand@webrtc.org | 554ae1a | 2011-12-16 10:09:04 +0000 | [diff] [blame] | 22 | namespace webrtc { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 23 | |
| 24 | #define NUM_PANN_COEFFS 10 |
| 25 | |
andrew@webrtc.org | 89df092 | 2013-09-12 01:27:43 +0000 | [diff] [blame] | 26 | SpatialAudio::SpatialAudio(int testMode) |
| 27 | : _acmLeft(AudioCodingModule::Create(1)), |
| 28 | _acmRight(AudioCodingModule::Create(2)), |
| 29 | _acmReceiver(AudioCodingModule::Create(3)), |
| 30 | _testMode(testMode) { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 31 | } |
| 32 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 33 | SpatialAudio::~SpatialAudio() { |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 34 | delete _channel; |
| 35 | _inFile.Close(); |
| 36 | _outFile.Close(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 37 | } |
| 38 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 39 | int16_t SpatialAudio::Setup() { |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 40 | _channel = new Channel; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 41 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 42 | // 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.org | 89df092 | 2013-09-12 01:27:43 +0000 | [diff] [blame] | 46 | _channel->RegisterReceiverACM(_acmReceiver.get()); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 47 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 48 | uint16_t sampFreqHz = 32000; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 49 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 50 | const std::string file_name = webrtc::test::ResourcePath( |
| 51 | "audio_coding/testfile32kHz", "pcm"); |
| 52 | _inFile.Open(file_name, sampFreqHz, "rb", false); |
tina.legrand@webrtc.org | ba46804 | 2012-08-17 10:38:28 +0000 | [diff] [blame] | 53 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 54 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 76 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 77 | status = _acmReceiver->RegisterReceiveCodec(codecInst); |
| 78 | if (status < 0) { |
| 79 | printf("Error in RegisterReceiveCodec() for payload type %d", |
| 80 | codecInst.pltype); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 81 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 82 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 83 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 84 | return 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 85 | } |
| 86 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 87 | void SpatialAudio::Perform() { |
| 88 | if (_testMode == 0) { |
| 89 | printf("Running SpatialAudio Test"); |
| 90 | WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, |
| 91 | "---------- SpatialAudio ----------"); |
| 92 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 93 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 94 | Setup(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 95 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 96 | CodecInst codecInst; |
| 97 | _acmLeft->Codec((uint8_t) 1, &codecInst); |
| 98 | CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); |
| 99 | EncodeDecode(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 100 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 101 | int16_t pannCntr = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 102 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 103 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 107 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 108 | while ((pannCntr + 1) < NUM_PANN_COEFFS) { |
| 109 | _acmLeft->Codec((uint8_t) 0, &codecInst); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 110 | codecInst.pacsize = 480; |
| 111 | CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); |
| 112 | CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst)); |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 113 | |
| 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 127 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 128 | } |
| 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 144 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 145 | } |
| 146 | if (_testMode == 0) { |
| 147 | printf("Done!\n"); |
| 148 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 149 | } |
| 150 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 151 | void SpatialAudio::EncodeDecode(const double leftPanning, |
| 152 | const double rightPanning) { |
| 153 | AudioFrame audioFrame; |
| 154 | int32_t outFileSampFreq = _outFile.SamplingFrequency(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 155 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 156 | const double rightToLeftRatio = rightPanning / leftPanning; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 157 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 158 | _channel->SetIsStereo(true); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 159 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 160 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 165 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 166 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 181 | } |
| 182 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 183 | void SpatialAudio::EncodeDecode() { |
| 184 | AudioFrame audioFrame; |
| 185 | int32_t outFileSampFreq = _outFile.SamplingFrequency(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 186 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 187 | _channel->SetIsStereo(false); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 188 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 189 | while (!_inFile.EndOfFile()) { |
| 190 | _inFile.Read10MsData(audioFrame); |
| 191 | CHECK_ERROR(_acmLeft->Add10MsData(audioFrame)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 192 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 193 | CHECK_ERROR(_acmLeft->Process()); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 194 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 195 | CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame)); |
| 196 | _outFile.Write10MsData(audioFrame); |
| 197 | } |
| 198 | _inFile.Rewind(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 199 | } |
| 200 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame] | 201 | } // namespace webrtc |