| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 } | 80 } |
| 81 | 81 |
| 82 PeriodicWave* PeriodicWave::createTriangle(float sampleRate) | 82 PeriodicWave* PeriodicWave::createTriangle(float sampleRate) |
| 83 { | 83 { |
| 84 PeriodicWave* periodicWave = new PeriodicWave(sampleRate); | 84 PeriodicWave* periodicWave = new PeriodicWave(sampleRate); |
| 85 periodicWave->generateBasicWaveform(OscillatorHandler::TRIANGLE); | 85 periodicWave->generateBasicWaveform(OscillatorHandler::TRIANGLE); |
| 86 return periodicWave; | 86 return periodicWave; |
| 87 } | 87 } |
| 88 | 88 |
| 89 PeriodicWave::PeriodicWave(float sampleRate) | 89 PeriodicWave::PeriodicWave(float sampleRate) |
| 90 : m_v8ExternalMemory(0) | 90 : m_sampleRate(sampleRate) |
| 91 , m_sampleRate(sampleRate) | |
| 92 , m_centsPerRange(CentsPerRange) | 91 , m_centsPerRange(CentsPerRange) |
| 93 { | 92 { |
| 94 float nyquist = 0.5 * m_sampleRate; | 93 float nyquist = 0.5 * m_sampleRate; |
| 95 m_lowestFundamentalFrequency = nyquist / maxNumberOfPartials(); | 94 m_lowestFundamentalFrequency = nyquist / maxNumberOfPartials(); |
| 96 m_rateScale = periodicWaveSize() / m_sampleRate; | 95 m_rateScale = periodicWaveSize() / m_sampleRate; |
| 97 // Compute the number of ranges needed to cover the entire frequency range,
assuming | 96 // Compute the number of ranges needed to cover the entire frequency range,
assuming |
| 98 // kNumberOfOctaveBands per octave. | 97 // kNumberOfOctaveBands per octave. |
| 99 m_numberOfRanges = 0.5 + kNumberOfOctaveBands * log2f(periodicWaveSize()); | 98 m_numberOfRanges = 0.5 + kNumberOfOctaveBands * log2f(periodicWaveSize()); |
| 100 } | 99 } |
| 101 | 100 |
| 102 PeriodicWave::~PeriodicWave() | 101 PeriodicWave::~PeriodicWave() |
| 103 { | 102 { |
| 104 adjustV8ExternalMemory(-static_cast<int64_t>(m_v8ExternalMemory)); | |
| 105 } | 103 } |
| 106 | 104 |
| 107 unsigned PeriodicWave::periodicWaveSize() const | 105 unsigned PeriodicWave::periodicWaveSize() const |
| 108 { | 106 { |
| 109 // Choose an appropriate wave size for the given sample rate. This allows u
s to use shorter | 107 // Choose an appropriate wave size for the given sample rate. This allows u
s to use shorter |
| 110 // FFTs when possible to limit the complexity. The breakpoints here are som
ewhat arbitrary, but | 108 // FFTs when possible to limit the complexity. The breakpoints here are som
ewhat arbitrary, but |
| 111 // we want sample rates around 44.1 kHz or so to have a size of 4096 to pres
erve backward | 109 // we want sample rates around 44.1 kHz or so to have a size of 4096 to pres
erve backward |
| 112 // compatibility. | 110 // compatibility. |
| 113 if (m_sampleRate <= 24000) { | 111 if (m_sampleRate <= 24000) { |
| 114 return 2048; | 112 return 2048; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 159 |
| 162 // A value from 0 -> 1 representing what fraction of the partials to keep. | 160 // A value from 0 -> 1 representing what fraction of the partials to keep. |
| 163 float cullingScale = pow(2, -centsToCull / 1200); | 161 float cullingScale = pow(2, -centsToCull / 1200); |
| 164 | 162 |
| 165 // The very top range will have all the partials culled. | 163 // The very top range will have all the partials culled. |
| 166 unsigned numberOfPartials = cullingScale * maxNumberOfPartials(); | 164 unsigned numberOfPartials = cullingScale * maxNumberOfPartials(); |
| 167 | 165 |
| 168 return numberOfPartials; | 166 return numberOfPartials; |
| 169 } | 167 } |
| 170 | 168 |
| 171 // Tell V8 about the memory we're using so it can properly schedule garbage coll
ects. | |
| 172 void PeriodicWave::adjustV8ExternalMemory(int delta) | |
| 173 { | |
| 174 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta); | |
| 175 m_v8ExternalMemory += delta; | |
| 176 } | |
| 177 | |
| 178 // Convert into time-domain wave buffers. | 169 // Convert into time-domain wave buffers. |
| 179 // One table is created for each range for non-aliasing playback at different pl
ayback rates. | 170 // One table is created for each range for non-aliasing playback at different pl
ayback rates. |
| 180 // Thus, higher ranges have more high-frequency partials culled out. | 171 // Thus, higher ranges have more high-frequency partials culled out. |
| 181 void PeriodicWave::createBandLimitedTables(const float* realData, const float* i
magData, unsigned numberOfComponents, bool disableNormalization) | 172 void PeriodicWave::createBandLimitedTables(const float* realData, const float* i
magData, unsigned numberOfComponents, bool disableNormalization) |
| 182 { | 173 { |
| 183 // TODO(rtoy): Figure out why this needs to be 0.5 when normalization is dis
abled. | 174 // TODO(rtoy): Figure out why this needs to be 0.5 when normalization is dis
abled. |
| 184 float normalizationScale = 0.5; | 175 float normalizationScale = 0.5; |
| 185 | 176 |
| 186 unsigned fftSize = periodicWaveSize(); | 177 unsigned fftSize = periodicWaveSize(); |
| 187 unsigned halfSize = fftSize / 2; | 178 unsigned halfSize = fftSize / 2; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 216 imagP[i] = 0; | 207 imagP[i] = 0; |
| 217 } | 208 } |
| 218 | 209 |
| 219 // Clear packed-nyquist and any DC-offset. | 210 // Clear packed-nyquist and any DC-offset. |
| 220 realP[0] = 0; | 211 realP[0] = 0; |
| 221 imagP[0] = 0; | 212 imagP[0] = 0; |
| 222 | 213 |
| 223 // Create the band-limited table. | 214 // Create the band-limited table. |
| 224 unsigned waveSize = periodicWaveSize(); | 215 unsigned waveSize = periodicWaveSize(); |
| 225 OwnPtr<AudioFloatArray> table = adoptPtr(new AudioFloatArray(waveSize)); | 216 OwnPtr<AudioFloatArray> table = adoptPtr(new AudioFloatArray(waveSize)); |
| 226 adjustV8ExternalMemory(waveSize * sizeof(float)); | |
| 227 m_bandLimitedTables.append(table.release()); | 217 m_bandLimitedTables.append(table.release()); |
| 228 | 218 |
| 229 // Apply an inverse FFT to generate the time-domain table data. | 219 // Apply an inverse FFT to generate the time-domain table data. |
| 230 float* data = m_bandLimitedTables[rangeIndex]->data(); | 220 float* data = m_bandLimitedTables[rangeIndex]->data(); |
| 231 frame.doInverseFFT(data); | 221 frame.doInverseFFT(data); |
| 232 | 222 |
| 233 // For the first range (which has the highest power), calculate its peak
value then compute normalization scale. | 223 // For the first range (which has the highest power), calculate its peak
value then compute normalization scale. |
| 234 if (!disableNormalization) { | 224 if (!disableNormalization) { |
| 235 if (!rangeIndex) { | 225 if (!rangeIndex) { |
| 236 float maxValue; | 226 float maxValue; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 311 } |
| 322 | 312 |
| 323 realP[n] = 0; | 313 realP[n] = 0; |
| 324 imagP[n] = b; | 314 imagP[n] = b; |
| 325 } | 315 } |
| 326 | 316 |
| 327 createBandLimitedTables(realP, imagP, halfSize, false); | 317 createBandLimitedTables(realP, imagP, halfSize, false); |
| 328 } | 318 } |
| 329 | 319 |
| 330 } // namespace blink | 320 } // namespace blink |
| 331 | |
| OLD | NEW |