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" |
| 19 | #include "testsupport/fileutils.h" |
| 20 | #include "utility.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 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 26 | SpatialAudio::SpatialAudio(int testMode) { |
| 27 | _testMode = testMode; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 28 | } |
| 29 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 30 | SpatialAudio::~SpatialAudio() { |
| 31 | AudioCodingModule::Destroy(_acmLeft); |
| 32 | AudioCodingModule::Destroy(_acmRight); |
| 33 | AudioCodingModule::Destroy(_acmReceiver); |
| 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() { |
| 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 45 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 46 | // 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 51 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 52 | uint16_t sampFreqHz = 32000; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 53 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 54 | const std::string file_name = webrtc::test::ResourcePath( |
| 55 | "audio_coding/testfile32kHz", "pcm"); |
| 56 | _inFile.Open(file_name, sampFreqHz, "rb", false); |
tina.legrand@webrtc.org | ba46804 | 2012-08-17 10:38:28 +0000 | [diff] [blame] | 57 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 58 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 80 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 81 | status = _acmReceiver->RegisterReceiveCodec(codecInst); |
| 82 | if (status < 0) { |
| 83 | printf("Error in RegisterReceiveCodec() for payload type %d", |
| 84 | codecInst.pltype); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 85 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 86 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 87 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 88 | return 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 89 | } |
| 90 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 91 | void SpatialAudio::Perform() { |
| 92 | if (_testMode == 0) { |
| 93 | printf("Running SpatialAudio Test"); |
| 94 | WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, |
| 95 | "---------- SpatialAudio ----------"); |
| 96 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 97 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 98 | Setup(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 99 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 100 | CodecInst codecInst; |
| 101 | _acmLeft->Codec((uint8_t) 1, &codecInst); |
| 102 | CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); |
| 103 | EncodeDecode(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 104 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 105 | int16_t pannCntr = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 106 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 107 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 111 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 112 | while ((pannCntr + 1) < NUM_PANN_COEFFS) { |
| 113 | _acmLeft->Codec((uint8_t) 0, &codecInst); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 114 | codecInst.pacsize = 480; |
| 115 | CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); |
| 116 | CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst)); |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 117 | |
| 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 131 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 132 | } |
| 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 148 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 149 | } |
| 150 | if (_testMode == 0) { |
| 151 | printf("Done!\n"); |
| 152 | } |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 153 | } |
| 154 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 155 | void SpatialAudio::EncodeDecode(const double leftPanning, |
| 156 | const double rightPanning) { |
| 157 | AudioFrame audioFrame; |
| 158 | int32_t outFileSampFreq = _outFile.SamplingFrequency(); |
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 | const double rightToLeftRatio = rightPanning / leftPanning; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 161 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 162 | _channel->SetIsStereo(true); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 163 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 164 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 169 | } |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 170 | 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.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 185 | } |
| 186 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 187 | void SpatialAudio::EncodeDecode() { |
| 188 | AudioFrame audioFrame; |
| 189 | int32_t outFileSampFreq = _outFile.SamplingFrequency(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 190 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 191 | _channel->SetIsStereo(false); |
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 | while (!_inFile.EndOfFile()) { |
| 194 | _inFile.Read10MsData(audioFrame); |
| 195 | CHECK_ERROR(_acmLeft->Add10MsData(audioFrame)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 196 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 197 | CHECK_ERROR(_acmLeft->Process()); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 198 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 199 | CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame)); |
| 200 | _outFile.Write10MsData(audioFrame); |
| 201 | } |
| 202 | _inFile.Rewind(); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 203 | } |
| 204 | |
tina.legrand@webrtc.org | d5726a1 | 2013-05-03 07:34:12 +0000 | [diff] [blame^] | 205 | } // namespace webrtc |