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 ThreadedDriver 00083 { 00084 public: 00085 Alsa (ConfigFile* cf, int section); 00086 ~Alsa (void); 00087 00088 virtual int ProcessMessage (QueuePointer &resp_queue, player_msghdr *hdr, void *data); 00089 00090 private: 00091 // Driver options 00092 bool useQueue; // If should use a queue for playback or just stop currently playing 00093 uint8_t debugLevel; // Debug info level 00094 char **mixerFilters; // Null-terminated array of strings to filter mixer elements by 00095 bool mixerFilterExact; // If mixer filters need to match element names exactly 00096 char *pbDevice; // Name of the playback device 00097 char *mixerDevice; // Name of the mixer device 00098 char *recDevice; // Name of the record device 00099 uint32_t cfgPBPeriodTime; // Length of a playback period in milliseconds 00100 uint32_t cfgPBBufferTime; // Length of the playback buffer in milliseconds 00101 uint32_t silenceTime; // Length of silence to put between samples in the queue 00102 uint32_t cfgRecBufferTime; // Length of the record buffer in milliseconds 00103 uint32_t cfgRecStoreTime; // Length of time to store recorded data before sending to clients 00104 uint32_t cfgRecPeriodTime; // Length of a record period in milliseconds 00105 uint8_t recNumChannels; // Number of channels for recording 00106 uint32_t recSampleRate; // Sample rate for recording 00107 uint8_t recBits; // Sample bits per frame for recording 00108 00109 // ALSA variables 00110 // Playback 00111 snd_pcm_t *pbHandle; // Handle to the PCM device for playback 00112 int numPBFDs; // Number of playback file descriptors 00113 struct pollfd *pbFDs; // Playback file descriptors for polling 00114 uint32_t actPBBufferTime; // Length of the playback buffer in microseconds (actual value) 00115 uint32_t actPBPeriodTime; // Length of a playback period in microseconds (actual value) 00116 snd_pcm_uframes_t pbPeriodSize; // Size of a playback period (used for filling the buffer) 00117 uint8_t *periodBuffer; // A buffer used to copy data from samples to the playback buffer 00118 // Record 00119 snd_pcm_t *recHandle; // Handle to the PCM device for recording 00120 int numRecFDs; // Number of record file descriptors 00121 struct pollfd *recFDs; // Record file descriptors for polling 00122 uint32_t actRecBufferTime; // Length of the record buffer in microseconds (actual value) 00123 uint32_t actRecPeriodTime; // Length of a record period in microseconds (actual value) 00124 snd_pcm_uframes_t recPeriodSize; // Size of a record period (used for filling the buffer) 00125 // Mixer 00126 snd_mixer_t *mixerHandle; // Mixer for controlling volume levels 00127 MixerElement *mixerElements; // Elements of the mixer 00128 uint32_t numElements; // Number of elements 00129 00130 // Other driver data 00131 int nextSampleIdx; // Next free index to store a sample at 00132 StoredSample *samplesHead, *samplesTail; // Stored samples 00133 QueueItem *queueHead, *queueTail; // Queue of audio data waiting to play 00134 PBState playState; // Playback state 00135 PBState recState; // Record state 00136 uint32_t recDataLength; // Length of recorded data buffer (in bytes) 00137 uint32_t recDataOffset; // Current end of recorded data in recData 00138 uint8_t *recData; // Somewhere to store recorded data before it goes to the client 00139 int recDest; // Destination of recorded data: -ve for to clients via data packets, 00140 // >=0 for to stored sample at that index 00141 00142 // Internal functions 00143 virtual void Main (void); 00144 virtual int MainSetup (void); 00145 virtual void MainQuit (void); 00146 void SendStateMessage (void); 00147 00148 // Stored sample functions 00149 bool AddStoredSample (StoredSample *newSample); 00150 bool AddStoredSample (player_audio_wav_t *waveData); 00151 bool AddStoredSample (const char *filePath); 00152 StoredSample* GetSampleAtIndex (int index); 00153 00154 // Queue functions 00155 void ClearQueue (void); 00156 bool AddToQueue (QueueItem *newItem); 00157 bool AddToQueue (player_audio_wav_t *waveData); 00158 bool AddToQueue (AudioSample *sample); 00159 bool AddSilence (uint32_t time, AudioSample *format); 00160 void AdvanceQueue (void); 00161 00162 // Playback functions 00163 // bool SetGeneralParams (void); 00164 // bool SetWaveHWParams (AudioSample *sample); 00165 bool SetupPlayBack (void); 00166 bool SetPBParams (AudioSample *sample); 00167 void PlaybackCallback (int numFrames); 00168 00169 // Record functions 00170 bool SetupRecord (void); 00171 bool SetRecParams (void); 00172 bool SetupRecordBuffer (uint32_t length); 00173 void RecordCallback (int numFrames); 00174 void HandleRecordedData (void); 00175 void PublishRecordedData (void); 00176 00177 // Playback/record control functions 00178 void StartPlayback (void); 00179 void StopPlayback (void); 00180 void StartRecording (void); 00181 void StopRecording (void); 00182 00183 // Mixer functions 00184 bool SetupMixer (void); 00185 bool EnumMixerElements (void); 00186 bool EnumElementCaps (MixerElement *element); 00187 MixerElement* SplitElements (MixerElement *elements, uint32_t &count); 00188 MixerElement* FilterElements (MixerElement *elements, uint32_t &count); 00189 void CleanUpMixerElements (MixerElement *elements, uint32_t count); 00190 void MixerDetailsToPlayer (player_audio_mixer_channel_list_detail_t *dest); 00191 void MixerLevelsToPlayer (player_audio_mixer_channel_list_t *dest); 00192 void SetElementLevel (uint32_t index, float level); 00193 void SetElementSwitch (uint32_t index, player_bool_t active); 00194 void PublishMixerData (void); 00195 float LevelToPlayer (long min, long max, long level); 00196 long LevelFromPlayer (long min, long max, float level); 00197 void PrintMixerElements (MixerElement *elements, uint32_t count); 00198 00199 // Command and request handling 00200 int HandleWavePlayCmd (player_audio_wav_t *waveData); 00201 int HandleSamplePlayCmd (player_audio_sample_item_t *data); 00202 int HandleRecordCmd (player_bool_t *data); 00203 int HandleMixerChannelCmd (player_audio_mixer_channel_list_t *data); 00204 int HandleSampleLoadReq (player_audio_sample_t *data, QueuePointer &resp_queue); 00205 int HandleSampleRetrieveReq (player_audio_sample_t *data, QueuePointer &resp_queue); 00206 int HandleSampleRecordReq (player_audio_sample_rec_req_t *data, QueuePointer &resp_queue); 00207 int HandleMixerChannelListReq (player_audio_mixer_channel_list_detail_t *data, QueuePointer &resp_queue); 00208 int HandleMixerChannelLevelReq (player_audio_mixer_channel_list_t *data, QueuePointer &resp_queue); 00209 };