alsa.h

00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2003
00004  *     Brian Gerkey
00005  *
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 
00023 #include <alsa/asoundlib.h>
00024 
00025 #include "audio_sample.h"
00026 
00028 // Describes a prestored sample for playing with PLAYER_AUDIO_CMD_SAMPLE_PLAY
00029 typedef struct StoredSample
00030 {
00031         AudioSample *sample;
00032         int index;                                      // Index of sample
00033         struct StoredSample *next;      // Next sample in the linked list
00034 } StoredSample;
00035 
00037 // An item on the queue of waves to play
00038 typedef struct QueueItem
00039 {
00040         AudioSample *sample;    // Audio sample at this position in the queue
00041         bool temp;                              // If true, the AudioSample will be deleted after playback completes
00042         struct QueueItem *next; // Next item in the queue
00043 } QueueItem;
00044 
00046 // Capabilities of a mixer element
00047 typedef uint32_t ElemCap;
00048 const ElemCap ELEMCAP_CAN_PLAYBACK              = 0x0001;
00049 const ElemCap ELEMCAP_CAN_CAPTURE               = 0x0002;
00050 const ElemCap ELEMCAP_COMMON                    = 0x0004;       // Has a single volume control for both playback and record
00051 const ElemCap ELEMCAP_PLAYBACK_VOL              = 0x0008;
00052 const ElemCap ELEMCAP_CAPTURE_VOL               = 0x0010;
00053 const ElemCap ELEMCAP_COMMON_VOL                = 0x0020;
00054 const ElemCap ELEMCAP_PLAYBACK_SWITCH   = 0x0040;
00055 const ElemCap ELEMCAP_CAPTURE_SWITCH    = 0x0080;
00056 const ElemCap ELEMCAP_COMMON_SWITCH             = 0x0100;
00057 // const ElemCap ELEMCAP_PB_JOINED_SWITCH       = 0x0200;
00058 // const ElemCap ELEMCAP_CAP_JOINED_SWITCH      = 0x0400;
00059 
00060 // Describes an ALSA mixer element
00061 typedef struct MixerElement
00062 {
00063         snd_mixer_elem_t *elem;                 // ALSA Mixer element structure
00064         long minPlayVol, curPlayVol, maxPlayVol;        // min, current and max volume levels for playback
00065         long minCapVol, curCapVol, maxCapVol;           // min, current and max volume levels for capture
00066         long minComVol, curComVol, maxComVol;           // min, current and max volume levels for common
00067         int playSwitch, capSwitch, comSwitch;           // Current switch status
00068         char *name;                                             // Name of the element
00069         ElemCap caps;                                   // Capabilities
00070 } MixerElement;
00071 
00073 // State of the playback system
00074 typedef uint8_t PBState;
00075 const PBState PB_STATE_STOPPED          = 0;    // Not playing anything
00076 const PBState PB_STATE_PLAYING          = 1;    // Playing
00077 const PBState PB_STATE_DRAIN            = 2;    // Draining current wave
00078 const PBState PB_STATE_RECORDING        = 3;    // Recording
00079 
00081 // The class for the driver
00082 class Alsa : public Driver
00083 {
00084         public:
00085                 Alsa (ConfigFile* cf, int section);
00086                 ~Alsa (void);
00087 
00088                 virtual int Setup (void);
00089                 virtual int Shutdown (void);
00090 
00091                 virtual int ProcessMessage (QueuePointer &resp_queue, player_msghdr *hdr, void *data);
00092 
00093         private:
00094                 // Driver options
00095                 bool useQueue;                                  // If should use a queue for playback or just stop currently playing
00096                 uint8_t debugLevel;                             // Debug info level
00097                 char **mixerFilters;                    // Null-terminated array of strings to filter mixer elements by
00098                 bool mixerFilterExact;                  // If mixer filters need to match element names exactly
00099                 char *pbDevice;                                 // Name of the playback device
00100                 char *mixerDevice;                              // Name of the mixer device
00101                 char *recDevice;                                // Name of the record device
00102                 uint32_t cfgPBPeriodTime;               // Length of a playback period in milliseconds
00103                 uint32_t cfgPBBufferTime;               // Length of the playback buffer in milliseconds
00104                 uint32_t silenceTime;                   // Length of silence to put between samples in the queue
00105                 uint32_t cfgRecBufferTime;              // Length of the record buffer in milliseconds
00106                 uint32_t cfgRecStoreTime;               // Length of time to store recorded data before sending to clients
00107                 uint32_t cfgRecPeriodTime;              // Length of a record period in milliseconds
00108                 uint8_t recNumChannels;                 // Number of channels for recording
00109                 uint32_t recSampleRate;                 // Sample rate for recording
00110                 uint8_t recBits;                                // Sample bits per frame for recording
00111 
00112                 // ALSA variables
00113                 // Playback
00114                 snd_pcm_t *pbHandle;                    // Handle to the PCM device for playback
00115                 int numPBFDs;                                   // Number of playback file descriptors
00116                 struct pollfd *pbFDs;                   // Playback file descriptors for polling
00117                 uint32_t actPBBufferTime;               // Length of the playback buffer in microseconds (actual value)
00118                 uint32_t actPBPeriodTime;               // Length of a playback period in microseconds (actual value)
00119                 snd_pcm_uframes_t pbPeriodSize; // Size of a playback period (used for filling the buffer)
00120                 uint8_t *periodBuffer;                  // A buffer used to copy data from samples to the playback buffer
00121                 // Record
00122                 snd_pcm_t *recHandle;                   // Handle to the PCM device for recording
00123                 int numRecFDs;                                  // Number of record file descriptors
00124                 struct pollfd *recFDs;                  // Record file descriptors for polling
00125                 uint32_t actRecBufferTime;              // Length of the record buffer in microseconds (actual value)
00126                 uint32_t actRecPeriodTime;              // Length of a record period in microseconds (actual value)
00127                 snd_pcm_uframes_t recPeriodSize;        // Size of a record period (used for filling the buffer)
00128                 // Mixer
00129                 snd_mixer_t *mixerHandle;               // Mixer for controlling volume levels
00130                 MixerElement *mixerElements;    // Elements of the mixer
00131                 uint32_t numElements;                   // Number of elements
00132 
00133                 // Other driver data
00134                 int nextSampleIdx;                              // Next free index to store a sample at
00135                 StoredSample *samplesHead, *samplesTail;        // Stored samples
00136                 QueueItem *queueHead, *queueTail;       // Queue of audio data waiting to play
00137                 PBState playState;                              // Playback state
00138                 PBState recState;                               // Record state
00139                 uint32_t recDataLength;                 // Length of recorded data buffer (in bytes)
00140                 uint32_t recDataOffset;                 // Current end of recorded data in recData
00141                 uint8_t *recData;                               // Somewhere to store recorded data before it goes to the client
00142                 int recDest;                                    // Destination of recorded data: -ve for to clients via data packets,
00143                                                                                 // >=0 for to stored sample at that index
00144 
00145                 // Internal functions
00146                 virtual void Main (void);
00147                 void SendStateMessage (void);
00148 
00149                 // Stored sample functions
00150                 bool AddStoredSample (StoredSample *newSample);
00151                 bool AddStoredSample (player_audio_wav_t *waveData);
00152                 bool AddStoredSample (const char *filePath);
00153                 StoredSample* GetSampleAtIndex (int index);
00154 
00155                 // Queue functions
00156                 void ClearQueue (void);
00157                 bool AddToQueue (QueueItem *newItem);
00158                 bool AddToQueue (player_audio_wav_t *waveData);
00159                 bool AddToQueue (AudioSample *sample);
00160                 bool AddSilence (uint32_t time, AudioSample *format);
00161                 void AdvanceQueue (void);
00162 
00163                 // Playback functions
00164 //              bool SetGeneralParams (void);
00165 //              bool SetWaveHWParams (AudioSample *sample);
00166                 bool SetupPlayBack (void);
00167                 bool SetPBParams (AudioSample *sample);
00168                 void PlaybackCallback (int numFrames);
00169 
00170                 // Record functions
00171                 bool SetupRecord (void);
00172                 bool SetRecParams (void);
00173                 bool SetupRecordBuffer (uint32_t length);
00174                 void RecordCallback (int numFrames);
00175                 void HandleRecordedData (void);
00176                 void PublishRecordedData (void);
00177 
00178                 // Playback/record control functions
00179                 void StartPlayback (void);
00180                 void StopPlayback (void);
00181                 void StartRecording (void);
00182                 void StopRecording (void);
00183 
00184                 // Mixer functions
00185                 bool SetupMixer (void);
00186                 bool EnumMixerElements (void);
00187                 bool EnumElementCaps (MixerElement *element);
00188                 MixerElement* SplitElements (MixerElement *elements, uint32_t &count);
00189                 MixerElement* FilterElements (MixerElement *elements, uint32_t &count);
00190                 void CleanUpMixerElements (MixerElement *elements, uint32_t count);
00191                 void MixerDetailsToPlayer (player_audio_mixer_channel_list_detail_t *dest);
00192                 void MixerLevelsToPlayer (player_audio_mixer_channel_list_t *dest);
00193                 void SetElementLevel (uint32_t index, float level);
00194                 void SetElementSwitch (uint32_t index, player_bool_t active);
00195                 void PublishMixerData (void);
00196                 float LevelToPlayer (long min, long max, long level);
00197                 long LevelFromPlayer (long min, long max, float level);
00198                 void PrintMixerElements (MixerElement *elements, uint32_t count);
00199 
00200                 // Command and request handling
00201                 int HandleWavePlayCmd (player_audio_wav_t *waveData);
00202                 int HandleSamplePlayCmd (player_audio_sample_item_t *data);
00203                 int HandleRecordCmd (player_bool_t *data);
00204                 int HandleMixerChannelCmd (player_audio_mixer_channel_list_t *data);
00205                 int HandleSampleLoadReq (player_audio_sample_t *data, QueuePointer &resp_queue);
00206                 int HandleSampleRetrieveReq (player_audio_sample_t *data, QueuePointer &resp_queue);
00207                 int HandleSampleRecordReq (player_audio_sample_rec_req_t *data, QueuePointer &resp_queue);
00208                 int HandleMixerChannelListReq (player_audio_mixer_channel_list_detail_t *data, QueuePointer &resp_queue);
00209                 int HandleMixerChannelLevelReq (player_audio_mixer_channel_list_t *data, QueuePointer &resp_queue);
00210 };

Last updated 12 September 2005 21:38:45