1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146

media / audio / simple_sources.h [blame]

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_AUDIO_SIMPLE_SOURCES_H_
#define MEDIA_AUDIO_SIMPLE_SOURCES_H_

#include <stdint.h>

#include <memory>

#include "base/containers/heap_array.h"
#include "base/files/file_path.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "media/audio/audio_io.h"
#include "media/base/audio_converter.h"
#include "media/base/seekable_buffer.h"

namespace media {

class WavAudioHandler;

// An audio source that produces a pure sinusoidal tone.
class MEDIA_EXPORT SineWaveAudioSource
    : public AudioOutputStream::AudioSourceCallback {
 public:
  // |channels| is the number of audio channels, |freq| is the frequency in
  // hertz and it has to be less than half of the sampling frequency
  // |sample_freq| or else you will get aliasing.
  SineWaveAudioSource(int channels, double freq, double sample_freq);
  ~SineWaveAudioSource() override;

  // Return up to |cap| samples of data via OnMoreData().  Use Reset() to
  // allow more data to be served.
  void CapSamples(int cap);
  void Reset();

  // Sets a callback to be called in OnMoreData(). The callback should be set
  // only once before SineWaveAudioSource is passed to AudioOutputStream. It
  // will be called on the same thread on which the stream calls OnMoreData(),
  // which is usually different from the thread where the source is created.
  void set_on_more_data_callback(base::RepeatingClosure on_more_data_callback) {
    on_more_data_callback_ = on_more_data_callback;
  }

  // Implementation of AudioSourceCallback.
  int OnMoreData(base::TimeDelta delay,
                 base::TimeTicks timestamp,
                 const AudioGlitchInfo& glitch_info,
                 AudioBus* dest) override;
  void OnError(ErrorType type) override;

  // The number of OnMoreData() and OnError() calls respectively.
  int callbacks() {
    base::AutoLock auto_lock(lock_);
    return callbacks_;
  }
  int pos_samples() {
    base::AutoLock auto_lock(lock_);
    return pos_samples_;
  }
  int errors() { return errors_; }

 protected:
  const int channels_;
  const double f_;

  base::RepeatingClosure on_more_data_callback_;

  base::Lock lock_;
  int pos_samples_ GUARDED_BY(lock_) = 0;
  int cap_ GUARDED_BY(lock_) = 0;
  int callbacks_ GUARDED_BY(lock_) = 0;
  int errors_ = 0;
};

class MEDIA_EXPORT FileSource : public AudioOutputStream::AudioSourceCallback,
                                public AudioConverter::InputCallback {
 public:
  FileSource(const AudioParameters& params,
             const base::FilePath& path_to_wav_file,
             bool loop);
  ~FileSource() override;

  // Implementation of AudioSourceCallback.
  int OnMoreData(base::TimeDelta delay,
                 base::TimeTicks delay_timestamp,
                 const AudioGlitchInfo& glitch_info,
                 AudioBus* dest) override;
  void OnError(ErrorType type) override;

 private:
  AudioParameters params_;
  base::FilePath path_to_wav_file_;

  // The WAV data at |path_to_wav_file_| is read into memory and kept here.
  // This memory needs to survive for the lifetime of |wav_audio_handler_|,
  // so declare it first. Do not access this member directly.
  base::HeapArray<uint8_t> raw_wav_data_;

  std::unique_ptr<WavAudioHandler> wav_audio_handler_;
  std::unique_ptr<AudioConverter> file_audio_converter_;
  bool load_failed_;
  bool looping_;

  // Provides audio data from wav_audio_handler_ into the file audio converter.
  double ProvideInput(AudioBus* audio_bus,
                      uint32_t frames_delayed,
                      const AudioGlitchInfo& glitch_info) override;

  // Loads the wav file on the first OnMoreData invocation.
  void LoadWavFile(const base::FilePath& path_to_wav_file);

  // Rewinds the player to the start of the loaded wav file.
  void Rewind();
};

class BeepingSource : public AudioOutputStream::AudioSourceCallback {
 public:
  explicit BeepingSource(const AudioParameters& params);
  ~BeepingSource() override;

  // Implementation of AudioSourceCallback.
  int OnMoreData(base::TimeDelta delay,
                 base::TimeTicks delay_timestamp,
                 const AudioGlitchInfo& glitch_info,
                 AudioBus* dest) override;
  void OnError(ErrorType type) override;

  static void BeepOnce();

 private:
  base::HeapArray<uint8_t> buffer_;
  AudioParameters params_;
  base::TimeTicks last_callback_time_;
  base::TimeDelta interval_from_last_beep_;
  int beep_duration_in_buffers_;
  int beep_generated_in_buffers_;
  int beep_period_in_frames_;
};

}  // namespace media

#endif  // MEDIA_AUDIO_SIMPLE_SOURCES_H_