alsa.h
1/*
2 * Player - One Hell of a Robot Server
3 * Copyright (C) 2003
4 * Brian Gerkey
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include <alsa/asoundlib.h>
24
25#include "audio_sample.h"
26
28// Describes a prestored sample for playing with PLAYER_AUDIO_CMD_SAMPLE_PLAY
29typedef struct StoredSample
30{
31 AudioSample *sample;
32 int index; // Index of sample
33 struct StoredSample *next; // Next sample in the linked list
35
37// An item on the queue of waves to play
38typedef struct QueueItem
39{
40 AudioSample *sample; // Audio sample at this position in the queue
41 bool temp; // If true, the AudioSample will be deleted after playback completes
42 struct QueueItem *next; // Next item in the queue
43} QueueItem;
44
46// Capabilities of a mixer element
47typedef uint32_t ElemCap;
48const ElemCap ELEMCAP_CAN_PLAYBACK = 0x0001;
49const ElemCap ELEMCAP_CAN_CAPTURE = 0x0002;
50const ElemCap ELEMCAP_COMMON = 0x0004; // Has a single volume control for both playback and record
51const ElemCap ELEMCAP_PLAYBACK_VOL = 0x0008;
52const ElemCap ELEMCAP_CAPTURE_VOL = 0x0010;
53const ElemCap ELEMCAP_COMMON_VOL = 0x0020;
54const ElemCap ELEMCAP_PLAYBACK_SWITCH = 0x0040;
55const ElemCap ELEMCAP_CAPTURE_SWITCH = 0x0080;
56const ElemCap ELEMCAP_COMMON_SWITCH = 0x0100;
57// const ElemCap ELEMCAP_PB_JOINED_SWITCH = 0x0200;
58// const ElemCap ELEMCAP_CAP_JOINED_SWITCH = 0x0400;
59
60// Describes an ALSA mixer element
61typedef struct MixerElement
62{
63 snd_mixer_elem_t *elem; // ALSA Mixer element structure
64 long minPlayVol, curPlayVol, maxPlayVol; // min, current and max volume levels for playback
65 long minCapVol, curCapVol, maxCapVol; // min, current and max volume levels for capture
66 long minComVol, curComVol, maxComVol; // min, current and max volume levels for common
67 int playSwitch, capSwitch, comSwitch; // Current switch status
68 char *name; // Name of the element
69 ElemCap caps; // Capabilities
71
73// State of the playback system
74typedef uint8_t PBState;
75const PBState PB_STATE_STOPPED = 0; // Not playing anything
76const PBState PB_STATE_PLAYING = 1; // Playing
77const PBState PB_STATE_DRAIN = 2; // Draining current wave
78const PBState PB_STATE_RECORDING = 3; // Recording
79
81// The class for the driver
82class Alsa : public ThreadedDriver
83{
84 public:
85 Alsa (ConfigFile* cf, int section);
86 ~Alsa (void);
87
88 virtual int ProcessMessage (QueuePointer &resp_queue, player_msghdr *hdr, void *data);
89
90 private:
91 // Driver options
92 bool useQueue; // If should use a queue for playback or just stop currently playing
93 uint8_t debugLevel; // Debug info level
94 char **mixerFilters; // Null-terminated array of strings to filter mixer elements by
95 bool mixerFilterExact; // If mixer filters need to match element names exactly
96 char *pbDevice; // Name of the playback device
97 char *mixerDevice; // Name of the mixer device
98 char *recDevice; // Name of the record device
99 uint32_t cfgPBPeriodTime; // Length of a playback period in milliseconds
100 uint32_t cfgPBBufferTime; // Length of the playback buffer in milliseconds
101 uint32_t silenceTime; // Length of silence to put between samples in the queue
102 uint32_t cfgRecBufferTime; // Length of the record buffer in milliseconds
103 uint32_t cfgRecStoreTime; // Length of time to store recorded data before sending to clients
104 uint32_t cfgRecPeriodTime; // Length of a record period in milliseconds
105 uint8_t recNumChannels; // Number of channels for recording
106 uint32_t recSampleRate; // Sample rate for recording
107 uint8_t recBits; // Sample bits per frame for recording
108
109 // ALSA variables
110 // Playback
111 snd_pcm_t *pbHandle; // Handle to the PCM device for playback
112 int numPBFDs; // Number of playback file descriptors
113 struct pollfd *pbFDs; // Playback file descriptors for polling
114 uint32_t actPBBufferTime; // Length of the playback buffer in microseconds (actual value)
115 uint32_t actPBPeriodTime; // Length of a playback period in microseconds (actual value)
116 snd_pcm_uframes_t pbPeriodSize; // Size of a playback period (used for filling the buffer)
117 uint8_t *periodBuffer; // A buffer used to copy data from samples to the playback buffer
118 // Record
119 snd_pcm_t *recHandle; // Handle to the PCM device for recording
120 int numRecFDs; // Number of record file descriptors
121 struct pollfd *recFDs; // Record file descriptors for polling
122 uint32_t actRecBufferTime; // Length of the record buffer in microseconds (actual value)
123 uint32_t actRecPeriodTime; // Length of a record period in microseconds (actual value)
124 snd_pcm_uframes_t recPeriodSize; // Size of a record period (used for filling the buffer)
125 // Mixer
126 snd_mixer_t *mixerHandle; // Mixer for controlling volume levels
127 MixerElement *mixerElements; // Elements of the mixer
128 uint32_t numElements; // Number of elements
129
130 // Other driver data
131 int nextSampleIdx; // Next free index to store a sample at
132 StoredSample *samplesHead, *samplesTail; // Stored samples
133 QueueItem *queueHead, *queueTail; // Queue of audio data waiting to play
134 PBState playState; // Playback state
135 PBState recState; // Record state
136 uint32_t recDataLength; // Length of recorded data buffer (in bytes)
137 uint32_t recDataOffset; // Current end of recorded data in recData
138 uint8_t *recData; // Somewhere to store recorded data before it goes to the client
139 int recDest; // Destination of recorded data: -ve for to clients via data packets,
140 // >=0 for to stored sample at that index
141
142 // Internal functions
143 virtual void Main (void);
144 virtual int MainSetup (void);
145 virtual void MainQuit (void);
146 void SendStateMessage (void);
147
148 // Stored sample functions
149 bool AddStoredSample (StoredSample *newSample);
150 bool AddStoredSample (player_audio_wav_t *waveData);
151 bool AddStoredSample (const char *filePath);
152 StoredSample* GetSampleAtIndex (int index);
153
154 // Queue functions
155 void ClearQueue (void);
156 bool AddToQueue (QueueItem *newItem);
157 bool AddToQueue (player_audio_wav_t *waveData);
158 bool AddToQueue (AudioSample *sample);
159 bool AddSilence (uint32_t time, AudioSample *format);
160 void AdvanceQueue (void);
161
162 // Playback functions
163// bool SetGeneralParams (void);
164// bool SetWaveHWParams (AudioSample *sample);
165 bool SetupPlayBack (void);
166 bool SetPBParams (AudioSample *sample);
167 void PlaybackCallback (int numFrames);
168
169 // Record functions
170 bool SetupRecord (void);
171 bool SetRecParams (void);
172 bool SetupRecordBuffer (uint32_t length);
173 void RecordCallback (int numFrames);
174 void HandleRecordedData (void);
175 void PublishRecordedData (void);
176
177 // Playback/record control functions
178 void StartPlayback (void);
179 void StopPlayback (void);
180 void StartRecording (void);
181 void StopRecording (void);
182
183 // Mixer functions
184 bool SetupMixer (void);
185 bool EnumMixerElements (void);
186 bool EnumElementCaps (MixerElement *element);
187 MixerElement* SplitElements (MixerElement *elements, uint32_t &count);
188 MixerElement* FilterElements (MixerElement *elements, uint32_t &count);
189 void CleanUpMixerElements (MixerElement *elements, uint32_t count);
190 void MixerDetailsToPlayer (player_audio_mixer_channel_list_detail_t *dest);
191 void MixerLevelsToPlayer (player_audio_mixer_channel_list_t *dest);
192 void SetElementLevel (uint32_t index, float level);
193 void SetElementSwitch (uint32_t index, player_bool_t active);
194 void PublishMixerData (void);
195 float LevelToPlayer (long min, long max, long level);
196 long LevelFromPlayer (long min, long max, float level);
197 void PrintMixerElements (MixerElement *elements, uint32_t count);
198
199 // Command and request handling
200 int HandleWavePlayCmd (player_audio_wav_t *waveData);
201 int HandleSamplePlayCmd (player_audio_sample_item_t *data);
202 int HandleRecordCmd (player_bool_t *data);
203 int HandleMixerChannelCmd (player_audio_mixer_channel_list_t *data);
204 int HandleSampleLoadReq (player_audio_sample_t *data, QueuePointer &resp_queue);
205 int HandleSampleRetrieveReq (player_audio_sample_t *data, QueuePointer &resp_queue);
206 int HandleSampleRecordReq (player_audio_sample_rec_req_t *data, QueuePointer &resp_queue);
207 int HandleMixerChannelListReq (player_audio_mixer_channel_list_detail_t *data, QueuePointer &resp_queue);
208 int HandleMixerChannelLevelReq (player_audio_mixer_channel_list_t *data, QueuePointer &resp_queue);
209};
Definition alsa.h:83
virtual void Main(void)
Main method for driver thread.
Definition alsa.cc:2257
virtual int MainSetup(void)
Sets up the resources needed by the driver thread.
Definition alsa.cc:2156
virtual void MainQuit(void)
Cleanup method for driver thread (called when main exits)
Definition alsa.cc:2197
virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr *hdr, void *data)
Message handler.
Definition alsa.cc:2575
Definition audio_sample.h:33
Class for loading configuration file information.
Definition configfile.h:197
An autopointer for the message queue.
Definition message.h:74
Base class for drivers which oeprate with a thread.
Definition driver.h:553
Definition alsa.h:62
Definition alsa.h:39
Definition alsa.h:30
A boolean variable, 0 for false anything else for true.
Definition player.h:334
Generic message header.
Definition player.h:162