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