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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 DCHECK(channel); | 46 DCHECK(channel); |
47 | 47 |
48 float* impulseP = channel->mutableData(); | 48 float* impulseP = channel->mutableData(); |
49 | 49 |
50 bool isSizeGood = channel->length() >= analysisFFTSize; | 50 bool isSizeGood = channel->length() >= analysisFFTSize; |
51 DCHECK(isSizeGood); | 51 DCHECK(isSizeGood); |
52 if (!isSizeGood) | 52 if (!isSizeGood) |
53 return 0; | 53 return 0; |
54 | 54 |
55 // Check for power-of-2. | 55 // Check for power-of-2. |
56 DCHECK_EQ(1UL << static_cast<unsigned>(log2(analysisFFTSize)), | 56 ASSERT(1UL << static_cast<unsigned>(log2(analysisFFTSize)) == |
57 analysisFFTSize); | 57 analysisFFTSize); |
58 | 58 |
59 FFTFrame estimationFrame(analysisFFTSize); | 59 FFTFrame estimationFrame(analysisFFTSize); |
60 estimationFrame.doFFT(impulseP); | 60 estimationFrame.doFFT(impulseP); |
61 | 61 |
62 float frameDelay = clampTo<float>(estimationFrame.extractAverageGroupDelay()); | 62 float frameDelay = clampTo<float>(estimationFrame.extractAverageGroupDelay()); |
63 estimationFrame.doInverseFFT(impulseP); | 63 estimationFrame.doInverseFFT(impulseP); |
64 | 64 |
65 return frameDelay; | 65 return frameDelay; |
66 } | 66 } |
67 | 67 |
68 HRTFKernel::HRTFKernel(AudioChannel* channel, size_t fftSize, float sampleRate) | 68 HRTFKernel::HRTFKernel(AudioChannel* channel, size_t fftSize, float sampleRate) |
69 : m_frameDelay(0), m_sampleRate(sampleRate) { | 69 : m_frameDelay(0), m_sampleRate(sampleRate) { |
70 DCHECK(channel); | 70 DCHECK(channel); |
71 | 71 |
72 // Determine the leading delay (average group delay) for the response. | 72 // Determine the leading delay (average group delay) for the response. |
73 m_frameDelay = extractAverageGroupDelay(channel, fftSize / 2); | 73 m_frameDelay = extractAverageGroupDelay(channel, fftSize / 2); |
74 | 74 |
75 float* impulseResponse = channel->mutableData(); | 75 float* impulseResponse = channel->mutableData(); |
76 size_t responseLength = channel->length(); | 76 size_t responseLength = channel->length(); |
77 | 77 |
78 // We need to truncate to fit into 1/2 the FFT size (with zero padding) in | 78 // We need to truncate to fit into 1/2 the FFT size (with zero padding) in |
79 // order to do proper convolution. | 79 // order to do proper convolution. |
80 // Truncate if necessary to max impulse response length allowed by FFT. | 80 // Truncate if necessary to max impulse response length allowed by FFT. |
81 size_t truncatedResponseLength = std::min(responseLength, fftSize / 2); | 81 size_t truncatedResponseLength = std::min(responseLength, fftSize / 2); |
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 DCHECK_LT(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>( |
92 i - (truncatedResponseLength - numberOfFadeOutFrames)) / | 92 i - (truncatedResponseLength - numberOfFadeOutFrames)) / |
93 numberOfFadeOutFrames; | 93 numberOfFadeOutFrames; |
94 impulseResponse[i] *= x; | 94 impulseResponse[i] *= x; |
95 } | 95 } |
96 } | 96 } |
(...skipping 12 matching lines...) Expand all Loading... |
109 fftFrame.doInverseFFT(channel->mutableData()); | 109 fftFrame.doInverseFFT(channel->mutableData()); |
110 | 110 |
111 return channel; | 111 return channel; |
112 } | 112 } |
113 | 113 |
114 // Interpolates two kernels with x: 0 -> 1 and returns the result. | 114 // Interpolates two kernels with x: 0 -> 1 and returns the result. |
115 std::unique_ptr<HRTFKernel> HRTFKernel::createInterpolatedKernel( | 115 std::unique_ptr<HRTFKernel> HRTFKernel::createInterpolatedKernel( |
116 HRTFKernel* kernel1, | 116 HRTFKernel* kernel1, |
117 HRTFKernel* kernel2, | 117 HRTFKernel* kernel2, |
118 float x) { | 118 float x) { |
119 DCHECK(kernel1); | 119 ASSERT(kernel1 && kernel2); |
120 DCHECK(kernel2); | |
121 if (!kernel1 || !kernel2) | 120 if (!kernel1 || !kernel2) |
122 return nullptr; | 121 return nullptr; |
123 | 122 |
124 DCHECK_GE(x, 0.0); | 123 ASSERT(x >= 0.0 && x < 1.0); |
125 DCHECK_LT(x, 1.0); | |
126 x = clampTo(x, 0.0f, 1.0f); | 124 x = clampTo(x, 0.0f, 1.0f); |
127 | 125 |
128 float sampleRate1 = kernel1->sampleRate(); | 126 float sampleRate1 = kernel1->sampleRate(); |
129 float sampleRate2 = kernel2->sampleRate(); | 127 float sampleRate2 = kernel2->sampleRate(); |
130 DCHECK_EQ(sampleRate1, sampleRate2); | 128 ASSERT(sampleRate1 == sampleRate2); |
131 if (sampleRate1 != sampleRate2) | 129 if (sampleRate1 != sampleRate2) |
132 return nullptr; | 130 return nullptr; |
133 | 131 |
134 float frameDelay = | 132 float frameDelay = |
135 (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay(); | 133 (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay(); |
136 | 134 |
137 std::unique_ptr<FFTFrame> interpolatedFrame = | 135 std::unique_ptr<FFTFrame> interpolatedFrame = |
138 FFTFrame::createInterpolatedFrame(*kernel1->fftFrame(), | 136 FFTFrame::createInterpolatedFrame(*kernel1->fftFrame(), |
139 *kernel2->fftFrame(), x); | 137 *kernel2->fftFrame(), x); |
140 return HRTFKernel::create(std::move(interpolatedFrame), frameDelay, | 138 return HRTFKernel::create(std::move(interpolatedFrame), frameDelay, |
141 sampleRate1); | 139 sampleRate1); |
142 } | 140 } |
143 | 141 |
144 } // namespace blink | 142 } // namespace blink |
OLD | NEW |