1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_AUDIO_LINUX_ALSA_INPUT_H_ 6 #define MEDIA_AUDIO_LINUX_ALSA_INPUT_H_ 7 8 #include <alsa/asoundlib.h> 9 10 #include <string> 11 12 #include "base/compiler_specific.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/time/time.h" 16 #include "media/audio/agc_audio_stream.h" 17 #include "media/audio/audio_io.h" 18 #include "media/audio/audio_parameters.h" 19 20 namespace media { 21 22 class AlsaWrapper; 23 class AudioManagerLinux; 24 25 // Provides an input stream for audio capture based on the ALSA PCM interface. 26 // This object is not thread safe and all methods should be invoked in the 27 // thread that created the object. 28 class AlsaPcmInputStream : public AgcAudioStream<AudioInputStream> { 29 public: 30 // Pass this to the constructor if you want to attempt auto-selection 31 // of the audio recording device. 32 static const char kAutoSelectDevice[]; 33 34 // Create a PCM Output stream for the ALSA device identified by 35 // |device_name|. If unsure of what to use for |device_name|, use 36 // |kAutoSelectDevice|. 37 AlsaPcmInputStream(AudioManagerLinux* audio_manager, 38 const std::string& device_name, 39 const AudioParameters& params, 40 AlsaWrapper* wrapper); 41 42 virtual ~AlsaPcmInputStream(); 43 44 // Implementation of AudioInputStream. 45 virtual bool Open() OVERRIDE; 46 virtual void Start(AudioInputCallback* callback) OVERRIDE; 47 virtual void Stop() OVERRIDE; 48 virtual void Close() OVERRIDE; 49 virtual double GetMaxVolume() OVERRIDE; 50 virtual void SetVolume(double volume) OVERRIDE; 51 virtual double GetVolume() OVERRIDE; 52 53 private: 54 // Logs the error and invokes any registered callbacks. 55 void HandleError(const char* method, int error); 56 57 // Reads one or more buffers of audio from the device, passes on to the 58 // registered callback and schedules the next read. 59 void ReadAudio(); 60 61 // Recovers from any device errors if possible. 62 bool Recover(int error); 63 64 // Utility function for talking with the ALSA API. 65 snd_pcm_sframes_t GetCurrentDelay(); 66 67 // Non-refcounted pointer back to the audio manager. 68 // The AudioManager indirectly holds on to stream objects, so we don't 69 // want circular references. Additionally, stream objects live on the audio 70 // thread, which is owned by the audio manager and we don't want to addref 71 // the manager from that thread. 72 AudioManagerLinux* audio_manager_; 73 std::string device_name_; 74 AudioParameters params_; 75 int bytes_per_buffer_; 76 AlsaWrapper* wrapper_; 77 base::TimeDelta buffer_duration_; // Length of each recorded buffer. 78 AudioInputCallback* callback_; // Valid during a recording session. 79 base::TimeTicks next_read_time_; // Scheduled time for next read callback. 80 snd_pcm_t* device_handle_; // Handle to the ALSA PCM recording device. 81 snd_mixer_t* mixer_handle_; // Handle to the ALSA microphone mixer. 82 snd_mixer_elem_t* mixer_element_handle_; // Handle to the capture element. 83 base::WeakPtrFactory<AlsaPcmInputStream> weak_factory_; 84 scoped_ptr<uint8[]> audio_buffer_; // Buffer used for reading audio data. 85 bool read_callback_behind_schedule_; 86 87 DISALLOW_COPY_AND_ASSIGN(AlsaPcmInputStream); 88 }; 89 90 } // namespace media 91 92 #endif // MEDIA_AUDIO_LINUX_ALSA_INPUT_H_ 93