OSDN Git Service

Hold lock when doing a route.
[android-x86/hardware-alsa_sound.git] / AudioHardwareALSA.h
index 83fdab3..e08fade 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef ANDROID_AUDIO_HARDWARE_ALSA_H
 #define ANDROID_AUDIO_HARDWARE_ALSA_H
 
+#include <utils/List.h>
 #include <hardware_legacy/AudioHardwareBase.h>
 
 #include <alsa/asoundlib.h>
 
 namespace android
 {
-    class AudioHardwareALSA;
 
-    /**
-     * The id of acoustics module
-     */
-#define ACOUSTICS_HARDWARE_MODULE_ID "acoustics"
-#define ACOUSTICS_HARDWARE_NAME "name"
-
-    struct acoustic_device_t {
-        hw_device_t common;
-
-        /**
-         * Set the provided acoustics for a particular ALSA pcm device.
-         *
-         * Returns: 0 on succes, error code on failure.
-         */
-        status_t (*set_acoustics)(snd_pcm_t *, AudioSystem::audio_in_acoustics);
-
-        /**
-         * Read callback with PCM data so that filtering may be applied.
-         *
-         * Returns: frames filtered on success, error code on failure.
-         */
-        ssize_t (*filter)(snd_pcm_t *, void *, ssize_t);
-    };
-
-    // ----------------------------------------------------------------------------
-
-    class ALSAMixer
-    {
-        public:
-                                    ALSAMixer();
-            virtual                ~ALSAMixer();
+class AudioHardwareALSA;
+
+/**
+ * The id of ALSA module
+ */
+#define ALSA_HARDWARE_MODULE_ID "alsa"
+#define ALSA_HARDWARE_NAME      "alsa"
+
+struct alsa_device_t;
+
+struct alsa_handle_t {
+    alsa_device_t *     module;
+    uint32_t            devices;
+    uint32_t            curDev;
+    int                 curMode;
+    snd_pcm_t *         handle;
+    snd_pcm_format_t    format;
+    uint32_t            channels;
+    uint32_t            sampleRate;
+    unsigned int        latency;         // Delay in usec
+    unsigned int        bufferSize;      // Size of sample buffer
+    void *              modPrivate;
+};
+
+typedef List<alsa_handle_t> ALSAHandleList;
+
+struct alsa_device_t {
+    hw_device_t common;
+
+    status_t (*init)(alsa_device_t *, ALSAHandleList &);
+    status_t (*open)(alsa_handle_t *, uint32_t, int);
+    status_t (*close)(alsa_handle_t *);
+    status_t (*route)(alsa_handle_t *, uint32_t, int);
+};
+
+/**
+ * The id of acoustics module
+ */
+#define ACOUSTICS_HARDWARE_MODULE_ID    "acoustics"
+#define ACOUSTICS_HARDWARE_NAME         "acoustics"
 
-            bool                    isValid() { return !!mMixer[SND_PCM_STREAM_PLAYBACK]; }
-            status_t                setMasterVolume(float volume);
-            status_t                setMasterGain(float gain);
+struct acoustic_device_t {
+    hw_device_t common;
 
-            status_t                setVolume(uint32_t device, float volume);
-            status_t                setGain(uint32_t device, float gain);
+    // Required methods...
+    status_t (*use_handle)(acoustic_device_t *, alsa_handle_t *);
+    status_t (*cleanup)(acoustic_device_t *);
 
-            status_t                setCaptureMuteState(uint32_t device, bool state);
-            status_t                getCaptureMuteState(uint32_t device, bool *state);
-            status_t                setPlaybackMuteState(uint32_t device, bool state);
-            status_t                getPlaybackMuteState(uint32_t device, bool *state);
+    status_t (*set_params)(acoustic_device_t *, AudioSystem::audio_in_acoustics, void *);
 
-        private:
-            snd_mixer_t            *mMixer[SND_PCM_STREAM_LAST+1];
-    };
+    // Optional methods...
+    ssize_t (*read)(acoustic_device_t *, void *, size_t);
+    ssize_t (*write)(acoustic_device_t *, const void *, size_t);
+    status_t (*recover)(acoustic_device_t *, int);
 
-    class ALSAControl
-    {
-        public:
-                                    ALSAControl(const char *device = "default");
-            virtual                ~ALSAControl();
+    void *              modPrivate;
+};
+
+// ----------------------------------------------------------------------------
+
+class ALSAMixer
+{
+public:
+    ALSAMixer();
+    virtual                ~ALSAMixer();
+
+    bool                    isValid() { return !!mMixer[SND_PCM_STREAM_PLAYBACK]; }
+    status_t                setMasterVolume(float volume);
+    status_t                setMasterGain(float gain);
+
+    status_t                setVolume(uint32_t device, float left, float right);
+    status_t                setGain(uint32_t device, float gain);
+
+    status_t                setCaptureMuteState(uint32_t device, bool state);
+    status_t                getCaptureMuteState(uint32_t device, bool *state);
+    status_t                setPlaybackMuteState(uint32_t device, bool state);
+    status_t                getPlaybackMuteState(uint32_t device, bool *state);
+
+private:
+    snd_mixer_t *           mMixer[SND_PCM_STREAM_LAST+1];
+};
+
+class ALSAControl
+{
+public:
+    ALSAControl(const char *device = "hw:00");
+    virtual                ~ALSAControl();
 
-            status_t                get(const char *name, unsigned int &value, int index = 0);
-            status_t                set(const char *name, unsigned int value, int index = -1);
+    status_t                get(const char *name, unsigned int &value, int index = 0);
+    status_t                set(const char *name, unsigned int value, int index = -1);
 
-        private:
-            snd_ctl_t              *mHandle;
-    };
+    status_t                set(const char *name, const char *);
 
-    class ALSAStreamOps
+private:
+    snd_ctl_t *             mHandle;
+};
+
+class ALSAStreamOps
+{
+public:
+    ALSAStreamOps(AudioHardwareALSA *parent, alsa_handle_t *handle);
+    virtual            ~ALSAStreamOps();
+
+    status_t            set(int *format, uint32_t *channels, uint32_t *rate);
+
+    status_t            setParameters(const String8& keyValuePairs);
+    String8             getParameters(const String8& keys);
+
+    uint32_t            sampleRate() const;
+    size_t              bufferSize() const;
+    int                 format() const;
+    uint32_t            channels() const;
+
+    status_t            open(int mode);
+    void                close();
+
+protected:
+    friend class AudioHardwareALSA;
+
+    acoustic_device_t *acoustics();
+    ALSAMixer *mixer();
+
+    AudioHardwareALSA *     mParent;
+    alsa_handle_t *         mHandle;
+
+    Mutex                   mLock;
+    bool                    mPowerLock;
+};
+
+// ----------------------------------------------------------------------------
+
+class AudioStreamOutALSA : public AudioStreamOut, public ALSAStreamOps
+{
+public:
+    AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle);
+    virtual            ~AudioStreamOutALSA();
+
+    virtual uint32_t    sampleRate() const
     {
-        public:
-            struct StreamDefaults
-            {
-                const char *        devicePrefix;
-                snd_pcm_stream_t    direction;       // playback or capture
-                snd_pcm_format_t    format;
-                int                 channels;
-                uint32_t            sampleRate;
-                unsigned int        latency;         // Delay in usec
-                unsigned int        bufferSize;      // Size of sample buffer
-            };
-
-                                    ALSAStreamOps(AudioHardwareALSA *parent);
-            virtual                ~ALSAStreamOps();
-
-            status_t                set(int format,
-                                        int channels,
-                                        uint32_t rate);
-            virtual uint32_t        sampleRate() const;
-            status_t                sampleRate(uint32_t rate);
-            virtual size_t          bufferSize() const;
-            virtual int             format() const;
-            virtual int             channelCount() const;
-            status_t                channelCount(int channels);
-            const char             *streamName();
-            virtual status_t        setDevice(int mode, uint32_t device);
-
-            const char             *deviceName(int mode, uint32_t device);
-
-        protected:
-            friend class AudioStreamOutALSA;
-            friend class AudioStreamInALSA;
-
-            status_t                open(int mode, uint32_t device);
-            void                    close();
-            status_t                setSoftwareParams();
-            status_t                setPCMFormat(snd_pcm_format_t format);
-            status_t                setHardwareResample(bool resample);
-
-            void                    setStreamDefaults(StreamDefaults *dev) {
-                mDefaults = dev;
-            }
-
-        private:
-            AudioHardwareALSA      *mParent;
-            snd_pcm_t              *mHandle;
-            snd_pcm_hw_params_t    *mHardwareParams;
-            snd_pcm_sw_params_t    *mSoftwareParams;
-            int                     mMode;
-            uint32_t                mDevice;
-
-            StreamDefaults         *mDefaults;
-    };
-
-    // ----------------------------------------------------------------------------
-
-    class AudioStreamOutALSA : public AudioStreamOut, public ALSAStreamOps
+        return ALSAStreamOps::sampleRate();
+    }
+
+    virtual size_t      bufferSize() const
     {
-        public:
-                                    AudioStreamOutALSA(AudioHardwareALSA *parent);
-            virtual                ~AudioStreamOutALSA();
+        return ALSAStreamOps::bufferSize();
+    }
 
