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