Chromium Code Reviews| Index: ppapi/examples/audio/audio.cc |
| diff --git a/ppapi/examples/audio/audio.cc b/ppapi/examples/audio/audio.cc |
| index 91042fa11fb3fda3d0eb7fa961fbddeecd58102d..8b813b327ffb03b4c8f2148cb3d398e271f86651 100644 |
| --- a/ppapi/examples/audio/audio.cc |
| +++ b/ppapi/examples/audio/audio.cc |
| @@ -2,7 +2,15 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include <cmath> |
| +// Needed on Windows to get |M_PI| from math.h on Windows. |
|
viettrungluu
2011/11/30 02:26:31
From the Department of Redundancy Department, obvi
|
| +#ifdef _WIN32 |
| +#define _USE_MATH_DEFINES |
| +#endif |
| + |
| +#include <math.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| + |
| #include <limits> |
| #include "ppapi/c/pp_errors.h" |
| @@ -14,61 +22,79 @@ |
| // Separate left and right frequency to make sure we didn't swap L & R. |
| // Sounds pretty horrible, though... |
| -const double frequency_l = 400; |
| -const double frequency_r = 1000; |
| +const double kLeftFrequency = 400; |
| +const double kRightFrequency = 1000; |
| // This sample frequency is guaranteed to work. |
| -const PP_AudioSampleRate sample_frequency = PP_AUDIOSAMPLERATE_44100; |
| -const uint32_t sample_count = 4096; |
| -uint32_t obtained_sample_count = 0; |
| +const PP_AudioSampleRate kDefaultSampleRate = PP_AUDIOSAMPLERATE_44100; |
| +const uint32_t kDefaultSampleCount = 4096; |
| -const double kPi = 3.141592653589; |
| -const double kTwoPi = 2.0 * kPi; |
| +const char kSampleRateAttributeName[] = "samplerate"; |
| class MyInstance : public pp::Instance { |
| public: |
| explicit MyInstance(PP_Instance instance) |
| : pp::Instance(instance), |
| + sample_rate_(kDefaultSampleRate), |
| + sample_count_(0), |
| audio_wave_l_(0.0), |
| audio_wave_r_(0.0) { |
| } |
| virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| + for (uint32_t i = 0; i < argc; i++) { |
| + if (strcmp(kSampleRateAttributeName, argn[i]) == 0) { |
| + int value = atoi(argv[i]); |
| + if (value > 0 && value <= 1000000) |
| + sample_rate_ = static_cast<PP_AudioSampleRate>(value); |
| + else |
| + return false; |
| + } |
| + } |
| + |
| pp::AudioConfig config; |
| - obtained_sample_count = pp::AudioConfig::RecommendSampleFrameCount( |
| - sample_frequency, sample_count); |
| - config = pp::AudioConfig(this, sample_frequency, obtained_sample_count); |
| - audio_ = pp::Audio(this, config, SineWaveCallback, this); |
| + sample_count_ = pp::AudioConfig::RecommendSampleFrameCount( |
| + sample_rate_, kDefaultSampleCount); |
| + config = pp::AudioConfig(this, sample_rate_, sample_count_); |
| + audio_ = pp::Audio(this, config, SineWaveCallbackTrampoline, this); |
| return audio_.StartPlayback(); |
| } |
| private: |
| - static void SineWaveCallback(void* samples, uint32_t num_bytes, void* thiz) { |
| - const double delta_l = kTwoPi * frequency_l / sample_frequency; |
| - const double delta_r = kTwoPi * frequency_r / sample_frequency; |
| + static void SineWaveCallbackTrampoline(void* samples, |
| + uint32_t num_bytes, |
| + void* thiz) { |
| + static_cast<MyInstance*>(thiz)->SineWaveCallback(samples, num_bytes); |
| + } |
| + |
| + void SineWaveCallback(void* samples, uint32_t num_bytes) { |
| + double delta_l = 2.0 * M_PI * kLeftFrequency / sample_rate_; |
| + double delta_r = 2.0 * M_PI * kRightFrequency / sample_rate_; |
| // Use per channel audio wave value to avoid clicks on buffer boundries. |
| - double wave_l = reinterpret_cast<MyInstance*>(thiz)->audio_wave_l_; |
| - double wave_r = reinterpret_cast<MyInstance*>(thiz)->audio_wave_r_; |
| + double wave_l = audio_wave_l_; |
| + double wave_r = audio_wave_r_; |
| const int16_t max_int16 = std::numeric_limits<int16_t>::max(); |
| int16_t* buf = reinterpret_cast<int16_t*>(samples); |
| - for (size_t sample = 0; sample < obtained_sample_count; ++sample) { |
| + for (size_t sample = 0; sample < sample_count_; ++sample) { |
| *buf++ = static_cast<int16_t>(sin(wave_l) * max_int16); |
| *buf++ = static_cast<int16_t>(sin(wave_r) * max_int16); |
| - // Add delta, keep within -kTwoPi..kTwoPi to preserve precision. |
| + // Add delta, keep within -2 * M_PI .. 2 * M_PI to preserve precision. |
| wave_l += delta_l; |
| - if (wave_l > kTwoPi) |
| - wave_l -= kTwoPi * 2.0; |
| + if (wave_l > 2.0 * M_PI) |
| + wave_l -= 2.0 * M_PI; |
| wave_r += delta_r; |
| - if (wave_r > kTwoPi) |
| - wave_r -= kTwoPi * 2.0; |
| + if (wave_r > 2.0 * M_PI) |
| + wave_r -= 2.0 * M_PI; |
| } |
| // Store current value to use as starting point for next callback. |
| - reinterpret_cast<MyInstance*>(thiz)->audio_wave_l_ = wave_l; |
| - reinterpret_cast<MyInstance*>(thiz)->audio_wave_r_ = wave_r; |
| + audio_wave_l_ = wave_l; |
| + audio_wave_r_ = wave_r; |
| } |
| - // Audio resource. Allocated in Init(), freed on destruction. |
| + PP_AudioSampleRate sample_rate_; |
| + uint32_t sample_count_; |
| + |
| pp::Audio audio_; |
| // Current audio wave position, used to prevent sine wave skips |