-            status_t                set(int format          = 0,
-                                        int channelCount    = 0,
-                                        uint32_t sampleRate = 0) {
-                return ALSAStreamOps::set(format, channelCount, sampleRate);
-            }
+    virtual uint32_t    channels() const;
 
-            virtual uint32_t        sampleRate() const
-            {
-                return ALSAStreamOps::sampleRate();
-            }
+    virtual int         format() const
+    {
+        return ALSAStreamOps::format();
+    }
 
-            virtual size_t          bufferSize() const
-            {
-                return ALSAStreamOps::bufferSize();
-            }
+    virtual uint32_t    latency() const;
 
-            virtual int             channelCount() const;
+    virtual ssize_t     write(const void *buffer, size_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
 
-            virtual int             format() const
-            {
-                return ALSAStreamOps::format();
-            }
+    status_t            setVolume(float left, float right);
 
-            virtual uint32_t        latency() const;
+    virtual status_t    standby();
 
-            virtual ssize_t         write(const void *buffer, size_t bytes);
-            virtual status_t        dump(int fd, const Vector<String16>& args);
-            virtual status_t        setDevice(int mode, uint32_t newDevice);
+    virtual status_t    setParameters(const String8& keyValuePairs) {
+        return ALSAStreamOps::setParameters(keyValuePairs);
+    }
 
-            status_t                setVolume(float volume);
+    virtual String8     getParameters(const String8& keys) {
+        return ALSAStreamOps::getParameters(keys);
+    }
 
-            status_t                standby();
-            bool                    isStandby();
-    };
+    // return the number of audio frames written by the audio dsp to DAC since
+    // the output has exited standby
+    virtual status_t    getRenderPosition(uint32_t *dspFrames);
 
