15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifndef COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_H_ 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_H_ 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string> 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/gtest_prod_util.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/macros.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "media/audio/audio_io.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "media/audio/audio_parameters.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "media/base/audio_converter.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace base { 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class MessageLoop; 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace media { 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AudioBus; 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace copresence { 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The AudioRecorder class will record audio until told to stop. 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AudioRecorder : public media::AudioInputStream::AudioInputCallback, 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public media::AudioConverter::InputCallback { 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef base::Callback<void(const std::string&)> DecodeSamplesCallback; 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit AudioRecorder(const DecodeSamplesCallback& decode_callback); 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Initializes the object. Do not use this object before calling this method. 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void Initialize(); 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void Record(); 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void Stop(); 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Cleans up and deletes this object. Do not use object after this call. 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void Finalize(); 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool IsRecording(); 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Takes ownership of the stream. 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void set_input_stream_for_testing( 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) media::AudioInputStream* input_stream_for_testing) { 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) input_stream_for_testing_.reset(input_stream_for_testing); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Takes ownership of the params. 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void set_params_for_testing(media::AudioParameters* params_for_testing) { 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params_for_testing_.reset(params_for_testing); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) protected: 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual ~AudioRecorder(); 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void set_is_recording(bool is_recording) { is_recording_ = is_recording; } 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) friend class AudioRecorderTest; 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, BasicRecordAndStop); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, OutOfOrderRecordAndStopMultiple); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Methods to do our various operations; all of these need to be run on the 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // audio thread. 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void InitializeOnAudioThread(); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void RecordOnAudioThread(); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void StopOnAudioThread(); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void StopAndCloseOnAudioThread(); 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void FinalizeOnAudioThread(); 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // AudioInputStream::AudioInputCallback overrides: 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Called by the audio recorder when a full packet of audio data is 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // available. This is called from a special audio thread and the 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // implementation should return as soon as possible. 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void OnData(media::AudioInputStream* stream, 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const media::AudioBus* source, 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32 hardware_delay_bytes, 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double volume) OVERRIDE; 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void OnError(media::AudioInputStream* stream) OVERRIDE; 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // AudioConverter::InputCallback overrides: 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual double ProvideInput(media::AudioBus* dest, 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta buffer_delay) OVERRIDE; 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Flushes the audio loop, making sure that any queued operations are 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // performed. 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void FlushAudioLoopForTesting(); 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_recording_; 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) media::AudioInputStream* stream_; 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DecodeSamplesCallback decode_callback_; 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // ProvideInput will use this buffer as its source. 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const media::AudioBus* temp_conversion_buffer_; 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Outside of the ctor/Initialize method, only access the next variables on 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the recording thread. 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<media::AudioBus> buffer_; 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int total_buffer_frames_; 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int buffer_frame_index_; 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<media::AudioConverter> converter_; 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<media::AudioInputStream> input_stream_for_testing_; 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<media::AudioParameters> params_for_testing_; 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioRecorder); 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace copresence 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif // COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_H_ 117