1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates a unified stream based on the cras (ChromeOS audio server) interface. 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// CrasUnifiedStream object is *not* thread-safe and should only be used 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from the audio thread. 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef MEDIA_AUDIO_LINUX_CRAS_UNIFIED_H_ 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MEDIA_AUDIO_LINUX_CRAS_UNIFIED_H_ 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cras_client.h> 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_io.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace media { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AudioManagerCras; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation of AudioOuputStream for Chrome OS using the Chrome OS audio 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// server. 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(dgreid): This class is used for only output, either remove all the 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// relevant input code and change the class to CrasOutputStream or merge 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// cras_input.cc into this unified implementation. 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MEDIA_EXPORT CrasUnifiedStream : public AudioOutputStream { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The ctor takes all the usual parameters, plus |manager| which is the 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // audio manager who is creating this object. 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CrasUnifiedStream(const AudioParameters& params, AudioManagerCras* manager); 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The dtor is typically called by the AudioManager only and it is usually 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // triggered by calling AudioUnifiedStream::Close(). 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~CrasUnifiedStream(); 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Implementation of AudioOutputStream. 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool Open() OVERRIDE; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Close() OVERRIDE; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Start(AudioSourceCallback* callback) OVERRIDE; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Stop() OVERRIDE; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetVolume(double volume) OVERRIDE; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetVolume(double* volume) OVERRIDE; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Convert Latency in time to bytes. 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 GetBytesLatency(const struct timespec& latency); 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Handles captured audio and fills the ouput with audio to be played. 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static int UnifiedCallback(cras_client* client, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_stream_id_t stream_id, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8* input_samples, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8* output_samples, 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int frames, 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const timespec* input_ts, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const timespec* output_ts, 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void* arg); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Handles notification that there was an error with the playback stream. 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static int StreamError(cras_client* client, 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_stream_id_t stream_id, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int err, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void* arg); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Chooses the correct audio callback based on stream direction. 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 DispatchCallback(size_t frames, 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8* input_samples, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8* output_samples, 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const timespec* input_ts, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const timespec* output_ts); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Writes audio for a playback stream. 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 WriteAudio(size_t frames, uint8* buffer, const timespec* sample_ts); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deals with an error that occured in the stream. Called from StreamError(). 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void NotifyStreamError(int err); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The client used to communicate with the audio server. 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_client* client_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ID of the playing stream. 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_stream_id_t stream_id_; 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // PCM parameters for the stream. 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioParameters params_; 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Size of frame in bytes. 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32 bytes_per_frame_; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // True if stream is playing. 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_playing_; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Volume level from 0.0 to 1.0. 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) float volume_; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Audio manager that created us. Used to report that we've been closed. 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioManagerCras* manager_; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Callback to get audio samples. 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioSourceCallback* source_callback_; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Container for exchanging data with AudioSourceCallback::OnMoreData(). 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<AudioBus> output_bus_; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Direciton of the stream. 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CRAS_STREAM_DIRECTION stream_direction_; 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrasUnifiedStream); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace media 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // MEDIA_AUDIO_LINUX_CRAS_UNIFIED_H_ 115