15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdlib.h> 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h> 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <limits> 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/audio_buffer.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/graphics_2d.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/image_data.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/instance.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/logging.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/media_stream_audio_track.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/module.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/rect.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/size.h" 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ppapi/cpp/var_dictionary.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When compiling natively on Windows, PostMessage can be #define-d to 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// something else. 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef PostMessage 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef PostMessage 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This example demonstrates receiving audio samples from an AndioMediaTrack 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and visualizing them. 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32_t kColorRed = 0xFFFF0000; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32_t kColorGreen = 0xFF00FF00; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32_t kColorGrey1 = 0xFF202020; 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32_t kColorGrey2 = 0xFF404040; 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32_t kColorGrey3 = 0xFF606060; 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MediaStreamAudioInstance : public pp::Instance { 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit MediaStreamAudioInstance(PP_Instance instance) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : pp::Instance(instance), 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_factory_(this), 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_buffer_(true), 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sample_count_(0), 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) channel_count_(0), 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_interval_(0), 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_paint_(false), 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) waiting_for_flush_completion_(false) { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MediaStreamAudioInstance() { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (position.size() == size_) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_ = position.size(); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_context_ = pp::Graphics2D(this, size_, false); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!BindGraphics(device_context_)) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Paint(); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void HandleMessage(const pp::Var& var_message) { 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!var_message.is_dictionary()) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::VarDictionary var_dictionary_message(var_message); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Var var_track = var_dictionary_message.Get("track"); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!var_track.is_resource()) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Resource resource_track = var_track.AsResource(); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_track_ = pp::MediaStreamAudioTrack(resource_track); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_track_.GetBuffer(callback_factory_.NewCallbackWithOutput( 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &MediaStreamAudioInstance::OnGetBuffer)); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ScheduleNextTimer() { 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_DCHECK(timer_interval_ > 0); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Module::Get()->core()->CallOnMainThread( 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_interval_, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_factory_.NewCallback(&MediaStreamAudioInstance::OnTimer), 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnTimer(int32_t) { 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleNextTimer(); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Paint(); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DidFlush(int32_t result) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) waiting_for_flush_completion_ = false; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pending_paint_) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Paint(); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Paint() { 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (waiting_for_flush_completion_) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_paint_ = true; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_paint_ = false; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (size_.IsEmpty()) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // Nothing to do. 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::ImageData image = PaintImage(size_); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!image.is_null()) { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_context_.ReplaceContents(&image); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) waiting_for_flush_completion_ = true; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_context_.Flush( 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_factory_.NewCallback(&MediaStreamAudioInstance::DidFlush)); 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::ImageData PaintImage(const pp::Size& size) { 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (image.is_null()) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return image; 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Clear to dark grey. 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int y = 0; y < size.height(); y++) { 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int x = 0; x < size.width(); x++) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *image.GetAddr32(pp::Point(x, y)) = kColorGrey1; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int mid_height = size.height() / 2; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int max_amplitude = size.height() * 4 / 10; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Draw some lines. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int x = 0; x < size.width(); x++) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *image.GetAddr32(pp::Point(x, mid_height)) = kColorGrey3; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *image.GetAddr32(pp::Point(x, mid_height + max_amplitude)) = kColorGrey2; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *image.GetAddr32(pp::Point(x, mid_height - max_amplitude)) = kColorGrey2; 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Draw our samples. 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int x = 0, i = 0; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) x < std::min(size.width(), static_cast<int>(sample_count_)); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) x++, i += channel_count_) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (uint32_t ch = 0; ch < std::min(channel_count_, 2U); ++ch) { 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int y = samples_[i + ch] * max_amplitude / 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (std::numeric_limits<int16_t>::max() + 1) + mid_height; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *image.GetAddr32(pp::Point(x, y)) = (ch == 0 ? kColorRed : kColorGreen); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return image; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Callback that is invoked when new buffers are received. 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnGetBuffer(int32_t result, pp::AudioBuffer buffer) { 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != PP_OK) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_DCHECK(buffer.GetSampleSize() == PP_AUDIOBUFFER_SAMPLESIZE_16_BITS); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* data = static_cast<const char*>(buffer.GetDataBuffer()); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t channels = buffer.GetNumberOfChannels(); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t samples = buffer.GetNumberOfSamples() / channels; 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (channel_count_ != channels || sample_count_ != samples) { 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) channel_count_ = channels; 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sample_count_ = samples; 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) samples_.resize(sample_count_ * channel_count_); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_interval_ = (sample_count_ * 1000) / buffer.GetSampleRate() + 5; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Start the timer for the first buffer. 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (first_buffer_) { 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_buffer_ = false; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleNextTimer(); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(samples_.data(), data, 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sample_count_ * channel_count_ * sizeof(int16_t)); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_track_.RecycleBuffer(buffer); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_track_.GetBuffer(callback_factory_.NewCallbackWithOutput( 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &MediaStreamAudioInstance::OnGetBuffer)); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::MediaStreamAudioTrack audio_track_; 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::CompletionCallbackFactory<MediaStreamAudioInstance> callback_factory_; 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool first_buffer_; 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t sample_count_; 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t channel_count_; 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<int16_t> samples_; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t timer_interval_; 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Painting stuff. 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Size size_; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp::Graphics2D device_context_; 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool pending_paint_; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool waiting_for_flush_completion_; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MediaStreamAudioModule : public pp::Module { 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual pp::Instance* CreateInstance(PP_Instance instance) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new MediaStreamAudioInstance(instance); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace pp { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Factory function for your specialization of the Module object. 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Module* CreateModule() { 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new MediaStreamAudioModule(); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace pp 225