-    class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps
+    status_t            open(int mode);
+    status_t            close();
+
+private:
+    uint32_t            mFrameCount;
+};
+
+class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps
+{
+public:
+    AudioStreamInALSA(AudioHardwareALSA *parent,
+            alsa_handle_t *handle,
+            AudioSystem::audio_in_acoustics audio_acoustics);
+    virtual            ~AudioStreamInALSA();
+
+    virtual uint32_t    sampleRate() const
+    {
+        return ALSAStreamOps::sampleRate();
+    }
+
+    virtual size_t      bufferSize() const
+    {
+        return ALSAStreamOps::bufferSize();
+    }
+
+    virtual uint32_t    channels() const
     {
-        public:
-                                    AudioStreamInALSA(AudioHardwareALSA *parent,
-                                                      AudioSystem::audio_in_acoustics acoustics);
-            virtual                ~AudioStreamInALSA();
+        return ALSAStreamOps::channels();
+    }
 
-            status_t                set(int      format       = 0,
-                                        int      channelCount = 0,
-                                        uint32_t sampleRate   = 0) {
-                return ALSAStreamOps::set(format, channelCount, sampleRate);
-            }
+    virtual int         format() const
+    {
+        return ALSAStreamOps::format();
+    }
+
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    virtual status_t    setGain(float gain);
+
+    virtual status_t    standby();
 
-            virtual uint32_t        sampleRate() {
-                return ALSAStreamOps::sampleRate();
-            }
+    virtual status_t    setParameters(const String8& keyValuePairs)
+    {
+        return ALSAStreamOps::setParameters(keyValuePairs);
+    }
 
-            virtual size_t          bufferSize() const
-            {
-                return ALSAStreamOps::bufferSize();
-            }
+    virtual String8     getParameters(const String8& keys)
+    {
+        return ALSAStreamOps::getParameters(keys);
+    }
 
-            virtual int             channelCount() const
-            {
-                return ALSAStreamOps::channelCount();
-            }
+    // Return the amount of input frames lost in the audio driver since the last call of this function.
+    // Audio driver is expected to reset the value to 0 and restart counting upon returning the current value by this function call.
+    // Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
+    // Unit: the number of input audio frames
+    virtual unsigned int  getInputFramesLost() const;
 
-            virtual int             format() const
-            {
-                return ALSAStreamOps::format();
-            }
+    status_t            setAcousticParams(void* params);
 
-            virtual ssize_t         read(void* buffer, ssize_t bytes);
-            virtual status_t        dump(int fd, const Vector<String16>& args);
-            virtual status_t        setDevice(int mode, uint32_t newDevice);
+    status_t            open(int mode);
+    status_t            close();
 
-            virtual status_t        setGain(float gain);
+private:
+    void                resetFramesLost();
 
-            virtual status_t        standby();
+    unsigned int        mFramesLost;
+    AudioSystem::audio_in_acoustics mAcoustics;
+};
 
