| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Software adjust volume of samples, allows each audio stream its own | 5 // Software adjust volume of samples, allows each audio stream its own |
| 6 // volume without impacting master volume for chrome and other applications. | 6 // volume without impacting master volume for chrome and other applications. |
| 7 | 7 |
| 8 // Implemented as templates to allow 8, 16 and 32 bit implementations. | 8 // Implemented as templates to allow 8, 16 and 32 bit implementations. |
| 9 // 8 bit is unsigned and biased by 128. | 9 // 8 bit is unsigned and biased by 128. |
| 10 | 10 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 reinterpret_cast<int32*>(buf), | 175 reinterpret_cast<int32*>(buf), |
| 176 sample_count, | 176 sample_count, |
| 177 volume, | 177 volume, |
| 178 channels); | 178 channels); |
| 179 return true; | 179 return true; |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 return false; | 182 return false; |
| 183 } | 183 } |
| 184 | 184 |
| 185 // TODO(dalecurtis): Delete once everywhere is using the AudioBus version: |
| 186 // http://crbug.com/120319. |
| 185 bool DeinterleaveAudioChannel(void* source, | 187 bool DeinterleaveAudioChannel(void* source, |
| 186 float* destination, | 188 float* destination, |
| 187 int channels, | 189 int channels, |
| 188 int channel_index, | 190 int channel_index, |
| 189 int bytes_per_sample, | 191 int bytes_per_sample, |
| 190 size_t number_of_frames) { | 192 size_t number_of_frames) { |
| 191 switch (bytes_per_sample) { | 193 switch (bytes_per_sample) { |
| 192 case 1: | 194 case 1: |
| 193 { | 195 { |
| 194 uint8* source8 = reinterpret_cast<uint8*>(source) + channel_index; | 196 uint8* source8 = reinterpret_cast<uint8*>(source) + channel_index; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 221 } | 223 } |
| 222 return true; | 224 return true; |
| 223 } | 225 } |
| 224 | 226 |
| 225 default: | 227 default: |
| 226 break; | 228 break; |
| 227 } | 229 } |
| 228 return false; | 230 return false; |
| 229 } | 231 } |
| 230 | 232 |
| 231 // |Format| is the destination type, |Fixed| is a type larger than |Format| | |
| 232 // such that operations can be made without overflowing. | |
| 233 template<class Format, class Fixed> | |
| 234 static void InterleaveFloatToInt(const AudioBus* source, | |
| 235 void* dst_bytes, size_t number_of_frames) { | |
| 236 Format* destination = reinterpret_cast<Format*>(dst_bytes); | |
| 237 Fixed max_value = std::numeric_limits<Format>::max(); | |
| 238 Fixed min_value = std::numeric_limits<Format>::min(); | |
| 239 | |
| 240 Format bias = 0; | |
| 241 if (!std::numeric_limits<Format>::is_signed) { | |
| 242 bias = max_value / 2; | |
| 243 max_value = bias; | |
| 244 min_value = -(bias - 1); | |
| 245 } | |
| 246 | |
| 247 int channels = source->channels(); | |
| 248 for (int i = 0; i < channels; ++i) { | |
| 249 const float* channel_data = source->channel(i); | |
| 250 for (size_t j = 0; j < number_of_frames; ++j) { | |
| 251 Fixed sample = max_value * channel_data[j]; | |
| 252 if (sample > max_value) | |
| 253 sample = max_value; | |
| 254 else if (sample < min_value) | |
| 255 sample = min_value; | |
| 256 | |
| 257 destination[j * channels + i] = static_cast<Format>(sample) + bias; | |
| 258 } | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 void InterleaveFloatToInt(const AudioBus* source, void* dst, | |
| 263 size_t number_of_frames, int bytes_per_sample) { | |
| 264 switch (bytes_per_sample) { | |
| 265 case 1: | |
| 266 InterleaveFloatToInt<uint8, int32>(source, dst, number_of_frames); | |
| 267 break; | |
| 268 case 2: | |
| 269 InterleaveFloatToInt<int16, int32>(source, dst, number_of_frames); | |
| 270 break; | |
| 271 case 4: | |
| 272 InterleaveFloatToInt<int32, int64>(source, dst, number_of_frames); | |
| 273 break; | |
| 274 default: | |
| 275 break; | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 // TODO(enal): use template specialization and size-specific intrinsics. | 233 // TODO(enal): use template specialization and size-specific intrinsics. |
| 280 // Call is on the time-critical path, and by using SSE/AVX | 234 // Call is on the time-critical path, and by using SSE/AVX |
| 281 // instructions we can speed things up by ~4-8x, more for the case | 235 // instructions we can speed things up by ~4-8x, more for the case |
| 282 // when we have to adjust volume as well. | 236 // when we have to adjust volume as well. |
| 283 template<class Format, class Fixed, int min_value, int max_value, int bias> | 237 template<class Format, class Fixed, int min_value, int max_value, int bias> |
| 284 static void MixStreams(Format* dst, Format* src, int count, float volume) { | 238 static void MixStreams(Format* dst, Format* src, int count, float volume) { |
| 285 if (volume == 0.0f) | 239 if (volume == 0.0f) |
| 286 return; | 240 return; |
| 287 if (volume == 1.0f) { | 241 if (volume == 1.0f) { |
| 288 // Most common case -- no need to adjust volume. | 242 // Most common case -- no need to adjust volume. |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 // out performance was degraded compared to XP. | 501 // out performance was degraded compared to XP. |
| 548 // - The regression was fixed in Windows 7 and most configurations will work | 502 // - The regression was fixed in Windows 7 and most configurations will work |
| 549 // with 2, but some (e.g., some Sound Blasters) still need 3. | 503 // with 2, but some (e.g., some Sound Blasters) still need 3. |
| 550 // - Some XP configurations (even multi-processor ones) also need 3. | 504 // - Some XP configurations (even multi-processor ones) also need 3. |
| 551 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; | 505 return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3; |
| 552 } | 506 } |
| 553 | 507 |
| 554 #endif | 508 #endif |
| 555 | 509 |
| 556 } // namespace media | 510 } // namespace media |
| OLD | NEW |