cmAudioPortAlsa.c : Added _cmApDevReportFormats().
Added, but disabled, _cmApS24_3BE*(). Added i/oSignFl and i/oSwapFl to device record. Changed sample format selection algorithm to use fmt[].
This commit is contained in:
parent
ba5cd463f0
commit
f48cc2e7f7
@ -40,11 +40,17 @@ typedef struct devRecd_str
|
|||||||
snd_async_handler_t* ahandler;
|
snd_async_handler_t* ahandler;
|
||||||
unsigned srate; // device sample rate
|
unsigned srate; // device sample rate
|
||||||
|
|
||||||
unsigned iChCnt; // ch count
|
unsigned iChCnt; // ch count
|
||||||
unsigned oChCnt;
|
unsigned oChCnt;
|
||||||
|
|
||||||
unsigned iBits; // bits per sample
|
unsigned iBits; // bits per sample
|
||||||
unsigned oBits;
|
unsigned oBits;
|
||||||
|
|
||||||
|
bool iSignFl; // sample type is signed
|
||||||
|
bool oSignFl;
|
||||||
|
|
||||||
|
bool iSwapFl; // swap the sample bytes
|
||||||
|
bool oSwapFl;
|
||||||
|
|
||||||
unsigned iSigBits; // significant bits in each sample beginning
|
unsigned iSigBits; // significant bits in each sample beginning
|
||||||
unsigned oSigBits; // with the most sig. bit.
|
unsigned oSigBits; // with the most sig. bit.
|
||||||
@ -362,6 +368,77 @@ void _cmApDevRtReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmApDevReportFormats( cmRpt_t* rpt, snd_pcm_hw_params_t* hwParams )
|
||||||
|
{
|
||||||
|
snd_pcm_format_mask_t* mask;
|
||||||
|
|
||||||
|
snd_pcm_format_t fmt[] =
|
||||||
|
{
|
||||||
|
SND_PCM_FORMAT_S8,
|
||||||
|
SND_PCM_FORMAT_U8,
|
||||||
|
SND_PCM_FORMAT_S16_LE,
|
||||||
|
SND_PCM_FORMAT_S16_BE,
|
||||||
|
SND_PCM_FORMAT_U16_LE,
|
||||||
|
SND_PCM_FORMAT_U16_BE,
|
||||||
|
SND_PCM_FORMAT_S24_LE,
|
||||||
|
SND_PCM_FORMAT_S24_BE,
|
||||||
|
SND_PCM_FORMAT_U24_LE,
|
||||||
|
SND_PCM_FORMAT_U24_BE,
|
||||||
|
SND_PCM_FORMAT_S32_LE,
|
||||||
|
SND_PCM_FORMAT_S32_BE,
|
||||||
|
SND_PCM_FORMAT_U32_LE,
|
||||||
|
SND_PCM_FORMAT_U32_BE,
|
||||||
|
SND_PCM_FORMAT_FLOAT_LE,
|
||||||
|
SND_PCM_FORMAT_FLOAT_BE,
|
||||||
|
SND_PCM_FORMAT_FLOAT64_LE,
|
||||||
|
SND_PCM_FORMAT_FLOAT64_BE,
|
||||||
|
SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
|
||||||
|
SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
|
||||||
|
SND_PCM_FORMAT_MU_LAW,
|
||||||
|
SND_PCM_FORMAT_A_LAW,
|
||||||
|
SND_PCM_FORMAT_IMA_ADPCM,
|
||||||
|
SND_PCM_FORMAT_MPEG,
|
||||||
|
SND_PCM_FORMAT_GSM,
|
||||||
|
SND_PCM_FORMAT_SPECIAL,
|
||||||
|
SND_PCM_FORMAT_S24_3LE,
|
||||||
|
SND_PCM_FORMAT_S24_3BE,
|
||||||
|
SND_PCM_FORMAT_U24_3LE,
|
||||||
|
SND_PCM_FORMAT_U24_3BE,
|
||||||
|
SND_PCM_FORMAT_S20_3LE,
|
||||||
|
SND_PCM_FORMAT_S20_3BE,
|
||||||
|
SND_PCM_FORMAT_U20_3LE,
|
||||||
|
SND_PCM_FORMAT_U20_3BE,
|
||||||
|
SND_PCM_FORMAT_S18_3LE,
|
||||||
|
SND_PCM_FORMAT_S18_3BE,
|
||||||
|
SND_PCM_FORMAT_U18_3LE,
|
||||||
|
SND_PCM_FORMAT_U18_3BE,
|
||||||
|
SND_PCM_FORMAT_G723_24,
|
||||||
|
SND_PCM_FORMAT_G723_24_1B,
|
||||||
|
SND_PCM_FORMAT_G723_40,
|
||||||
|
SND_PCM_FORMAT_G723_40_1B,
|
||||||
|
SND_PCM_FORMAT_DSD_U8,
|
||||||
|
//SND_PCM_FORMAT_DSD_U16_LE,
|
||||||
|
//SND_PCM_FORMAT_DSD_U32_LE,
|
||||||
|
//SND_PCM_FORMAT_DSD_U16_BE,
|
||||||
|
//SND_PCM_FORMAT_DSD_U32_BE,
|
||||||
|
SND_PCM_FORMAT_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
snd_pcm_format_mask_alloca(&mask);
|
||||||
|
|
||||||
|
snd_pcm_hw_params_get_format_mask(hwParams,mask);
|
||||||
|
|
||||||
|
cmRptPrintf(rpt,"Formats: " );
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i=0; fmt[i]!=SND_PCM_FORMAT_UNKNOWN; ++i)
|
||||||
|
if( snd_pcm_format_mask_test(mask, fmt[i] ))
|
||||||
|
cmRptPrintf(rpt,"%s%s",snd_pcm_format_name(fmt[i]), snd_pcm_format_cpu_endian(fmt[i]) ? " " : " (swap) ");
|
||||||
|
|
||||||
|
cmRptPrintf(rpt,"\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
|
void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
|
||||||
{
|
{
|
||||||
bool inputFl = true;
|
bool inputFl = true;
|
||||||
@ -377,7 +454,7 @@ void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
|
|||||||
{
|
{
|
||||||
if( ((inputFl==true) && (drp->flags&kInFl)) || (((inputFl==false) && (drp->flags&kOutFl))))
|
if( ((inputFl==true) && (drp->flags&kInFl)) || (((inputFl==false) && (drp->flags&kOutFl))))
|
||||||
{
|
{
|
||||||
const char* ioLabel = inputFl ? "In" : "Out";
|
const char* ioLabel = inputFl ? "In " : "Out";
|
||||||
|
|
||||||
// attempt to open the sub-device
|
// attempt to open the sub-device
|
||||||
if((err = snd_pcm_open(&pcmH,drp->nameStr,inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,0)) < 0 )
|
if((err = snd_pcm_open(&pcmH,drp->nameStr,inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,0)) < 0 )
|
||||||
@ -435,6 +512,8 @@ void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
|
|||||||
ioLabel,minChCnt,maxChCnt,minSrate,maxSrate,minPeriodFrmCnt,maxPeriodFrmCnt,minBufFrmCnt,maxBufFrmCnt,
|
ioLabel,minChCnt,maxChCnt,minSrate,maxSrate,minPeriodFrmCnt,maxPeriodFrmCnt,minBufFrmCnt,maxBufFrmCnt,
|
||||||
(snd_pcm_hw_params_is_half_duplex(hwParams) ? "yes" : "no"),
|
(snd_pcm_hw_params_is_half_duplex(hwParams) ? "yes" : "no"),
|
||||||
(snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no"));
|
(snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no"));
|
||||||
|
|
||||||
|
_cmApDevReportFormats( rpt, hwParams );
|
||||||
}
|
}
|
||||||
|
|
||||||
if((err = snd_pcm_close(pcmH)) < 0)
|
if((err = snd_pcm_close(pcmH)) < 0)
|
||||||
@ -610,6 +689,28 @@ void _cmApStateRecover( snd_pcm_t* pcmH, cmApDevRecd_t* drp, bool inputFl )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmApS24_3BE_to_Float( const char* x, cmApSample_t* y, unsigned n )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<n; ++i,x+=3)
|
||||||
|
{
|
||||||
|
int s = (((int)x[0])<<16) + (((int)x[1])<<8) + (((int)x[2]));
|
||||||
|
y[i] = ((cmApSample_t)s)/0x7fffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cmApS24_3BE_from_Float( const cmApSample_t* x, char* y, unsigned n )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<n; ++i)
|
||||||
|
{
|
||||||
|
int s = x[i] * 0x7fffff;
|
||||||
|
y[i*3+2] = (char)((s & 0x7f0000) >> 16);
|
||||||
|
y[i*3+1] = (char)((s & 0x00ff00) >> 8);
|
||||||
|
y[i*3+0] = (char)((s & 0x0000ff) >> 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns count of frames written on success or < 0 on error;
|
// Returns count of frames written on success or < 0 on error;
|
||||||
// set smpPtr to NULL to write a buffer of silence
|
// set smpPtr to NULL to write a buffer of silence
|
||||||
@ -648,9 +749,13 @@ int _cmApWriteBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp,
|
|||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
{
|
{
|
||||||
|
// for use w/ MBox
|
||||||
|
//_cmApS24_3BE_from_Float(sp, obuf, ep-sp );
|
||||||
|
|
||||||
int* dp = (int*)obuf;
|
int* dp = (int*)obuf;
|
||||||
while( sp < ep )
|
while( sp < ep )
|
||||||
*dp++ = (int)(*sp++ * 0x7fffff);
|
*dp++ = (int)(*sp++ * 0x7fffff);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -696,7 +801,6 @@ int _cmApWriteBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Returns frames read on success or < 0 on error.
|
// Returns frames read on success or < 0 on error.
|
||||||
// Set smpPtr to NULL to read the incoming buffer and discard it
|
// Set smpPtr to NULL to read the incoming buffer and discard it
|
||||||
int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
|
int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
|
||||||
@ -729,7 +833,6 @@ int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, uns
|
|||||||
|
|
||||||
// setup the return buffer
|
// setup the return buffer
|
||||||
cmApSample_t* dp = smpPtr;
|
cmApSample_t* dp = smpPtr;
|
||||||
|
|
||||||
cmApSample_t* ep = dp + cmMin(smpCnt,err*chCnt);
|
cmApSample_t* ep = dp + cmMin(smpCnt,err*chCnt);
|
||||||
|
|
||||||
switch(bits)
|
switch(bits)
|
||||||
@ -752,6 +855,8 @@ int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, uns
|
|||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
{
|
{
|
||||||
|
// For use with MBox
|
||||||
|
//_cmApS24_3BE_to_Float(buf, dp, ep-dp );
|
||||||
int* sp = (int*)buf;
|
int* sp = (int*)buf;
|
||||||
while(dp < ep)
|
while(dp < ep)
|
||||||
*dp++ = ((cmApSample_t)*sp++) / 0x7fffff;
|
*dp++ = ((cmApSample_t)*sp++) / 0x7fffff;
|
||||||
@ -819,7 +924,7 @@ void _cmApStaticAsyncHandler( snd_async_handler_t* ahandler )
|
|||||||
while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
|
while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
|
||||||
{
|
{
|
||||||
|
|
||||||
// Handle inpuut
|
// Handle input
|
||||||
if( inputFl )
|
if( inputFl )
|
||||||
{
|
{
|
||||||
// read samples from the device
|
// read samples from the device
|
||||||
@ -1024,7 +1129,21 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
snd_pcm_uframes_t bufferFrameCnt;
|
snd_pcm_uframes_t bufferFrameCnt;
|
||||||
unsigned bits = 0;
|
unsigned bits = 0;
|
||||||
int sig_bits = 0;
|
int sig_bits = 0;
|
||||||
|
bool signFl = true;
|
||||||
|
bool swapFl = false;
|
||||||
cmApRoot_t* p = drp->rootPtr;
|
cmApRoot_t* p = drp->rootPtr;
|
||||||
|
|
||||||
|
snd_pcm_format_t fmt[] =
|
||||||
|
{
|
||||||
|
SND_PCM_FORMAT_S32_LE,
|
||||||
|
SND_PCM_FORMAT_S32_BE,
|
||||||
|
SND_PCM_FORMAT_S24_LE,
|
||||||
|
SND_PCM_FORMAT_S24_BE,
|
||||||
|
SND_PCM_FORMAT_S24_3LE,
|
||||||
|
SND_PCM_FORMAT_S24_3BE,
|
||||||
|
SND_PCM_FORMAT_S16_LE,
|
||||||
|
SND_PCM_FORMAT_S16_BE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// setup input, then output device
|
// setup input, then output device
|
||||||
@ -1041,7 +1160,6 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
if( _cmApDevShutdown(p, drp, inputFl ) != kOkApRC )
|
if( _cmApDevShutdown(p, drp, inputFl ) != kOkApRC )
|
||||||
retFl = false;
|
retFl = false;
|
||||||
|
|
||||||
|
|
||||||
// attempt to open the sub-device
|
// attempt to open the sub-device
|
||||||
if((err = snd_pcm_open(&pcmH,drp->nameStr, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)) < 0 )
|
if((err = snd_pcm_open(&pcmH,drp->nameStr, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)) < 0 )
|
||||||
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Unable to open the PCM handle");
|
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Unable to open the PCM handle");
|
||||||
@ -1075,23 +1193,23 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
|
|
||||||
if((err = snd_pcm_hw_params_set_access(pcmH,hwParams,SND_PCM_ACCESS_RW_INTERLEAVED )) < 0 )
|
if((err = snd_pcm_hw_params_set_access(pcmH,hwParams,SND_PCM_ACCESS_RW_INTERLEAVED )) < 0 )
|
||||||
retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set access to: RW Interleaved");
|
retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set access to: RW Interleaved");
|
||||||
|
|
||||||
// select the widest possible sample width
|
// select the format width
|
||||||
if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S32)) >= 0 )
|
int j;
|
||||||
bits = 32;
|
int fmtN = sizeof(fmt)/sizeof(fmt[0]);
|
||||||
|
for(j=0; j<fmtN; ++j)
|
||||||
|
if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,fmt[j])) >= 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( j == fmtN )
|
||||||
|
retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set format to: S16");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S24)) >= 0 )
|
bits = snd_pcm_format_width(fmt[j]); // bits per sample
|
||||||
bits = 24;
|
signFl = snd_pcm_format_signed(fmt[j]);
|
||||||
else
|
swapFl = !snd_pcm_format_cpu_endian(fmt[j]);
|
||||||
{
|
|
||||||
if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S16)) >= 0 )
|
|
||||||
bits = 16;
|
|
||||||
else
|
|
||||||
retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set format to: S16");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_bits = snd_pcm_hw_params_get_sbits(hwParams);
|
sig_bits = snd_pcm_hw_params_get_sbits(hwParams);
|
||||||
|
|
||||||
snd_pcm_uframes_t ps_min,ps_max;
|
snd_pcm_uframes_t ps_min,ps_max;
|
||||||
@ -1167,6 +1285,8 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
{
|
{
|
||||||
drp->iBits = bits;
|
drp->iBits = bits;
|
||||||
drp->iSigBits = sig_bits;
|
drp->iSigBits = sig_bits;
|
||||||
|
drp->iSignFl = signFl;
|
||||||
|
drp->iSwapFl = swapFl;
|
||||||
drp->iPcmH = pcmH;
|
drp->iPcmH = pcmH;
|
||||||
drp->iBuf = cmMemResizeZ( cmApSample_t, drp->iBuf, actFpC * drp->iChCnt );
|
drp->iBuf = cmMemResizeZ( cmApSample_t, drp->iBuf, actFpC * drp->iChCnt );
|
||||||
drp->iFpC = actFpC;
|
drp->iFpC = actFpC;
|
||||||
@ -1175,6 +1295,8 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
{
|
{
|
||||||
drp->oBits = bits;
|
drp->oBits = bits;
|
||||||
drp->oSigBits = sig_bits;
|
drp->oSigBits = sig_bits;
|
||||||
|
drp->oSignFl = signFl;
|
||||||
|
drp->oSwapFl = swapFl;
|
||||||
drp->oPcmH = pcmH;
|
drp->oPcmH = pcmH;
|
||||||
drp->oBuf = cmMemResizeZ( cmApSample_t, drp->oBuf, actFpC * drp->oChCnt );
|
drp->oBuf = cmMemResizeZ( cmApSample_t, drp->oBuf, actFpC * drp->oChCnt );
|
||||||
drp->oFpC = actFpC;
|
drp->oFpC = actFpC;
|
||||||
@ -1448,7 +1570,7 @@ cmApRC_t cmApAlsaInitialize( cmRpt_t* rpt, unsigned baseApDevIdx )
|
|||||||
// this device uses this subdevice in the current direction
|
// this device uses this subdevice in the current direction
|
||||||
dr.flags += inputFl ? kInFl : kOutFl;
|
dr.flags += inputFl ? kInFl : kOutFl;
|
||||||
|
|
||||||
printf("%s in:%i chs:%i rate:%i\n",dr.nameStr,inputFl,*chCntPtr,rate);
|
//printf("%s in:%i chs:%i rate:%i\n",dr.nameStr,inputFl,*chCntPtr,rate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user