00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef USE_ALSA09
00024
00025
00026 #include <stdio.h>
00027 #include <limits.h>
00028 #include <string.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <alsa/asoundlib.h>
00032
00033 #include "AudioA2.hh"
00034
00035
00036 static const char *cpEmptyName = "N/A";
00037
00038
00039 clAudioA2::clAudioA2 ()
00040 {
00041 sndpcmPcm = NULL;
00042 sndpcmInfo = NULL;
00043 sndpcmHwParams = NULL;
00044 sndpcmSwParams = NULL;
00045 snd_output_stdio_attach(&sndoutErr, stderr, 0);
00046 }
00047
00048
00049 clAudioA2::~clAudioA2 ()
00050 {
00051 PcmClose();
00052 CardClose();
00053 snd_output_close(sndoutErr);
00054 }
00055
00056
00057 bool clAudioA2::CardOpen (int iCard)
00058 {
00059 if (snd_card_load(iCard) != 0)
00060 return false;
00061 return true;
00062 }
00063
00064
00065 void clAudioA2::CardClose ()
00066 {
00067 }
00068
00069
00070 const char *clAudioA2::CardGetName (int iCard)
00071 {
00072 char *cpCardName;
00073
00074 if (snd_card_get_name(iCard, &cpCardName) != 0)
00075 return cpEmptyName;
00076 return cpCardName;
00077 }
00078
00079
00080 const char *clAudioA2::CardGetLongName (int iCard)
00081 {
00082 char *cpCardName;
00083
00084 if (snd_card_get_name(iCard, &cpCardName) != 0)
00085 return cpEmptyName;
00086 return cpCardName;
00087 }
00088
00089
00090 bool clAudioA2::PcmOpen (const char *cpDeviceId, snd_pcm_stream_t eMode)
00091 {
00092 if (snd_pcm_open(&sndpcmPcm, cpDeviceId, eMode, 0) != 0)
00093 return false;
00094 if (snd_pcm_info_malloc(&sndpcmInfo) != 0)
00095 return false;
00096 if (snd_pcm_info(sndpcmPcm, sndpcmInfo) != 0)
00097 return false;
00098 if (snd_pcm_hw_params_malloc(&sndpcmHwParams) != 0)
00099 return false;
00100 return true;
00101 }
00102
00103
00104 void clAudioA2::PcmClose ()
00105 {
00106 if (sndpcmSwParams != NULL)
00107 {
00108 snd_pcm_sw_params_free(sndpcmSwParams);
00109 sndpcmSwParams = NULL;
00110 }
00111 if (sndpcmHwParams != NULL)
00112 {
00113 snd_pcm_hw_params_free(sndpcmHwParams);
00114 sndpcmHwParams = NULL;
00115 }
00116 if (sndpcmInfo != NULL)
00117 {
00118 snd_pcm_info_free(sndpcmInfo);
00119 sndpcmInfo = NULL;
00120 }
00121 if (sndpcmPcm != NULL)
00122 {
00123 snd_pcm_close(sndpcmPcm);
00124 sndpcmPcm = NULL;
00125 }
00126 }
00127
00128
00129 bool clAudioA2::PcmSetSetup (int iChannels, int iSampleRate, int iBits,
00130 int iFragSize, int iFragCount)
00131 {
00132 int iDir;
00133
00134 uiFrameSize = (iBits / 8) * iChannels;
00135 snd_pcm_hw_params_any(sndpcmPcm, sndpcmHwParams);
00136
00137 if (snd_pcm_hw_params_set_access(sndpcmPcm, sndpcmHwParams,
00138 SND_PCM_ACCESS_RW_INTERLEAVED) != 0)
00139 return false;
00140 switch (iBits)
00141 {
00142 case 8:
00143 if (snd_pcm_hw_params_set_format(sndpcmPcm, sndpcmHwParams,
00144 SND_PCM_FORMAT_U8) != 0)
00145 return false;
00146 break;
00147 case 16:
00148 if (snd_pcm_hw_params_set_format(sndpcmPcm, sndpcmHwParams,
00149 SND_PCM_FORMAT_S16) != 0)
00150 return false;
00151 break;
00152 case 24:
00153 if (snd_pcm_hw_params_set_format(sndpcmPcm, sndpcmHwParams,
00154 SND_PCM_FORMAT_S24) != 0)
00155 return false;
00156 break;
00157 case 32:
00158 if (snd_pcm_hw_params_set_format(sndpcmPcm, sndpcmHwParams,
00159 SND_PCM_FORMAT_S32) != 0)
00160 return false;
00161 break;
00162
00163
00164
00165
00166
00167 default:
00168 return false;
00169 }
00170 if (snd_pcm_hw_params_set_channels(sndpcmPcm, sndpcmHwParams,
00171 iChannels) != 0)
00172 return false;
00173 iDir = 0;
00174 uiActRate = snd_pcm_hw_params_set_rate_near(sndpcmPcm, sndpcmHwParams,
00175 iSampleRate, &iDir);
00176 uiActBufSize = snd_pcm_hw_params_set_buffer_size_near(sndpcmPcm,
00177 sndpcmHwParams, iFragSize * iFragCount / uiFrameSize);
00178 uiActBufSize *= uiFrameSize;
00179 iDir = 0;
00180 uiActFragSize = snd_pcm_hw_params_set_period_size_near(sndpcmPcm,
00181 sndpcmHwParams, iFragSize / uiFrameSize, &iDir);
00182 uiActFragSize *= uiFrameSize;
00183 iDir = 0;
00184 uiActFragCount = snd_pcm_hw_params_set_periods_near(sndpcmPcm,
00185 sndpcmHwParams, iFragCount, &iDir);
00186
00187 if (snd_pcm_hw_params(sndpcmPcm, sndpcmHwParams) != 0)
00188 return false;
00189
00190 if (snd_pcm_sw_params_malloc(&sndpcmSwParams) != 0)
00191 return false;
00192 if (snd_pcm_sw_params_current(sndpcmPcm, sndpcmSwParams) != 0)
00193 return false;
00194
00195
00196
00197
00198 if (snd_pcm_sw_params_set_stop_threshold(sndpcmPcm, sndpcmSwParams,
00199 0xffffffff) != 0)
00200 return false;
00201
00202 if (snd_pcm_sw_params(sndpcmPcm, sndpcmSwParams) != 0)
00203 return false;
00204 return true;
00205 }
00206
00207
00208 int clAudioA2::PcmGetChannels ()
00209 {
00210 return snd_pcm_hw_params_get_channels(sndpcmHwParams);
00211 }
00212
00213
00214 int clAudioA2::PcmGetSampleRate ()
00215 {
00216 return ((int) uiActRate);
00217 }
00218
00219
00220 int clAudioA2::PcmGetBits ()
00221 {
00222 switch (snd_pcm_hw_params_get_format(sndpcmHwParams))
00223 {
00224 case SND_PCM_FORMAT_U8:
00225 return 8;
00226 case SND_PCM_FORMAT_S16:
00227 return 16;
00228 case SND_PCM_FORMAT_S24:
00229 return 24;
00230 case SND_PCM_FORMAT_S32:
00231 return 32;
00232
00233
00234 default:
00235 return -1;
00236 }
00237 }
00238
00239
00240 int clAudioA2::PcmGetBufferSize ()
00241 {
00242 return ((int) uiActBufSize);
00243 }
00244
00245
00246 int clAudioA2::PcmGetFragmentSize ()
00247 {
00248 return ((int) uiActFragSize);
00249 }
00250
00251
00252 int clAudioA2::PcmGetFragmentCount ()
00253 {
00254 return ((int) uiActFragCount);
00255 }
00256
00257
00258 int clAudioA2::PcmGetStatus ()
00259 {
00260 return ((int) snd_pcm_state(sndpcmPcm));
00261 }
00262
00263
00264 const char *clAudioA2::PcmGetStatusStr (int iStatusCode)
00265 {
00266 snd_pcm_state_t iState;
00267
00268 iState = snd_pcm_state(sndpcmPcm);
00269 return snd_pcm_state_name(iState);
00270 }
00271
00272
00273 const char *clAudioA2::PcmGetName ()
00274 {
00275 return snd_pcm_info_get_name(sndpcmInfo);
00276 }
00277
00278
00279 bool clAudioA2::PcmLink (clAudioA2 &Device)
00280 {
00281 if (snd_pcm_link(sndpcmPcm, Device.GetPcmHandle()) != 0)
00282 return false;
00283 return true;
00284 }
00285
00286
00287 bool clAudioA2::PcmUnlink ()
00288 {
00289 if (snd_pcm_unlink(sndpcmPcm) != 0)
00290 return false;
00291 return true;
00292 }
00293
00294
00295 bool clAudioA2::PcmPrepare ()
00296 {
00297 if (snd_pcm_prepare(sndpcmPcm) != 0)
00298 return false;
00299 return true;
00300 }
00301
00302
00303 bool clAudioA2::PcmStart ()
00304 {
00305 if (snd_pcm_start(sndpcmPcm) != 0)
00306 return false;
00307 return true;
00308 }
00309
00310
00311 bool clAudioA2::PcmReset ()
00312 {
00313 if (snd_pcm_reset(sndpcmPcm) != 0)
00314 return false;
00315 return true;
00316 }
00317
00318
00319 bool clAudioA2::PcmDrain ()
00320 {
00321 if (snd_pcm_drain(sndpcmPcm) != 0)
00322 return false;
00323 return true;
00324 }
00325
00326
00327 int clAudioA2::PcmRead (void *vpBuffer, int iBufSize)
00328 {
00329 int iReadSize;
00330
00331 iReadSize = snd_pcm_readi(sndpcmPcm, vpBuffer, iBufSize / uiFrameSize);
00332 if (iReadSize < 0)
00333 return iReadSize;
00334 return (iReadSize * uiFrameSize);
00335 }
00336
00337
00338 int clAudioA2::PcmWrite (const void *vpBuffer, int iBufSize)
00339 {
00340 int iWriteSize;
00341
00342 iWriteSize = snd_pcm_writei(sndpcmPcm, vpBuffer, iBufSize / uiFrameSize);
00343 if (iWriteSize < 0)
00344 return iWriteSize;
00345 return (iWriteSize * uiFrameSize);
00346 }
00347
00348 #endif // USE_ALSA09