TestAudioMixer.cpp (6078B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "AudioMixer.h" 8 #include "gtest/gtest.h" 9 10 using mozilla::AudioDataValue; 11 using mozilla::AudioSampleFormat; 12 13 namespace audio_mixer { 14 15 struct MixerConsumer : public mozilla::MixerCallbackReceiver { 16 /* In this test, the different audio stream and channels are always created to 17 * cancel each other. */ 18 void MixerCallback(mozilla::AudioChunk* aMixedBuffer, uint32_t aSampleRate) { 19 bool silent = true; 20 ASSERT_EQ(aMixedBuffer->mBufferFormat, mozilla::AUDIO_FORMAT_FLOAT32); 21 for (uint32_t c = 0; c < aMixedBuffer->ChannelCount(); c++) { 22 const float* channelData = aMixedBuffer->ChannelData<AudioDataValue>()[c]; 23 for (uint32_t i = 0; i < aMixedBuffer->mDuration; i++) { 24 if (channelData[i] != 0.0) { 25 fprintf(stderr, "Sample at %d in channel %c is not silent: %f\n", i, 26 c, channelData[i]); 27 silent = false; 28 } 29 } 30 } 31 ASSERT_TRUE(silent); 32 } 33 }; 34 35 /* Helper function to give us the maximum and minimum value that don't clip, 36 * for a given sample format (integer or floating-point). */ 37 template <typename T> 38 T GetLowValue(); 39 40 template <typename T> 41 T GetHighValue(); 42 43 template <> 44 float GetLowValue<float>() { 45 return -1.0; 46 } 47 48 template <> 49 short GetLowValue<short>() { 50 return -INT16_MAX; 51 } 52 53 template <> 54 float GetHighValue<float>() { 55 return 1.0; 56 } 57 58 template <> 59 short GetHighValue<short>() { 60 return INT16_MAX; 61 } 62 63 void FillBuffer(AudioDataValue* aBuffer, uint32_t aLength, 64 AudioDataValue aValue) { 65 AudioDataValue* end = aBuffer + aLength; 66 while (aBuffer != end) { 67 *aBuffer++ = aValue; 68 } 69 } 70 71 TEST(AudioMixer, Test) 72 { 73 const uint32_t CHANNEL_LENGTH = 256; 74 const uint32_t AUDIO_RATE = 44100; 75 MixerConsumer consumer; 76 AudioDataValue a[CHANNEL_LENGTH * 2]; 77 AudioDataValue b[CHANNEL_LENGTH * 2]; 78 FillBuffer(a, CHANNEL_LENGTH, GetLowValue<AudioDataValue>()); 79 FillBuffer(a + CHANNEL_LENGTH, CHANNEL_LENGTH, 80 GetHighValue<AudioDataValue>()); 81 FillBuffer(b, CHANNEL_LENGTH, GetHighValue<AudioDataValue>()); 82 FillBuffer(b + CHANNEL_LENGTH, CHANNEL_LENGTH, GetLowValue<AudioDataValue>()); 83 84 { 85 int iterations = 2; 86 mozilla::AudioMixer mixer; 87 88 fprintf(stderr, "Test AudioMixer constant buffer length.\n"); 89 90 while (iterations--) { 91 mixer.StartMixing(); 92 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 93 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 94 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 95 } 96 } 97 98 { 99 mozilla::AudioMixer mixer; 100 101 fprintf(stderr, "Test AudioMixer variable buffer length.\n"); 102 103 FillBuffer(a, CHANNEL_LENGTH / 2, GetLowValue<AudioDataValue>()); 104 FillBuffer(a + CHANNEL_LENGTH / 2, CHANNEL_LENGTH / 2, 105 GetLowValue<AudioDataValue>()); 106 FillBuffer(b, CHANNEL_LENGTH / 2, GetHighValue<AudioDataValue>()); 107 FillBuffer(b + CHANNEL_LENGTH / 2, CHANNEL_LENGTH / 2, 108 GetHighValue<AudioDataValue>()); 109 mixer.StartMixing(); 110 mixer.Mix(a, 2, CHANNEL_LENGTH / 2, AUDIO_RATE); 111 mixer.Mix(b, 2, CHANNEL_LENGTH / 2, AUDIO_RATE); 112 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 113 FillBuffer(a, CHANNEL_LENGTH, GetLowValue<AudioDataValue>()); 114 FillBuffer(a + CHANNEL_LENGTH, CHANNEL_LENGTH, 115 GetHighValue<AudioDataValue>()); 116 FillBuffer(b, CHANNEL_LENGTH, GetHighValue<AudioDataValue>()); 117 FillBuffer(b + CHANNEL_LENGTH, CHANNEL_LENGTH, 118 GetLowValue<AudioDataValue>()); 119 mixer.StartMixing(); 120 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 121 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 122 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 123 FillBuffer(a, CHANNEL_LENGTH / 2, GetLowValue<AudioDataValue>()); 124 FillBuffer(a + CHANNEL_LENGTH / 2, CHANNEL_LENGTH / 2, 125 GetLowValue<AudioDataValue>()); 126 FillBuffer(b, CHANNEL_LENGTH / 2, GetHighValue<AudioDataValue>()); 127 FillBuffer(b + CHANNEL_LENGTH / 2, CHANNEL_LENGTH / 2, 128 GetHighValue<AudioDataValue>()); 129 mixer.StartMixing(); 130 mixer.Mix(a, 2, CHANNEL_LENGTH / 2, AUDIO_RATE); 131 mixer.Mix(b, 2, CHANNEL_LENGTH / 2, AUDIO_RATE); 132 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 133 } 134 135 FillBuffer(a, CHANNEL_LENGTH, GetLowValue<AudioDataValue>()); 136 FillBuffer(b, CHANNEL_LENGTH, GetHighValue<AudioDataValue>()); 137 138 { 139 mozilla::AudioMixer mixer; 140 141 fprintf(stderr, "Test AudioMixer variable channel count.\n"); 142 143 mixer.StartMixing(); 144 mixer.Mix(a, 1, CHANNEL_LENGTH, AUDIO_RATE); 145 mixer.Mix(b, 1, CHANNEL_LENGTH, AUDIO_RATE); 146 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 147 mixer.StartMixing(); 148 mixer.Mix(a, 1, CHANNEL_LENGTH, AUDIO_RATE); 149 mixer.Mix(b, 1, CHANNEL_LENGTH, AUDIO_RATE); 150 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 151 mixer.StartMixing(); 152 mixer.Mix(a, 1, CHANNEL_LENGTH, AUDIO_RATE); 153 mixer.Mix(b, 1, CHANNEL_LENGTH, AUDIO_RATE); 154 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 155 } 156 157 { 158 mozilla::AudioMixer mixer; 159 fprintf(stderr, "Test AudioMixer variable stream count.\n"); 160 161 mixer.StartMixing(); 162 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 163 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 164 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 165 mixer.StartMixing(); 166 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 167 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 168 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 169 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 170 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 171 mixer.StartMixing(); 172 mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE); 173 mixer.Mix(b, 2, CHANNEL_LENGTH, AUDIO_RATE); 174 consumer.MixerCallback(mixer.MixedChunk(), AUDIO_RATE); 175 } 176 } 177 178 } // namespace audio_mixer