-        private:
-            AudioSystem::audio_in_acoustics mAcoustics;
-    };
+class AudioHardwareALSA : public AudioHardwareBase
+{
+public:
+    AudioHardwareALSA();
+    virtual            ~AudioHardwareALSA();
 
-    class AudioHardwareALSA : public AudioHardwareBase
+    /**
+     * check to see if the audio hardware interface has been initialized.
+     * return status based on values defined in include/utils/Errors.h
+     */
+    virtual status_t    initCheck();
+
+    /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
+    virtual status_t    setVoiceVolume(float volume);
+
+    /**
+     * set the audio volume for all audio activities other than voice call.
+     * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
+     * the software mixer will emulate this capability.
+     */
+    virtual status_t    setMasterVolume(float volume);
+
+    /**
+     * setMode is called when the audio mode changes. NORMAL mode is for
+     * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
+     * when a call is in progress.
+     */
+    virtual status_t    setMode(int mode);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    // set/get global audio parameters
+    //virtual status_t    setParameters(const String8& keyValuePairs);
+    //virtual String8     getParameters(const String8& keys);
+
+    // Returns audio input buffer size according to parameters passed or 0 if one of the
+    // parameters is not supported
+    //virtual size_t    getInputBufferSize(uint32_t sampleRate, int format, int channels);
+
+    /** This method creates and opens the audio hardware output stream */
+    virtual AudioStreamOut* openOutputStream(
+            uint32_t devices,
+            int *format=0,
+            uint32_t *channels=0,
+            uint32_t *sampleRate=0,
+            status_t *status=0);
+    virtual    void        closeOutputStream(AudioStreamOut* out);
+
+    /** This method creates and opens the audio hardware input stream */
+    virtual AudioStreamIn* openInputStream(
+            uint32_t devices,
+            int *format,
+            uint32_t *channels,
+            uint32_t *sampleRate,
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
+    virtual    void        closeInputStream(AudioStreamIn* in);
+
+    /**This method dumps the state of the audio hardware */
+    //virtual status_t dumpState(int fd, const Vector<String16>& args);
+
+    static AudioHardwareInterface* create();
+
+    int                 mode()
     {
-        public:
-                                    AudioHardwareALSA();
-            virtual                ~AudioHardwareALSA();
-
-            /**
-             * check to see if the audio hardware interface has been initialized.
-             * return status based on values defined in include/utils/Errors.h
-             */
-            virtual status_t        initCheck();
-
-            /**
-             * put the audio hardware into standby mode to conserve power. Returns
-             * status based on include/utils/Errors.h
-             */
-            virtual status_t        standby();
-
-            /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
-            virtual status_t        setVoiceVolume(float volume);
-
-            /**
-             * set the audio volume for all audio activities other than voice call.
-             * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
-             * the software mixer will emulate this capability.
-             */
-            virtual status_t        setMasterVolume(float volume);
-
-            // mic mute
-            virtual status_t        setMicMute(bool state);
-            virtual status_t        getMicMute(bool* state);
-
-            /** This method creates and opens the audio hardware output stream */
-            virtual AudioStreamOut* openOutputStream(
-                int format=0,
-                int channelCount=0,
-                uint32_t sampleRate=0,
-                status_t *status=0);
-
-            /** This method creates and opens the audio hardware input stream */
-            virtual AudioStreamIn*  openInputStream(
-                int inputSource,
-                int format,
-                int channelCount,
-                uint32_t sampleRate,
-                status_t *status,
-                AudioSystem::audio_in_acoustics acoustics);
-
-        protected:
-            /**
-             * doRouting actually initiates the routing. A call to setRouting
-             * or setMode may result in a routing change. The generic logic calls
-             * doRouting when required. If the device has any special requirements these
-             * methods can be overriden.
-             */
-            virtual status_t    doRouting();
-
-            virtual status_t    dump(int fd, const Vector<String16>& args);
-
-            friend class AudioStreamOutALSA;
-            friend class AudioStreamInALSA;
-
-            ALSAMixer          *mMixer;
-            AudioStreamOutALSA *mOutput;
-            AudioStreamInALSA  *mInput;
-
-            acoustic_device_t *mAcousticDevice;
-
-        private:
-            Mutex               mLock;
-            bool                mPowerLock;
-    };
-
-    // ----------------------------------------------------------------------------
+        return mMode;
+    }
+
+protected:
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    friend class AudioStreamOutALSA;
+    friend class AudioStreamInALSA;
+    friend class ALSAStreamOps;
+
+    ALSAMixer *         mMixer;
+
+    alsa_device_t *     mALSADevice;
+    acoustic_device_t * mAcousticDevice;
+
+    ALSAHandleList      mDeviceList;
+
+private:
+    Mutex               mLock;
+};
+
+// ----------------------------------------------------------------------------
 
 };        // namespace android
 #endif    // ANDROID_AUDIO_HARDWARE_ALSA_H