Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(650)

Side by Side Diff: Source/core/platform/audio/HRTFPanner.cpp

Issue 14636011: Support multiple HRTFDatabases for different sample-rates (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 29 matching lines...) Expand all
40 40
41 namespace WebCore { 41 namespace WebCore {
42 42
43 // The value of 2 milliseconds is larger than the largest delay which exists in any HRTFKernel from the default HRTFDatabase (0.0136 seconds). 43 // The value of 2 milliseconds is larger than the largest delay which exists in any HRTFKernel from the default HRTFDatabase (0.0136 seconds).
44 // We ASSERT the delay values used in process() with this value. 44 // We ASSERT the delay values used in process() with this value.
45 const double MaxDelayTimeSeconds = 0.002; 45 const double MaxDelayTimeSeconds = 0.002;
46 46
47 const int UninitializedAzimuth = -1; 47 const int UninitializedAzimuth = -1;
48 const unsigned RenderingQuantum = 128; 48 const unsigned RenderingQuantum = 128;
49 49
50 HRTFPanner::HRTFPanner(float sampleRate) 50 HRTFPanner::HRTFPanner(float sampleRate, HRTFDatabase* database)
51 : Panner(PanningModelHRTF) 51 : Panner(PanningModelHRTF)
52 , m_database(database)
52 , m_sampleRate(sampleRate) 53 , m_sampleRate(sampleRate)
53 , m_crossfadeSelection(CrossfadeSelection1) 54 , m_crossfadeSelection(CrossfadeSelection1)
54 , m_azimuthIndex1(UninitializedAzimuth) 55 , m_azimuthIndex1(UninitializedAzimuth)
55 , m_elevation1(0) 56 , m_elevation1(0)
56 , m_azimuthIndex2(UninitializedAzimuth) 57 , m_azimuthIndex2(UninitializedAzimuth)
57 , m_elevation2(0) 58 , m_elevation2(0)
58 , m_crossfadeX(0) 59 , m_crossfadeX(0)
59 , m_crossfadeIncr(0) 60 , m_crossfadeIncr(0)
60 , m_convolverL1(fftSizeForSampleRate(sampleRate)) 61 , m_convolverL1(fftSizeForSampleRate(sampleRate))
61 , m_convolverR1(fftSizeForSampleRate(sampleRate)) 62 , m_convolverR1(fftSizeForSampleRate(sampleRate))
62 , m_convolverL2(fftSizeForSampleRate(sampleRate)) 63 , m_convolverL2(fftSizeForSampleRate(sampleRate))
63 , m_convolverR2(fftSizeForSampleRate(sampleRate)) 64 , m_convolverR2(fftSizeForSampleRate(sampleRate))
64 , m_delayLineL(MaxDelayTimeSeconds, sampleRate) 65 , m_delayLineL(MaxDelayTimeSeconds, sampleRate)
65 , m_delayLineR(MaxDelayTimeSeconds, sampleRate) 66 , m_delayLineR(MaxDelayTimeSeconds, sampleRate)
66 , m_tempL1(RenderingQuantum) 67 , m_tempL1(RenderingQuantum)
67 , m_tempR1(RenderingQuantum) 68 , m_tempR1(RenderingQuantum)
68 , m_tempL2(RenderingQuantum) 69 , m_tempL2(RenderingQuantum)
69 , m_tempR2(RenderingQuantum) 70 , m_tempR2(RenderingQuantum)
70 { 71 {
72 ASSERT(database);
71 } 73 }
72 74
73 HRTFPanner::~HRTFPanner() 75 HRTFPanner::~HRTFPanner()
74 { 76 {
75 } 77 }
76 78
77 size_t HRTFPanner::fftSizeForSampleRate(float sampleRate) 79 size_t HRTFPanner::fftSizeForSampleRate(float sampleRate)
78 { 80 {
79 // The HRTF impulse responses (loaded as audio resources) are 512 sample-fra mes @44.1KHz. 81 // The HRTF impulse responses (loaded as audio resources) are 512 sample-fra mes @44.1KHz.
80 // Currently, we truncate the impulse responses to half this size, but an FF T-size of twice impulse response size is needed (for convolution). 82 // Currently, we truncate the impulse responses to half this size, but an FF T-size of twice impulse response size is needed (for convolution).
(...skipping 12 matching lines...) Expand all
93 m_delayLineR.reset(); 95 m_delayLineR.reset();
94 } 96 }
95 97
96 int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azi muthBlend) 98 int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azi muthBlend)
97 { 99 {
98 // Convert the azimuth angle from the range -180 -> +180 into the range 0 -> 360. 100 // Convert the azimuth angle from the range -180 -> +180 into the range 0 -> 360.
99 // The azimuth index may then be calculated from this positive value. 101 // The azimuth index may then be calculated from this positive value.
100 if (azimuth < 0) 102 if (azimuth < 0)
101 azimuth += 360.0; 103 azimuth += 360.0;
102 104
103 HRTFDatabase* database = HRTFDatabaseLoader::defaultHRTFDatabase(); 105 int numberOfAzimuths = m_database->numberOfAzimuths();
104 ASSERT(database);
105
106 int numberOfAzimuths = database->numberOfAzimuths();
107 const double angleBetweenAzimuths = 360.0 / numberOfAzimuths; 106 const double angleBetweenAzimuths = 360.0 / numberOfAzimuths;
108 107
109 // Calculate the azimuth index and the blend (0 -> 1) for interpolation. 108 // Calculate the azimuth index and the blend (0 -> 1) for interpolation.
110 double desiredAzimuthIndexFloat = azimuth / angleBetweenAzimuths; 109 double desiredAzimuthIndexFloat = azimuth / angleBetweenAzimuths;
111 int desiredAzimuthIndex = static_cast<int>(desiredAzimuthIndexFloat); 110 int desiredAzimuthIndex = static_cast<int>(desiredAzimuthIndexFloat);
112 azimuthBlend = desiredAzimuthIndexFloat - static_cast<double>(desiredAzimuth Index); 111 azimuthBlend = desiredAzimuthIndexFloat - static_cast<double>(desiredAzimuth Index);
113 112
114 // We don't immediately start using this azimuth index, but instead approach this index from the last index we rendered at. 113 // We don't immediately start using this azimuth index, but instead approach this index from the last index we rendered at.
115 // This minimizes the clicks and graininess for moving sources which occur o therwise. 114 // This minimizes the clicks and graininess for moving sources which occur o therwise.
116 desiredAzimuthIndex = max(0, desiredAzimuthIndex); 115 desiredAzimuthIndex = max(0, desiredAzimuthIndex);
(...skipping 10 matching lines...) Expand all
127 126
128 bool isOutputGood = outputBus && outputBus->numberOfChannels() == 2 && frame sToProcess <= outputBus->length(); 127 bool isOutputGood = outputBus && outputBus->numberOfChannels() == 2 && frame sToProcess <= outputBus->length();
129 ASSERT(isOutputGood); 128 ASSERT(isOutputGood);
130 129
131 if (!isInputGood || !isOutputGood) { 130 if (!isInputGood || !isOutputGood) {
132 if (outputBus) 131 if (outputBus)
133 outputBus->zero(); 132 outputBus->zero();
134 return; 133 return;
135 } 134 }
136 135
137 // This code only runs as long as the context is alive and after database ha s been loaded.
138 HRTFDatabase* database = HRTFDatabaseLoader::defaultHRTFDatabase();
139 ASSERT(database);
140 if (!database) {
141 outputBus->zero();
142 return;
143 }
144
145 // IRCAM HRTF azimuths values from the loaded database is reversed from the panner's notion of azimuth. 136 // IRCAM HRTF azimuths values from the loaded database is reversed from the panner's notion of azimuth.
146 double azimuth = -desiredAzimuth; 137 double azimuth = -desiredAzimuth;
147 138
148 bool isAzimuthGood = azimuth >= -180.0 && azimuth <= 180.0; 139 bool isAzimuthGood = azimuth >= -180.0 && azimuth <= 180.0;
149 ASSERT(isAzimuthGood); 140 ASSERT(isAzimuthGood);
150 if (!isAzimuthGood) { 141 if (!isAzimuthGood) {
151 outputBus->zero(); 142 outputBus->zero();
152 return; 143 return;
153 } 144 }
154 145
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 for (unsigned segment = 0; segment < numberOfSegments; ++segment) { 200 for (unsigned segment = 0; segment < numberOfSegments; ++segment) {
210 // Get the HRTFKernels and interpolated delays. 201 // Get the HRTFKernels and interpolated delays.
211 HRTFKernel* kernelL1; 202 HRTFKernel* kernelL1;
212 HRTFKernel* kernelR1; 203 HRTFKernel* kernelR1;
213 HRTFKernel* kernelL2; 204 HRTFKernel* kernelL2;
214 HRTFKernel* kernelR2; 205 HRTFKernel* kernelR2;
215 double frameDelayL1; 206 double frameDelayL1;
216 double frameDelayR1; 207 double frameDelayR1;
217 double frameDelayL2; 208 double frameDelayL2;
218 double frameDelayR2; 209 double frameDelayR2;
219 database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex1, m_elevation1, kernelL1, kernelR1, frameDelayL1, frameDelayR1); 210 m_database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex1 , m_elevation1, kernelL1, kernelR1, frameDelayL1, frameDelayR1);
220 database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex2, m_elevation2, kernelL2, kernelR2, frameDelayL2, frameDelayR2); 211 m_database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex2 , m_elevation2, kernelL2, kernelR2, frameDelayL2, frameDelayR2);
221 212
222 bool areKernelsGood = kernelL1 && kernelR1 && kernelL2 && kernelR2; 213 bool areKernelsGood = kernelL1 && kernelR1 && kernelL2 && kernelR2;
223 ASSERT(areKernelsGood); 214 ASSERT(areKernelsGood);
224 if (!areKernelsGood) { 215 if (!areKernelsGood) {
225 outputBus->zero(); 216 outputBus->zero();
226 return; 217 return;
227 } 218 }
228 219
229 ASSERT(frameDelayL1 / sampleRate() < MaxDelayTimeSeconds && frameDelayR1 / sampleRate() < MaxDelayTimeSeconds); 220 ASSERT(frameDelayL1 / sampleRate() < MaxDelayTimeSeconds && frameDelayR1 / sampleRate() < MaxDelayTimeSeconds);
230 ASSERT(frameDelayL2 / sampleRate() < MaxDelayTimeSeconds && frameDelayR2 / sampleRate() < MaxDelayTimeSeconds); 221 ASSERT(frameDelayL2 / sampleRate() < MaxDelayTimeSeconds && frameDelayR2 / sampleRate() < MaxDelayTimeSeconds);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 double HRTFPanner::latencyTime() const 296 double HRTFPanner::latencyTime() const
306 { 297 {
307 // The latency of a FFTConvolver is also fftSize() / 2, and is in addition t o its tailTime of the 298 // The latency of a FFTConvolver is also fftSize() / 2, and is in addition t o its tailTime of the
308 // same value. 299 // same value.
309 return (fftSize() / 2) / static_cast<double>(sampleRate()); 300 return (fftSize() / 2) / static_cast<double>(sampleRate());
310 } 301 }
311 302
312 } // namespace WebCore 303 } // namespace WebCore
313 304
314 #endif // ENABLE(WEB_AUDIO) 305 #endif // ENABLE(WEB_AUDIO)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698