OLD | NEW |
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 * | 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 18 matching lines...) Expand all Loading... |
29 #include "platform/audio/HRTFKernel.h" | 29 #include "platform/audio/HRTFKernel.h" |
30 | 30 |
31 #include "platform/audio/AudioChannel.h" | 31 #include "platform/audio/AudioChannel.h" |
32 #include "wtf/MathExtras.h" | 32 #include "wtf/MathExtras.h" |
33 #include "wtf/PtrUtil.h" | 33 #include "wtf/PtrUtil.h" |
34 #include <algorithm> | 34 #include <algorithm> |
35 #include <memory> | 35 #include <memory> |
36 | 36 |
37 namespace blink { | 37 namespace blink { |
38 | 38 |
39 // Takes the input AudioChannel as an input impulse response and calculates the
average group delay. | 39 // Takes the input AudioChannel as an input impulse response and calculates the |
40 // This represents the initial delay before the most energetic part of the impul
se response. | 40 // average group delay. This represents the initial delay before the most |
41 // The sample-frame delay is removed from the impulseP impulse response, and thi
s value is returned. | 41 // energetic part of the impulse response. The sample-frame delay is removed |
42 // the length of the passed in AudioChannel must be a power of 2. | 42 // from the impulseP impulse response, and this value is returned. The length |
| 43 // of the passed in AudioChannel must be a power of 2. |
43 static float extractAverageGroupDelay(AudioChannel* channel, | 44 static float extractAverageGroupDelay(AudioChannel* channel, |
44 size_t analysisFFTSize) { | 45 size_t analysisFFTSize) { |
45 ASSERT(channel); | 46 ASSERT(channel); |
46 | 47 |
47 float* impulseP = channel->mutableData(); | 48 float* impulseP = channel->mutableData(); |
48 | 49 |
49 bool isSizeGood = channel->length() >= analysisFFTSize; | 50 bool isSizeGood = channel->length() >= analysisFFTSize; |
50 ASSERT(isSizeGood); | 51 ASSERT(isSizeGood); |
51 if (!isSizeGood) | 52 if (!isSizeGood) |
52 return 0; | 53 return 0; |
(...skipping 14 matching lines...) Expand all Loading... |
67 HRTFKernel::HRTFKernel(AudioChannel* channel, size_t fftSize, float sampleRate) | 68 HRTFKernel::HRTFKernel(AudioChannel* channel, size_t fftSize, float sampleRate) |
68 : m_frameDelay(0), m_sampleRate(sampleRate) { | 69 : m_frameDelay(0), m_sampleRate(sampleRate) { |
69 ASSERT(channel); | 70 ASSERT(channel); |
70 | 71 |
71 // Determine the leading delay (average group delay) for the response. | 72 // Determine the leading delay (average group delay) for the response. |
72 m_frameDelay = extractAverageGroupDelay(channel, fftSize / 2); | 73 m_frameDelay = extractAverageGroupDelay(channel, fftSize / 2); |
73 | 74 |
74 float* impulseResponse = channel->mutableData(); | 75 float* impulseResponse = channel->mutableData(); |
75 size_t responseLength = channel->length(); | 76 size_t responseLength = channel->length(); |
76 | 77 |
77 // We need to truncate to fit into 1/2 the FFT size (with zero padding) in ord
er to do proper convolution. | 78 // We need to truncate to fit into 1/2 the FFT size (with zero padding) in |
78 size_t truncatedResponseLength = std::min( | 79 // order to do proper convolution. |
79 responseLength, | 80 // Truncate if necessary to max impulse response length allowed by FFT. |
80 fftSize / | 81 size_t truncatedResponseLength = std::min(responseLength, fftSize / 2); |
81 2); // truncate if necessary to max impulse response length allowed b
y FFT | |
82 | 82 |
83 // Quick fade-out (apply window) at truncation point | 83 // Quick fade-out (apply window) at truncation point |
84 unsigned numberOfFadeOutFrames = static_cast<unsigned>( | 84 unsigned numberOfFadeOutFrames = static_cast<unsigned>( |
85 sampleRate / 4410); // 10 sample-frames @44.1KHz sample-rate | 85 sampleRate / 4410); // 10 sample-frames @44.1KHz sample-rate |
86 ASSERT(numberOfFadeOutFrames < truncatedResponseLength); | 86 ASSERT(numberOfFadeOutFrames < truncatedResponseLength); |
87 if (numberOfFadeOutFrames < truncatedResponseLength) { | 87 if (numberOfFadeOutFrames < truncatedResponseLength) { |
88 for (unsigned i = truncatedResponseLength - numberOfFadeOutFrames; | 88 for (unsigned i = truncatedResponseLength - numberOfFadeOutFrames; |
89 i < truncatedResponseLength; ++i) { | 89 i < truncatedResponseLength; ++i) { |
90 float x = 1.0f - | 90 float x = 1.0f - |
91 static_cast<float>( | 91 static_cast<float>( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay(); | 133 (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay(); |
134 | 134 |
135 std::unique_ptr<FFTFrame> interpolatedFrame = | 135 std::unique_ptr<FFTFrame> interpolatedFrame = |
136 FFTFrame::createInterpolatedFrame(*kernel1->fftFrame(), | 136 FFTFrame::createInterpolatedFrame(*kernel1->fftFrame(), |
137 *kernel2->fftFrame(), x); | 137 *kernel2->fftFrame(), x); |
138 return HRTFKernel::create(std::move(interpolatedFrame), frameDelay, | 138 return HRTFKernel::create(std::move(interpolatedFrame), frameDelay, |
139 sampleRate1); | 139 sampleRate1); |
140 } | 140 } |
141 | 141 |
142 } // namespace blink | 142 } // namespace blink |
OLD | NEW |