2018-03-17 Fred Gleason <fredg@paravelsystems.com>

* Added support for DMA bus-mastering to the HPI driver.
This commit is contained in:
Fred Gleason 2018-03-17 16:55:49 -04:00
parent d4e8112bf0
commit 25e9d6fb28
7 changed files with 329 additions and 223 deletions

View File

@ -16610,3 +16610,5 @@
2018-02-22 Fred Gleason <fredg@paravelsystems.com> 2018-02-22 Fred Gleason <fredg@paravelsystems.com>
* Updated 'NEWS'. * Updated 'NEWS'.
* Incremented the package version to 2.19.0. * Incremented the package version to 2.19.0.
2018-03-17 Fred Gleason <fredg@paravelsystems.com>
* Added support for DMA bus-mastering to the HPI driver.

View File

@ -2,7 +2,7 @@
// //
// A class for playing Microsoft WAV files. // A class for playing Microsoft WAV files.
// //
// (C) Copyright 2002-2007,2016 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2007,2016-2018 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -66,7 +66,10 @@ RDHPIPlayStream::RDHPIPlayStream(RDHPISoundCard *card,QWidget *parent)
// hpi_err_t hpi_err; // hpi_err_t hpi_err;
int quan; int quan;
uint16_t type[HPI_MAX_ADAPTERS]; uint16_t type[HPI_MAX_ADAPTERS];
struct hpi_format fmt;
uint32_t dma_size=0;
dma_buffer_size=0;
sound_card=card; sound_card=card;
card_number=-1; card_number=-1;
stream_number=-1; stream_number=-1;
@ -94,16 +97,28 @@ RDHPIPlayStream::RDHPIPlayStream(RDHPISoundCard *card,QWidget *parent)
card_index[i]=i; card_index[i]=i;
} }
#else #else
LogHpi(HPI_SubSysGetNumAdapters(NULL,&quan)); LogHpi(HPI_SubSysGetNumAdapters(NULL,&quan),__LINE__);
for(int i=0;i<quan;i++) { for(int i=0;i<quan;i++) {
LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,type+i)); LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,type+i),__LINE__);
} }
#endif // HPI_VER #endif // HPI_VER
clock=new QTimer(this,"clock"); //
// Calculate DMA Buffer Size
//
memset(&fmt,0,sizeof(fmt)); // Worst case situation
fmt.dwSampleRate=48000;
fmt.wChannels=2;
fmt.wFormat=HPI_FORMAT_PCM32_FLOAT;
if(LogHpi(HPI_StreamEstimateBufferSize(&fmt,FRAGMENT_TIME,&dma_size),
__LINE__)==0) {
dma_buffer_size=dma_size;
}
clock=new QTimer(this);
connect(clock,SIGNAL(timeout()),this,SLOT(tickClock())); connect(clock,SIGNAL(timeout()),this,SLOT(tickClock()));
play_timer=new QTimer(this,"play_timer"); play_timer=new QTimer(this);
connect(play_timer,SIGNAL(timeout()),this,SLOT(pause())); connect(play_timer,SIGNAL(timeout()),this,SLOT(pause()));
} }
@ -171,7 +186,9 @@ bool RDHPIPlayStream::formatSupported(RDWaveFile::Format format)
} }
if(!is_open) { if(!is_open) {
for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) { for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) {
if(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hostream)==0) { if(LogHpi(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hostream),
__LINE__)==0) {
syslog(LOG_NOTICE,"buffer_size: %u\n",dma_buffer_size);
found=true; found=true;
break; break;
} }
@ -179,6 +196,11 @@ bool RDHPIPlayStream::formatSupported(RDWaveFile::Format format)
if(!found) { if(!found) {
return false; return false;
} }
if(LogHpi(HPI_OutStreamHostBufferAllocate(NULL,hostream,dma_buffer_size),
__LINE__)!=0) {
LogHpi(HPI_OutStreamClose(NULL,hostream),__LINE__);
return false;
}
} }
else { else {
hostream=hpi_stream; hostream=hpi_stream;
@ -187,36 +209,46 @@ bool RDHPIPlayStream::formatSupported(RDWaveFile::Format format)
case RDWaveFile::Pcm16: case RDWaveFile::Pcm16:
LogHpi(HPI_FormatCreate(&hpi_format,getChannels(), LogHpi(HPI_FormatCreate(&hpi_format,getChannels(),
HPI_FORMAT_PCM16_SIGNED, HPI_FORMAT_PCM16_SIGNED,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format); __LINE__);
state=LogHpi(HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format),
__LINE__);
break; break;
case RDWaveFile::Pcm24: case RDWaveFile::Pcm24:
LogHpi(HPI_FormatCreate(&hpi_format,getChannels(), LogHpi(HPI_FormatCreate(&hpi_format,getChannels(),
HPI_FORMAT_PCM24_SIGNED, HPI_FORMAT_PCM24_SIGNED,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format); __LINE__);
state=LogHpi(HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format),
__LINE__);
break; break;
case RDWaveFile::MpegL1: case RDWaveFile::MpegL1:
LogHpi(HPI_FormatCreate(&hpi_format,getChannels(), LogHpi(HPI_FormatCreate(&hpi_format,getChannels(),
HPI_FORMAT_MPEG_L1, HPI_FORMAT_MPEG_L1,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format); __LINE__);
state=LogHpi(HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format),
__LINE__);
break; break;
case RDWaveFile::MpegL2: case RDWaveFile::MpegL2:
LogHpi(HPI_FormatCreate(&hpi_format,getChannels(), LogHpi(HPI_FormatCreate(&hpi_format,getChannels(),
HPI_FORMAT_MPEG_L2, HPI_FORMAT_MPEG_L2,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format); __LINE__);
state=LogHpi(HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format),
__LINE__);
break;; break;;
case RDWaveFile::MpegL3: case RDWaveFile::MpegL3:
LogHpi(HPI_FormatCreate(&hpi_format,getChannels(), LogHpi(HPI_FormatCreate(&hpi_format,getChannels(),
HPI_FORMAT_MPEG_L3, HPI_FORMAT_MPEG_L3,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format); __LINE__);
state=LogHpi(HPI_OutStreamQueryFormat(NULL,hostream,&hpi_format),
__LINE__);
break; break;
default: default:
@ -224,7 +256,8 @@ bool RDHPIPlayStream::formatSupported(RDWaveFile::Format format)
break; break;
} }
if(!is_open) { if(!is_open) {
LogHpi(HPI_OutStreamClose(NULL,hostream)); LogHpi(HPI_OutStreamHostBufferFree(NULL,hostream),__LINE__);
LogHpi(HPI_OutStreamClose(NULL,hostream),__LINE__);
} }
if(state!=0) { if(state!=0) {
return false; return false;
@ -396,10 +429,10 @@ bool RDHPIPlayStream::play()
if((!playing)&&(!is_paused)) { if((!playing)&&(!is_paused)) {
LogHpi(HPI_OutStreamSetTimeScale(NULL,hpi_stream, LogHpi(HPI_OutStreamSetTimeScale(NULL,hpi_stream,
(uint16_t)((RD_TIMESCALE_DIVISOR/(double)play_speed)* (uint16_t)((RD_TIMESCALE_DIVISOR/(double)play_speed)*
HPI_OSTREAM_TIMESCALE_UNITS))); HPI_OSTREAM_TIMESCALE_UNITS)),__LINE__);
if(HPI_OutStreamGetInfoEx(NULL,hpi_stream, if(LogHpi(HPI_OutStreamGetInfoEx(NULL,hpi_stream,
&state,&buffer_size,&data_to_play, &state,&buffer_size,&data_to_play,
&samples_played,&reserved)!=0) { &samples_played,&reserved),__LINE__)!=0) {
return false; return false;
} }
fragment_size=buffer_size/4; fragment_size=buffer_size/4;
@ -420,25 +453,25 @@ bool RDHPIPlayStream::play()
case 8: case 8:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM8_UNSIGNED, HPI_FORMAT_PCM8_UNSIGNED,
getSamplesPerSec(),0,0)); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 16: case 16:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM16_SIGNED, HPI_FORMAT_PCM16_SIGNED,
getSamplesPerSec(),0,0)); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 24: case 24:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM24_SIGNED, HPI_FORMAT_PCM24_SIGNED,
getSamplesPerSec(),0,0)); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 32: case 32:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM32_SIGNED, HPI_FORMAT_PCM32_SIGNED,
getSamplesPerSec(),0,0)); getSamplesPerSec(),0,0),__LINE__);
break; break;
default: default:
LogHpi(HPI_AdapterClose(NULL,card_index[card_number])); LogHpi(HPI_AdapterClose(NULL,card_index[card_number]),__LINE__);
return false; return false;
break; break;
} }
@ -448,20 +481,23 @@ bool RDHPIPlayStream::play()
case 1: case 1:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L1,getSamplesPerSec(), HPI_FORMAT_MPEG_L1,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags())); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
case 2: case 2:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L2,getSamplesPerSec(), HPI_FORMAT_MPEG_L2,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags())); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
case 3: case 3:
LogHpi(HPI_FormatCreate(&format,getChannels(), LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L3,getSamplesPerSec(), HPI_FORMAT_MPEG_L3,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags())); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
default: default:
LogHpi(HPI_AdapterClose(NULL,card_index[card_number])); LogHpi(HPI_AdapterClose(NULL,card_index[card_number]),__LINE__);
return false; return false;
} }
break; break;
@ -469,7 +505,8 @@ bool RDHPIPlayStream::play()
return false; return false;
} }
#if HPI_VER < 0x00030500 #if HPI_VER < 0x00030500
if(HPI_DataCreate(&hpi_data,&format,pdata,fragment_size)!=0) { if(LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,fragment_size),__LINE__)!=
0) {
return false; return false;
} }
#endif #endif
@ -488,15 +525,15 @@ bool RDHPIPlayStream::play()
} }
readWave(pdata,read_bytes); readWave(pdata,read_bytes);
#if HPI_VER > 0x00030500 #if HPI_VER > 0x00030500
LogHpi(HPI_OutStreamWriteBuf(NULL,hpi_stream,pdata,read_bytes,&format)); LogHpi(HPI_OutStreamWriteBuf(NULL,hpi_stream,pdata,read_bytes,&format),
__LINE__);
#else #else
LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,read_bytes)); LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,read_bytes),__LINE__);
LogHpi(HPI_OutStreamWrite(NULL,hpi_stream,&hpi_data)); LogHpi(HPI_OutStreamWrite(NULL,hpi_stream,&hpi_data),__LINE__);
#endif #endif
if(HPI_OutStreamStart(NULL,hpi_stream)!=0) { if(LogHpi(HPI_OutStreamStart(NULL,hpi_stream),__LINE__)!=0) {
return false; return false;
} }
clock->start(50);
clock->start(FRAGMENT_TIME); clock->start(FRAGMENT_TIME);
playing=true; playing=true;
is_paused=false; is_paused=false;
@ -513,7 +550,7 @@ bool RDHPIPlayStream::play()
} }
} }
if((!playing)&(is_paused|repositioned)) { if((!playing)&(is_paused|repositioned)) {
LogHpi(HPI_OutStreamStart(NULL,hpi_stream)); LogHpi(HPI_OutStreamStart(NULL,hpi_stream),__LINE__);
clock->start(FRAGMENT_TIME); clock->start(FRAGMENT_TIME);
playing=true; playing=true;
stopping=false; stopping=false;
@ -543,10 +580,11 @@ void RDHPIPlayStream::pause()
return; return;
} }
if(playing) { if(playing) {
LogHpi(HPI_OutStreamStop(NULL,hpi_stream)); LogHpi(HPI_OutStreamStop(NULL,hpi_stream),__LINE__);
clock->stop(); clock->stop();
LogHpi(HPI_OutStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size, LogHpi(HPI_OutStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size,
&data_to_play,&samples_played,&reserved)); &data_to_play,&samples_played,&reserved),
__LINE__);
switch(getFormatTag()) { switch(getFormatTag()) {
case WAVE_FORMAT_PCM: case WAVE_FORMAT_PCM:
samples_pending=data_to_play/(getChannels()*getBitsPerSample()/8); samples_pending=data_to_play/(getChannels()*getBitsPerSample()/8);
@ -580,12 +618,12 @@ void RDHPIPlayStream::stop()
return; return;
} }
if(playing|is_paused) { if(playing|is_paused) {
LogHpi(HPI_OutStreamStop(NULL,hpi_stream)); LogHpi(HPI_OutStreamStop(NULL,hpi_stream),__LINE__);
clock->stop(); clock->stop();
playing=false; playing=false;
is_paused=false; is_paused=false;
seekWave(0,SEEK_SET); seekWave(0,SEEK_SET);
LogHpi(HPI_OutStreamReset(NULL,hpi_stream)); LogHpi(HPI_OutStreamReset(NULL,hpi_stream),__LINE__);
samples_pending=0; samples_pending=0;
samples_skipped=0; samples_skipped=0;
stream_state=RDHPIPlayStream::Stopped; stream_state=RDHPIPlayStream::Stopped;
@ -632,7 +670,7 @@ bool RDHPIPlayStream::setPosition(unsigned samples)
is_paused=false; is_paused=false;
repositioned=true; repositioned=true;
} }
LogHpi(HPI_OutStreamReset(NULL,hpi_stream)); LogHpi(HPI_OutStreamReset(NULL,hpi_stream),__LINE__);
samples_played=0; samples_played=0;
switch(getFormatTag()) { switch(getFormatTag()) {
case WAVE_FORMAT_PCM: case WAVE_FORMAT_PCM:
@ -686,24 +724,25 @@ void RDHPIPlayStream::tickClock()
char hpi_text[100]; char hpi_text[100];
int n; int n;
hpi_err=HPI_OutStreamGetInfoEx(NULL,hpi_stream, hpi_err=LogHpi(HPI_OutStreamGetInfoEx(NULL,hpi_stream,
&state,&buffer_size,&data_to_play, &state,&buffer_size,&data_to_play,
&samples_played,&reserved); &samples_played,&reserved),__LINE__);
if(!stopping) { if(!stopping) {
while((buffer_size-data_to_play)>=fragment_size) { while((buffer_size-data_to_play)>=fragment_size) {
n=readWave(pdata,fragment_size); n=readWave(pdata,fragment_size);
if((n<=0)||(((uint32_t)n)<fragment_size)) { if((n<=0)||(((uint32_t)n)<fragment_size)) {
// End of file // End of file
#if HPI_VER > 0x00030500 #if HPI_VER > 0x00030500
if((hpi_err=HPI_OutStreamWriteBuf(NULL,hpi_stream, if((hpi_err=LogHpi(HPI_OutStreamWriteBuf(NULL,hpi_stream,
pdata,n,&format))!=0) { pdata,n,&format),__LINE__))!=
0) {
HPI_GetErrorText(hpi_err,hpi_text); HPI_GetErrorText(hpi_err,hpi_text);
fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text); fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text);
} }
#else #else
HPI_DataCreate(&hpi_data,&format,pdata,n); HPI_DataCreate(&hpi_data,&format,pdata,n);
if((hpi_err=HPI_OutStreamWrite(NULL,hpi_stream, if((hpi_err=LogHpi(HPI_OutStreamWrite(NULL,hpi_stream,
&hpi_data))!=0) { &hpi_data),__LINE__))!=0) {
HPI_GetErrorText(hpi_err,hpi_text); HPI_GetErrorText(hpi_err,hpi_text);
fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text); fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text);
} }
@ -714,26 +753,28 @@ void RDHPIPlayStream::tickClock()
} }
left_to_write-=n; left_to_write-=n;
#if HPI_VER > 0x00030500 #if HPI_VER > 0x00030500
hpi_err=HPI_OutStreamWriteBuf(NULL,hpi_stream, hpi_err=LogHpi(HPI_OutStreamWriteBuf(NULL,hpi_stream,pdata,n,&format),
pdata,n,&format); __LINE__);
#else #else
hpi_err=HPI_DataCreate(&hpi_data,&format,pdata,n); hpi_err=LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,n),__LINE__);
hpi_err=HPI_OutStreamWrite(NULL,hpi_stream,&hpi_data); hpi_err=LogHpi(HPI_OutStreamWrite(NULL,hpi_stream,&hpi_data),__LINE__);
#endif #endif
hpi_err=HPI_OutStreamGetInfoEx(NULL,hpi_stream, hpi_err=LogHpi(HPI_OutStreamGetInfoEx(NULL,hpi_stream,
&state,&buffer_size,&data_to_play, &state,&buffer_size,&data_to_play,
&samples_played,&reserved); &samples_played,&reserved),
__LINE__);
} }
} }
else { else {
if(state==HPI_STATE_DRAINED) { if(state==HPI_STATE_DRAINED) {
hpi_err=HPI_OutStreamStop(NULL,hpi_stream); LogHpi(HPI_OutStreamStop(NULL,hpi_stream),__LINE__);
hpi_err=HPI_OutStreamClose(NULL,hpi_stream); LogHpi(HPI_OutStreamHostBufferFree(NULL,hpi_stream),__LINE__);
hpi_err=HPI_AdapterClose(NULL,card_index[card_number]); LogHpi(HPI_OutStreamClose(NULL,hpi_stream),__LINE__);
hpi_err=LogHpi(HPI_AdapterClose(NULL,card_index[card_number]),__LINE__);
clock->stop(); clock->stop();
playing=false; playing=false;
seekWave(0,SEEK_SET); seekWave(0,SEEK_SET);
hpi_err=HPI_OutStreamReset(NULL,hpi_stream); hpi_err=LogHpi(HPI_OutStreamReset(NULL,hpi_stream),__LINE__);
samples_pending=0; samples_pending=0;
samples_skipped=0; samples_skipped=0;
stream_state=RDHPIPlayStream::Stopped; stream_state=RDHPIPlayStream::Stopped;
@ -761,7 +802,10 @@ int RDHPIPlayStream::GetStream()
#ifdef RDHPIPLAYSTREAM_USE_LOCAL_MUTEX #ifdef RDHPIPLAYSTREAM_USE_LOCAL_MUTEX
for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) { for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) {
if(++stream_mutex[card_number][i]==1) { if(++stream_mutex[card_number][i]==1) {
LogHpi(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hpi_stream)); LogHpi(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hpi_stream),
__LINE__);
LogHpi(HPI_OutStreamHostBufferAllocate(NULL,hpi_stream,dma_buffer_size),
__LINE__);
stream_number=i; stream_number=i;
return stream_number; return stream_number;
} }
@ -772,7 +816,8 @@ int RDHPIPlayStream::GetStream()
return -1; return -1;
#else #else
for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) { for(int i=0;i<sound_card->getCardOutputStreams(card_number);i++) {
if(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hpi_stream)==0) { if(LogHpi(HPI_OutStreamOpen(NULL,card_index[card_number],i,&hpi_stream),
__LINE__)==0) {
stream_number=i; stream_number=i;
// syslog(LOG_ERR,"HPI allocating ostream: %d",stream_number); // syslog(LOG_ERR,"HPI allocating ostream: %d",stream_number);
return stream_number; return stream_number;
@ -787,23 +832,25 @@ void RDHPIPlayStream::FreeStream()
{ {
#ifdef RDHPIPLAYSTREAM_USE_LOCAL_MUTEX #ifdef RDHPIPLAYSTREAM_USE_LOCAL_MUTEX
stream_mutex[card_number][stream_number]--; stream_mutex[card_number][stream_number]--;
LogHpi(HPI_OutStreamClose(NULL,hpi_stream)); LogHpi(HPI_OutStreamHostBufferFree(NULL,hpi_stream),__LINE__);
LogHpi(HPI_OutStreamClose(NULL,hpi_stream),__LINE__);
stream_number=-1; stream_number=-1;
#else #else
LogHpi(HPI_OutStreamClose(NULL,hpi_stream)); LogHpi(HPI_OutStreamHostBufferFree(NULL,hpi_stream),__LINE__);
LogHpi(HPI_OutStreamClose(NULL,hpi_stream),__LINE__);
// syslog(LOG_ERR,"HPI closing ostream: %d",stream_number); // syslog(LOG_ERR,"HPI closing ostream: %d",stream_number);
stream_number=-1; stream_number=-1;
#endif #endif
} }
hpi_err_t RDHPIPlayStream::LogHpi(hpi_err_t err) hpi_err_t RDHPIPlayStream::LogHpi(hpi_err_t err,int lineno)
{ {
char err_txt[200]; char err_txt[200];
if(err!=0) { if(err!=0) {
HPI_GetErrorText(err,err_txt); HPI_GetErrorText(err,err_txt);
syslog(LOG_NOTICE,"HPI Error: %s",err_txt); syslog(LOG_NOTICE,"HPI Error: %s, %s line %d",err_txt,__FILE__,lineno);
} }
return err; return err;
} }

View File

@ -87,7 +87,7 @@ class RDHPIPlayStream : public QObject,public RDWaveFile
void Drained(); void Drained();
int GetStream(); int GetStream();
void FreeStream(); void FreeStream();
hpi_err_t LogHpi(hpi_err_t err); hpi_err_t LogHpi(hpi_err_t err,int lineno);
RDHPISoundCard *sound_card; RDHPISoundCard *sound_card;
RDHPIPlayStream::State stream_state; RDHPIPlayStream::State stream_state;
QString wave_name; QString wave_name;
@ -130,6 +130,7 @@ class RDHPIPlayStream : public QObject,public RDWaveFile
bool restart_transport; bool restart_transport;
int samples_pending; int samples_pending;
unsigned current_position; unsigned current_position;
uint32_t dma_buffer_size;
}; };

View File

@ -2,7 +2,7 @@
// //
// A class for recording Microsoft WAV files. // A class for recording Microsoft WAV files.
// //
// (C) Copyright 2002-2016 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2018 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -37,6 +37,8 @@ RDHPIRecordStream::RDHPIRecordStream(RDHPISoundCard *card,QWidget *parent)
{ {
int quan; int quan;
uint16_t type[HPI_MAX_ADAPTERS]; uint16_t type[HPI_MAX_ADAPTERS];
struct hpi_format fmt;
uint32_t dma_size=0;
if(getenv(DEBUG_VAR)==NULL) { if(getenv(DEBUG_VAR)==NULL) {
debug=false; debug=false;
@ -74,16 +76,28 @@ RDHPIRecordStream::RDHPIRecordStream(RDHPISoundCard *card,QWidget *parent)
card_index[i]=i; card_index[i]=i;
} }
#else #else
LogHpi(HPI_SubSysGetNumAdapters(NULL,&quan)); LogHpi(HPI_SubSysGetNumAdapters(NULL,&quan),__LINE__);
for(int i=0;i<quan;i++) { for(int i=0;i<quan;i++) {
LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,type+i)); LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,type+i),__LINE__);
} }
#endif // HPI_VER #endif // HPI_VER
clock=new QTimer(this,"clock"); //
// Calculate DMA Buffer Size
//
memset(&fmt,0,sizeof(fmt)); // Worst case situation
fmt.dwSampleRate=48000;
fmt.wChannels=2;
fmt.wFormat=HPI_FORMAT_PCM32_FLOAT;
if(LogHpi(HPI_StreamEstimateBufferSize(&fmt,RDHPIRECORDSTREAM_CLOCK_INTERVAL,
&dma_size),__LINE__)==0) {
dma_buffer_size=dma_size;
}
clock=new QTimer(this);
connect(clock,SIGNAL(timeout()),this,SLOT(tickClock())); connect(clock,SIGNAL(timeout()),this,SLOT(tickClock()));
length_timer=new QTimer(this,"length_timer"); length_timer=new QTimer(this);
connect(length_timer,SIGNAL(timeout()),this,SLOT(pause())); connect(length_timer,SIGNAL(timeout()),this,SLOT(pause()));
} }
@ -187,7 +201,8 @@ bool RDHPIRecordStream::formatSupported(RDWaveFile::Format format)
} }
if(!is_open) { if(!is_open) {
for(int i=0;i<sound_card->getCardInputStreams(card_number);i++) { for(int i=0;i<sound_card->getCardInputStreams(card_number);i++) {
if(HPI_InStreamOpen(NULL,card_index[card_number],i,&histream)==0) { if(LogHpi(HPI_InStreamOpen(NULL,card_index[card_number],i,&histream),
__LINE__)==0) {
found=true; found=true;
break; break;
} }
@ -195,6 +210,12 @@ bool RDHPIRecordStream::formatSupported(RDWaveFile::Format format)
if(!found) { if(!found) {
return false; return false;
} }
if(LogHpi(HPI_InStreamHostBufferAllocate(NULL,histream,dma_buffer_size),
__LINE__)!=0) {
LogHpi(HPI_InStreamHostBufferFree(NULL,histream),__LINE__);
LogHpi(HPI_InStreamClose(NULL,histream),__LINE__);
return false;
}
} }
else { else {
histream=hpi_stream; histream=hpi_stream;
@ -203,40 +224,46 @@ bool RDHPIRecordStream::formatSupported(RDWaveFile::Format format)
case RDWaveFile::Pcm8: case RDWaveFile::Pcm8:
LogHpi(HPI_FormatCreate(&hformat,getChannels(), LogHpi(HPI_FormatCreate(&hformat,getChannels(),
HPI_FORMAT_PCM8_UNSIGNED, HPI_FORMAT_PCM8_UNSIGNED,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
case RDWaveFile::Pcm16: case RDWaveFile::Pcm16:
LogHpi(HPI_FormatCreate(&hformat,getChannels(), LogHpi(HPI_FormatCreate(&hformat,getChannels(),
HPI_FORMAT_PCM16_SIGNED, HPI_FORMAT_PCM16_SIGNED,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
case RDWaveFile::Pcm24: case RDWaveFile::Pcm24:
LogHpi(HPI_FormatCreate(&hformat,getChannels(), LogHpi(HPI_FormatCreate(&hformat,getChannels(),
HPI_FORMAT_PCM24_SIGNED, HPI_FORMAT_PCM24_SIGNED,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
case RDWaveFile::MpegL1: case RDWaveFile::MpegL1:
LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L1, LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L1,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
case RDWaveFile::MpegL2: case RDWaveFile::MpegL2:
LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L2, LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L2,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
case RDWaveFile::MpegL3: case RDWaveFile::MpegL3:
LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L3, LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L3,
getSamplesPerSec(),getHeadBitRate(),0)); getSamplesPerSec(),getHeadBitRate(),0),
state=HPI_InStreamQueryFormat(NULL,histream,&hformat); __LINE__);
state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
break; break;
default: default:
@ -244,7 +271,8 @@ bool RDHPIRecordStream::formatSupported(RDWaveFile::Format format)
break; break;
} }
if(!is_open) { if(!is_open) {
LogHpi(HPI_InStreamClose(NULL,histream)); LogHpi(HPI_InStreamHostBufferFree(NULL,histream),__LINE__);
LogHpi(HPI_InStreamClose(NULL,histream),__LINE__);
} }
if(state!=0) { if(state!=0) {
return false; return false;
@ -381,9 +409,9 @@ bool RDHPIRecordStream::recordReady()
} }
if((!is_recording)&&(!is_paused)) { if((!is_recording)&&(!is_paused)) {
resetWave(); resetWave();
if(HPI_InStreamGetInfoEx(NULL,hpi_stream, if(LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,
&state,&buffer_size,&data_recorded, &state,&buffer_size,&data_recorded,
&samples_recorded,&reserved)!=0) { &samples_recorded,&reserved),__LINE__)!=0) {
if(debug) { if(debug) {
printf("RDHPIRecordStream: HPI_InStreamGetInfoEx() failed\n"); printf("RDHPIRecordStream: HPI_InStreamGetInfoEx() failed\n");
} }
@ -412,27 +440,27 @@ bool RDHPIRecordStream::recordReady()
} }
switch(getBitsPerSample()) { switch(getBitsPerSample()) {
case 8: case 8:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM8_UNSIGNED,getSamplesPerSec(), HPI_FORMAT_PCM8_UNSIGNED,
0,0); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 16: case 16:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM16_SIGNED,getSamplesPerSec(), HPI_FORMAT_PCM16_SIGNED,
0,0); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 24: case 24:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM24_SIGNED,getSamplesPerSec(), HPI_FORMAT_PCM24_SIGNED,
0,0); getSamplesPerSec(),0,0),__LINE__);
break; break;
case 32: case 32:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM32_SIGNED,getSamplesPerSec(), HPI_FORMAT_PCM32_SIGNED,
0,0); getSamplesPerSec(),0,0),__LINE__);
break; break;
default: default:
@ -449,25 +477,29 @@ bool RDHPIRecordStream::recordReady()
} }
switch(getHeadLayer()) { switch(getHeadLayer()) {
case 1: case 1:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L1,getSamplesPerSec(), HPI_FORMAT_MPEG_L1,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags()); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
case 2: case 2:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L2,getSamplesPerSec(), HPI_FORMAT_MPEG_L2,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags()); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
case 3: case 3:
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_MPEG_L3,getSamplesPerSec(), HPI_FORMAT_MPEG_L3,getSamplesPerSec(),
getHeadBitRate(),getHeadFlags()); getHeadBitRate(),getHeadFlags()),
__LINE__);
break; break;
default: default:
hpi_error=HPI_AdapterClose(NULL,card_index[card_number]); hpi_error=LogHpi(HPI_AdapterClose(NULL,card_index[card_number]),
__LINE__);
if(debug) { if(debug) {
printf("RDHPIRecordStream: invalid MPEG-1 layer\n"); printf("RDHPIRecordStream: invalid MPEG-1 layer\n");
} }
@ -495,9 +527,9 @@ bool RDHPIRecordStream::recordReady()
if(debug) { if(debug) {
printf("RDHPIRecordStream: using OggVorbis\n"); printf("RDHPIRecordStream: using OggVorbis\n");
} }
hpi_error=HPI_FormatCreate(&format,getChannels(), hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
HPI_FORMAT_PCM16_SIGNED,getSamplesPerSec(), HPI_FORMAT_PCM16_SIGNED,
0,0); getSamplesPerSec(),0,0),__LINE__);
break; break;
default: default:
@ -507,8 +539,8 @@ bool RDHPIRecordStream::recordReady()
return false; return false;
break; break;
} }
if((hpi_error=HPI_InStreamQueryFormat(NULL,hpi_stream, if((hpi_error=LogHpi(HPI_InStreamQueryFormat(NULL,hpi_stream,
&format))!=0) { &format),__LINE__))!=0) {
if(debug) { if(debug) {
HPI_GetErrorText(hpi_error,hpi_text); HPI_GetErrorText(hpi_error,hpi_text);
printf("Num: %d\n",hpi_error); printf("Num: %d\n",hpi_error);
@ -518,12 +550,12 @@ bool RDHPIRecordStream::recordReady()
} }
} }
#if HPI_VER < 0x00030500 #if HPI_VER < 0x00030500
HPI_DataCreate(&hpi_data,&format,pdata,fragment_size); LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,fragment_size),__LINE__);
#endif #endif
hpi_error=HPI_InStreamSetFormat(NULL,hpi_stream,&format); hpi_error=LogHpi(HPI_InStreamSetFormat(NULL,hpi_stream,&format),__LINE__);
hpi_error=HPI_InStreamStart(NULL,hpi_stream); hpi_error=LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
// clock->start(2*fragment_time/3); // clock->start(2*fragment_time/3);
clock->start(100); clock->start(RDHPIRECORDSTREAM_CLOCK_INTERVAL);
is_ready=true; is_ready=true;
is_recording=false; is_recording=false;
is_paused=false; is_paused=false;
@ -553,8 +585,8 @@ void RDHPIRecordStream::record()
recordReady(); recordReady();
} }
record_started=false; record_started=false;
LogHpi(HPI_InStreamReset(NULL,hpi_stream)); LogHpi(HPI_InStreamReset(NULL,hpi_stream),__LINE__);
LogHpi(HPI_InStreamStart(NULL,hpi_stream)); LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
is_recording=true; is_recording=true;
is_paused=false; is_paused=false;
emit isStopped(false); emit isStopped(false);
@ -577,13 +609,14 @@ void RDHPIRecordStream::pause()
if(!is_recording) { if(!is_recording) {
return; return;
} }
LogHpi(HPI_InStreamStop(NULL,hpi_stream)); LogHpi(HPI_InStreamStop(NULL,hpi_stream),__LINE__);
tickClock(); tickClock();
LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size, LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size,
&data_recorded,&samples_recorded,&reserved)); &data_recorded,&samples_recorded,&reserved),
__LINE__);
is_recording=false; is_recording=false;
is_paused=true; is_paused=true;
LogHpi(HPI_InStreamStart(NULL,hpi_stream)); LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
emit paused(); emit paused();
emit stateChanged(card_number,stream_number,2); // Paused emit stateChanged(card_number,stream_number,2); // Paused
if(debug) { if(debug) {
@ -599,7 +632,7 @@ void RDHPIRecordStream::stop()
printf("RDHPIRecordStream: received stop()\n"); printf("RDHPIRecordStream: received stop()\n");
} }
if(is_ready|is_recording|is_paused) { if(is_ready|is_recording|is_paused) {
LogHpi(HPI_InStreamStop(NULL,hpi_stream)); LogHpi(HPI_InStreamStop(NULL,hpi_stream),__LINE__);
tickClock(); tickClock();
clock->stop(); clock->stop();
is_recording=false; is_recording=false;
@ -639,7 +672,7 @@ void RDHPIRecordStream::tickClock()
{ {
LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream, LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,
&state,&buffer_size,&data_recorded, &state,&buffer_size,&data_recorded,
&samples_recorded,&reserved)); &samples_recorded,&reserved),__LINE__);
if((!record_started)&&(is_recording)) { if((!record_started)&&(is_recording)) {
if(samples_recorded>0) { if(samples_recorded>0) {
if(record_length>0) { if(record_length>0) {
@ -656,22 +689,23 @@ void RDHPIRecordStream::tickClock()
} }
while(data_recorded>fragment_size) { while(data_recorded>fragment_size) {
#if HPI_VER > 0x00030500 #if HPI_VER > 0x00030500
LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,fragment_size)); LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,fragment_size),__LINE__);
#else #else
LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data)); LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data),__LINE__);
#endif #endif
if(is_recording) { if(is_recording) {
writeWave(pdata,fragment_size); writeWave(pdata,fragment_size);
} }
LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size, LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size,
&data_recorded,&samples_recorded,&reserved)); &data_recorded,&samples_recorded,&reserved),
__LINE__);
} }
if(state==HPI_STATE_STOPPED) { if(state==HPI_STATE_STOPPED) {
#if HPI_VER > 0x00030500 #if HPI_VER > 0x00030500
LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,data_recorded)); LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,data_recorded),__LINE__);
#else #else
LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,data_recorded)); LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,data_recorded),__LINE__);
LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data)); LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data),__LINE__);
#endif #endif
if(is_recording) { if(is_recording) {
writeWave(pdata,data_recorded); writeWave(pdata,data_recorded);
@ -691,30 +725,38 @@ bool RDHPIRecordStream::GetStream()
char hpi_text[100]; char hpi_text[100];
if((hpi_err= if((hpi_err=
HPI_InStreamOpen(NULL,card_index[card_number],stream_number,&hpi_stream))!=0) { LogHpi(HPI_InStreamOpen(NULL,card_index[card_number],stream_number,
&hpi_stream),__LINE__))!=0) {
if(debug) { if(debug) {
HPI_GetErrorText(hpi_err,hpi_text); HPI_GetErrorText(hpi_err,hpi_text);
fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text); fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text);
} }
return false; return false;
} }
if(LogHpi(HPI_InStreamHostBufferAllocate(NULL,hpi_stream,dma_buffer_size),
__LINE__)!=0) {
LogHpi(HPI_InStreamHostBufferFree(NULL,hpi_stream),__LINE__);
LogHpi(HPI_InStreamClose(NULL,hpi_stream),__LINE__);
return false;
}
return true; return true;
} }
void RDHPIRecordStream::FreeStream() void RDHPIRecordStream::FreeStream()
{ {
LogHpi(HPI_InStreamClose(NULL,hpi_stream)); LogHpi(HPI_InStreamHostBufferFree(NULL,hpi_stream),__LINE__);
LogHpi(HPI_InStreamClose(NULL,hpi_stream),__LINE__);
} }
hpi_err_t RDHPIRecordStream::LogHpi(hpi_err_t err) hpi_err_t RDHPIRecordStream::LogHpi(hpi_err_t err,int lineno)
{ {
char err_txt[200]; char err_txt[200];
if(err!=0) { if(err!=0) {
HPI_GetErrorText(err,err_txt); HPI_GetErrorText(err,err_txt);
syslog(LOG_NOTICE,"HPI Error: %s",err_txt); syslog(LOG_NOTICE,"HPI Error: %s, %s line %d",err_txt,__FILE__,lineno);
} }
return err; return err;
} }

View File

@ -44,7 +44,6 @@
#define AUDIO_SIZE 32768 #define AUDIO_SIZE 32768
#define RDHPIRECORDSTREAM_CLOCK_INTERVAL 100 #define RDHPIRECORDSTREAM_CLOCK_INTERVAL 100
class RDHPIRecordStream : public QObject,public RDWaveFile class RDHPIRecordStream : public QObject,public RDWaveFile
{ {
Q_OBJECT Q_OBJECT
@ -94,7 +93,7 @@ class RDHPIRecordStream : public QObject,public RDWaveFile
private: private:
bool GetStream(); bool GetStream();
void FreeStream(); void FreeStream();
hpi_err_t LogHpi(hpi_err_t err); hpi_err_t LogHpi(hpi_err_t err,int lineno);
RDHPISoundCard *sound_card; RDHPISoundCard *sound_card;
bool debug; bool debug;
bool xrun; bool xrun;
@ -130,6 +129,7 @@ class RDHPIRecordStream : public QObject,public RDWaveFile
HPI_DATA hpi_data; HPI_DATA hpi_data;
#endif #endif
bool is_open; bool is_open;
uint32_t dma_buffer_size;
}; };

View File

@ -170,14 +170,15 @@ bool RDHPISoundCard::setClockSource(int card,RDHPISoundCard::ClockSource src)
break; break;
case RDHPISoundCard::AesEbu: case RDHPISoundCard::AesEbu:
case RDHPISoundCard::SpDiff: case RDHPISoundCard::SpDiff:
hpi_err=HPI_SampleClock_SetSource(NULL, hpi_err=LogHpi(HPI_SampleClock_SetSource(NULL,
clock_source_control[card], clock_source_control[card],
HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC); HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC),__LINE__);
break; break;
case RDHPISoundCard::WordClock: case RDHPISoundCard::WordClock:
hpi_err=HPI_SampleClock_SetSource(NULL, hpi_err=LogHpi(HPI_SampleClock_SetSource(NULL,
clock_source_control[card], clock_source_control[card],
HPI_SAMPLECLOCK_SOURCE_WORD); HPI_SAMPLECLOCK_SOURCE_WORD),
__LINE__);
break; break;
} }
return hpi_err==0; return hpi_err==0;
@ -226,7 +227,7 @@ RDHPISoundCard::SourceNode RDHPISoundCard::getInputPortMux(int card,int port)
uint16_t index; uint16_t index;
LogHpi(HPI_Multiplexer_GetSource(NULL,input_mux_control[card][port], LogHpi(HPI_Multiplexer_GetSource(NULL,input_mux_control[card][port],
&type,&index)); &type,&index),__LINE__);
return (RDHPISoundCard::SourceNode)type; return (RDHPISoundCard::SourceNode)type;
} }
@ -236,15 +237,15 @@ bool RDHPISoundCard::setInputPortMux(int card,int port,RDHPISoundCard::SourceNod
switch(node) { switch(node) {
case RDHPISoundCard::LineIn: case RDHPISoundCard::LineIn:
if(HPI_Multiplexer_SetSource(NULL, if(HPI_Multiplexer_SetSource(NULL,
input_mux_control[card][port], input_mux_control[card][port],node,0)!=0) {
node,0)!=0) {
return false; return false;
} }
break; break;
case RDHPISoundCard::AesEbuIn: case RDHPISoundCard::AesEbuIn:
if(HPI_Multiplexer_SetSource(NULL, if(LogHpi(HPI_Multiplexer_SetSource(NULL,
input_mux_control[card][port],node, input_mux_control[card][port],node,
input_mux_index[card][port][1])!=0) { input_mux_index[card][port][1]),
__LINE__)!=0) {
return false; return false;
} }
break; break;
@ -263,7 +264,7 @@ unsigned short RDHPISoundCard::getInputPortError(int card,int port)
if(input_port_aesebu[card][port]) { if(input_port_aesebu[card][port]) {
LogHpi(HPI_AESEBU_Receiver_GetErrorStatus(NULL, LogHpi(HPI_AESEBU_Receiver_GetErrorStatus(NULL,
input_port_aesebu_control[card][port], input_port_aesebu_control[card][port],
&error_word)); &error_word),__LINE__);
} }
return error_word; return error_word;
} }
@ -366,7 +367,8 @@ bool RDHPISoundCard::inputStreamMeter(int card,int stream,short *level)
return false; return false;
} }
LogHpi(HPI_MeterGetPeak(NULL, LogHpi(HPI_MeterGetPeak(NULL,
input_stream_meter_control[card][stream],level)); input_stream_meter_control[card][stream],level),
__LINE__);
return true; return true;
} }
@ -379,8 +381,8 @@ bool RDHPISoundCard::outputStreamMeter(int card,int stream,short *level)
if(stream>=card_output_streams[card]) { if(stream>=card_output_streams[card]) {
return false; return false;
} }
LogHpi(HPI_MeterGetPeak(NULL, LogHpi(HPI_MeterGetPeak(NULL,output_stream_meter_control[card][stream],
output_stream_meter_control[card][stream],level)); level),__LINE__);
return true; return true;
} }
@ -393,8 +395,8 @@ bool RDHPISoundCard::inputPortMeter(int card,int port,short *level)
if(port>=card_input_ports[card]) { if(port>=card_input_ports[card]) {
return false; return false;
} }
LogHpi(HPI_MeterGetPeak(NULL, LogHpi(HPI_MeterGetPeak(NULL,input_port_meter_control[card][port],level),
input_port_meter_control[card][port],level)); __LINE__);
return true; return true;
} }
@ -407,7 +409,8 @@ bool RDHPISoundCard::outputPortMeter(int card,int port,short *level)
if(port>=card_output_ports[card]) { if(port>=card_output_ports[card]) {
return false; return false;
} }
LogHpi(HPI_MeterGetPeak(NULL,output_port_meter_control[card][port],level)); LogHpi(HPI_MeterGetPeak(NULL,output_port_meter_control[card][port],level),
__LINE__);
return true; return true;
} }
@ -456,8 +459,8 @@ int RDHPISoundCard::getInputVolume(int card,int stream,int port)
{ {
short gain[2]; short gain[2];
LogHpi(HPI_VolumeGetGain(NULL, LogHpi(HPI_VolumeGetGain(NULL,input_stream_volume_control[card][stream][port],
input_stream_volume_control[card][stream][port],gain)); gain),__LINE__);
return gain[0]; return gain[0];
} }
@ -466,8 +469,7 @@ int RDHPISoundCard::getOutputVolume(int card,int stream,int port)
{ {
short gain[2]; short gain[2];
LogHpi(HPI_VolumeGetGain(NULL, LogHpi(HPI_VolumeGetGain(NULL,output_stream_volume_control[card][stream][port],gain),__LINE__);
output_stream_volume_control[card][stream][port],gain));
return gain[0]; return gain[0];
} }
@ -476,7 +478,8 @@ int RDHPISoundCard::getInputLevel(int card,int port)
{ {
short gain[2]; short gain[2];
LogHpi(HPI_VolumeGetGain(NULL,input_port_level_control[card][port],gain)); LogHpi(HPI_VolumeGetGain(NULL,input_port_level_control[card][port],gain),
__LINE__);
return gain[0]; return gain[0];
} }
@ -485,7 +488,8 @@ int RDHPISoundCard::getOutputLevel(int card,int port)
{ {
short gain[2]; short gain[2];
LogHpi(HPI_VolumeGetGain(NULL,output_port_level_control[card][port],gain)); LogHpi(HPI_VolumeGetGain(NULL,output_port_level_control[card][port],gain),
__LINE__);
return gain[0]; return gain[0];
} }
@ -499,8 +503,8 @@ void RDHPISoundCard::setInputVolume(int card,int stream,int level)
short gain[2]; short gain[2];
gain[0]=level; gain[0]=level;
gain[1]=level; gain[1]=level;
LogHpi(HPI_VolumeSetGain(NULL, LogHpi(HPI_VolumeSetGain(NULL,input_stream_volume_control[card][stream][0],
input_stream_volume_control[card][stream][0],gain)); gain),__LINE__);
} }
@ -514,7 +518,7 @@ void RDHPISoundCard::setOutputVolume(int card,int stream,int port,int level)
gain[1]=level; gain[1]=level;
LogHpi(HPI_VolumeSetGain(NULL, LogHpi(HPI_VolumeSetGain(NULL,
output_stream_volume_control[card][stream][port], output_stream_volume_control[card][stream][port],
gain)); gain),__LINE__);
} }
@ -531,7 +535,7 @@ void RDHPISoundCard::fadeOutputVolume(int card,int stream,int port,
gain[1]=level; gain[1]=level;
LogHpi(HPI_VolumeAutoFadeProfile(NULL, LogHpi(HPI_VolumeAutoFadeProfile(NULL,
output_stream_volume_control[card][stream][port], output_stream_volume_control[card][stream][port],
gain,length,hpi_fade_type)); gain,length,hpi_fade_type),__LINE__);
} }
@ -545,7 +549,8 @@ void RDHPISoundCard::setInputLevel(int card,int port,int level)
for(unsigned i=0;i<HPI_MAX_CHANNELS;i++) { for(unsigned i=0;i<HPI_MAX_CHANNELS;i++) {
gain[i]=level; gain[i]=level;
} }
LogHpi(HPI_LevelSetGain(NULL,input_port_level_control[card][port],gain)); LogHpi(HPI_LevelSetGain(NULL,input_port_level_control[card][port],gain),
__LINE__);
} }
@ -559,7 +564,8 @@ void RDHPISoundCard::setOutputLevel(int card,int port,int level)
for(unsigned i=0;i<HPI_MAX_CHANNELS;i++) { for(unsigned i=0;i<HPI_MAX_CHANNELS;i++) {
gain[i]=level; gain[i]=level;
} }
LogHpi(HPI_LevelSetGain(NULL,output_port_level_control[card][port],gain)); LogHpi(HPI_LevelSetGain(NULL,output_port_level_control[card][port],gain),
__LINE__);
} }
@ -569,7 +575,8 @@ void RDHPISoundCard::setInputMode(int card,int port,
if(!haveInputMode(card,port)) { if(!haveInputMode(card,port)) {
return; return;
} }
LogHpi(HPI_ChannelModeSet(NULL,input_port_mode_control[card][port],mode+1)); LogHpi(HPI_ChannelModeSet(NULL,input_port_mode_control[card][port],mode+1),
__LINE__);
} }
@ -580,13 +587,14 @@ void RDHPISoundCard::setOutputMode(int card,int stream,
return; return;
} }
LogHpi(HPI_ChannelModeSet(NULL,output_stream_mode_control[card][stream], LogHpi(HPI_ChannelModeSet(NULL,output_stream_mode_control[card][stream],
mode+1)); mode+1),__LINE__);
} }
void RDHPISoundCard::setInputStreamVOX(int card,int stream,short gain) void RDHPISoundCard::setInputStreamVOX(int card,int stream,short gain)
{ {
LogHpi(HPI_VoxSetThreshold(NULL,input_stream_vox_control[card][stream],gain)); LogHpi(HPI_VoxSetThreshold(NULL,input_stream_vox_control[card][stream],gain),
__LINE__);
} }
@ -607,7 +615,7 @@ bool RDHPISoundCard::setPassthroughVolume(int card,int in_port,int out_port,
gain[1]=level; gain[1]=level;
LogHpi(HPI_VolumeSetGain(NULL, LogHpi(HPI_VolumeSetGain(NULL,
passthrough_port_volume_control[card][in_port][out_port], passthrough_port_volume_control[card][in_port][out_port],
gain)); gain),__LINE__);
return true; return true;
} }
@ -644,18 +652,19 @@ void RDHPISoundCard::HPIProbe()
hpi_fade_type=HPI_VOLUME_AUTOFADE_LOG; hpi_fade_type=HPI_VOLUME_AUTOFADE_LOG;
#if HPI_VER < 0x00030600 #if HPI_VER < 0x00030600
LogHpi(HPI_SubSysGetVersion(NULL,&dummy_hpi)); LogHpi(HPI_SubSysGetVersion(NULL,&dummy_hpi),__LINE__);
HPI_SubSysFindAdapters(NULL,(uint16_t *)&card_quantity, LogHpi(HPI_SubSysFindAdapters(NULL,(uint16_t *)&card_quantity,
hpi_adapter_list,HPI_MAX_ADAPTERS); hpi_adapter_list,HPI_MAX_ADAPTERS),__LINE__);
#else #else
LogHpi(HPI_SubSysGetVersionEx(NULL,&dummy_hpi)); LogHpi(HPI_SubSysGetVersionEx(NULL,&dummy_hpi),__LINE__);
LogHpi(HPI_SubSysGetNumAdapters(NULL,&card_quantity)); LogHpi(HPI_SubSysGetNumAdapters(NULL,&card_quantity),__LINE__);
#endif // HPI_VER #endif // HPI_VER
for(int i=0;i<card_quantity;i++) { for(int i=0;i<card_quantity;i++) {
#if HPI_VER < 0x00030600 #if HPI_VER < 0x00030600
card_index[i]=i; card_index[i]=i;
#else #else
LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,hpi_adapter_list+i)); LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,hpi_adapter_list+i),
__LINE__);
#endif // HPI_VER #endif // HPI_VER
if((hpi_adapter_list[i]&0xF000)==0x6000) { if((hpi_adapter_list[i]&0xF000)==0x6000) {
timescale_support[i]=true; timescale_support[i]=true;
@ -677,19 +686,19 @@ void RDHPISoundCard::HPIProbe()
card_output_ports[i]=0; card_output_ports[i]=0;
card_description[i]=QString().sprintf("AudioScience %04X [%d]", card_description[i]=QString().sprintf("AudioScience %04X [%d]",
hpi_adapter_list[i],i+1); hpi_adapter_list[i],i+1);
LogHpi(HPI_AdapterOpen(NULL,card_index[i])); LogHpi(HPI_AdapterOpen(NULL,card_index[i]),__LINE__);
LogHpi(HPI_AdapterGetInfo(NULL,card_index[i], LogHpi(HPI_AdapterGetInfo(NULL,card_index[i],
&card_output_streams[i], &card_output_streams[i],
&card_input_streams[i], &card_input_streams[i],
&dummy_version,(uint32_t *)&dummy_serial, &dummy_version,(uint32_t *)&dummy_serial,
&dummy_type)); &dummy_type),__LINE__);
hpi_info[i].setSerialNumber(dummy_serial); hpi_info[i].setSerialNumber(dummy_serial);
hpi_info[i].setHpiVersion(dummy_hpi); hpi_info[i].setHpiVersion(dummy_hpi);
hpi_info[i].setDspMajorVersion((dummy_version>>13)&7); hpi_info[i].setDspMajorVersion((dummy_version>>13)&7);
hpi_info[i].setDspMinorVersion((dummy_version>>7)&63); hpi_info[i].setDspMinorVersion((dummy_version>>7)&63);
hpi_info[i].setPcbVersion((char)(((dummy_version>>3)&7)+'A')); hpi_info[i].setPcbVersion((char)(((dummy_version>>3)&7)+'A'));
hpi_info[i].setAssemblyVersion(dummy_version&7); hpi_info[i].setAssemblyVersion(dummy_version&7);
LogHpi(HPI_AdapterClose(NULL,card_index[i])); LogHpi(HPI_AdapterClose(NULL,card_index[i]),__LINE__);
str=QString(tr("Input Stream")); str=QString(tr("Input Stream"));
for(int j=0;j<card_input_streams[i];j++) { for(int j=0;j<card_input_streams[i];j++) {
input_stream_description[i][j]= input_stream_description[i][j]=
@ -708,7 +717,7 @@ void RDHPISoundCard::HPIProbe()
// Mixer Initialization // Mixer Initialization
// //
for(int i=0;i<card_quantity;i++) { for(int i=0;i<card_quantity;i++) {
LogHpi(HPI_MixerOpen(NULL,card_index[i],&hpi_mixer[i])); LogHpi(HPI_MixerOpen(NULL,card_index[i],&hpi_mixer[i]),__LINE__);
// //
// Get Input Ports // Get Input Ports
@ -765,13 +774,14 @@ void RDHPISoundCard::HPIProbe()
HPI_SOURCENODE_CLOCK_SOURCE,0, HPI_SOURCENODE_CLOCK_SOURCE,0,
0,0, 0,0,
HPI_CONTROL_SAMPLECLOCK, HPI_CONTROL_SAMPLECLOCK,
&clock_source_control[i])); &clock_source_control[i]),__LINE__);
for(int j=0;j<card_input_streams[i];j++) { for(int j=0;j<card_input_streams[i];j++) {
if(HPI_MixerGetControl(NULL,hpi_mixer[i], // VOX Controls if(LogHpi(HPI_MixerGetControl(NULL,hpi_mixer[i], // VOX Controls
0,0, 0,0,
HPI_DESTNODE_ISTREAM,j, HPI_DESTNODE_ISTREAM,j,
HPI_CONTROL_VOX, HPI_CONTROL_VOX,
&input_stream_vox_control[i][j])==0) { &input_stream_vox_control[i][j]),
__LINE__)==0) {
input_stream_vox[i][j]=true; input_stream_vox[i][j]=true;
} }
else { else {
@ -779,18 +789,19 @@ void RDHPISoundCard::HPIProbe()
} }
if(input_mux_type[i]) { if(input_mux_type[i]) {
if(HPI_MixerGetControl(NULL,hpi_mixer[i], // MUX Controls if(LogHpi(HPI_MixerGetControl(NULL,hpi_mixer[i], // MUX Controls
0,0, 0,0,
HPI_DESTNODE_ISTREAM,j, HPI_DESTNODE_ISTREAM,j,
HPI_CONTROL_MULTIPLEXER, HPI_CONTROL_MULTIPLEXER,
&input_mux_control[i][j])==0) { &input_mux_control[i][j]),__LINE__)==0) {
input_stream_mux[i][j]=true; input_stream_mux[i][j]=true;
l=0; l=0;
input_port_mux_type[i][j][0]=false; input_port_mux_type[i][j][0]=false;
input_port_mux_type[i][j][1]=false; input_port_mux_type[i][j][1]=false;
while(HPI_Multiplexer_QuerySource(NULL, while(LogHpi(HPI_Multiplexer_QuerySource(NULL,
input_mux_control[i][j], input_mux_control[i][j],
l++,&type,&index)==0) { l++,&type,&index),
__LINE__)==0) {
switch(type) { switch(type) {
case HPI_SOURCENODE_LINEIN: case HPI_SOURCENODE_LINEIN:
input_port_mux_type[i][j][0]=true; input_port_mux_type[i][j][0]=true;
@ -836,21 +847,23 @@ void RDHPISoundCard::HPIProbe()
output_stream_volume[i][j][k]=false; output_stream_volume[i][j][k]=false;
} }
} }
if(HPI_MixerGetControl(NULL,hpi_mixer[i], if(LogHpi(HPI_MixerGetControl(NULL,hpi_mixer[i],
0,0, 0,0,
HPI_DESTNODE_ISTREAM,j, HPI_DESTNODE_ISTREAM,j,
HPI_CONTROL_METER, HPI_CONTROL_METER,
&input_stream_meter_control[i][j])==0) { &input_stream_meter_control[i][j]),
__LINE__)==0) {
input_stream_meter[i][j]=true; input_stream_meter[i][j]=true;
} }
else { else {
input_stream_meter[i][j]=false; input_stream_meter[i][j]=false;
} }
if(HPI_MixerGetControl(NULL,hpi_mixer[i], if(LogHpi(HPI_MixerGetControl(NULL,hpi_mixer[i],
HPI_SOURCENODE_OSTREAM,j, HPI_SOURCENODE_OSTREAM,j,
0,0, 0,0,
HPI_CONTROL_METER, HPI_CONTROL_METER,
&output_stream_meter_control[i][j])==0) { &output_stream_meter_control[i][j]),
__LINE__)==0) {
output_stream_meter[i][j]=true; output_stream_meter[i][j]=true;
} }
else { else {
@ -928,9 +941,10 @@ void RDHPISoundCard::HPIProbe()
l=0; l=0;
input_port_mux_type[i][j][0]=false; input_port_mux_type[i][j][0]=false;
input_port_mux_type[i][j][1]=false; input_port_mux_type[i][j][1]=false;
while(HPI_Multiplexer_QuerySource(NULL, while(LogHpi(HPI_Multiplexer_QuerySource(NULL,
input_mux_control[i][j], input_mux_control[i][j],
l++,&type,&index)==0) { l++,&type,&index),
__LINE__)==0) {
switch(type) { switch(type) {
case HPI_SOURCENODE_LINEIN: case HPI_SOURCENODE_LINEIN:
input_port_mux_type[i][j][0]=true; input_port_mux_type[i][j][0]=true;
@ -978,13 +992,13 @@ void RDHPISoundCard::HPIProbe()
} }
hpi_err_t RDHPISoundCard::LogHpi(hpi_err_t err) hpi_err_t RDHPISoundCard::LogHpi(hpi_err_t err,int lineno)
{ {
char err_txt[200]; char err_txt[200];
if(err!=0) { if(err!=0) {
HPI_GetErrorText(err,err_txt); HPI_GetErrorText(err,err_txt);
syslog(LOG_NOTICE,"HPI Error: %s",err_txt); syslog(LOG_NOTICE,"HPI Error: %s, %s line %d",err_txt,__FILE__,lineno);
} }
return err; return err;
} }

View File

@ -169,7 +169,7 @@ class RDHPISoundCard : public QObject
private: private:
void HPIProbe(); void HPIProbe();
hpi_err_t LogHpi(hpi_err_t err); hpi_err_t LogHpi(hpi_err_t err,int lineno);
uint16_t card_input_streams[HPI_MAX_ADAPTERS]; uint16_t card_input_streams[HPI_MAX_ADAPTERS];
uint16_t card_output_streams[HPI_MAX_ADAPTERS]; uint16_t card_output_streams[HPI_MAX_ADAPTERS];
uint16_t card_input_ports[HPI_MAX_ADAPTERS]; uint16_t card_input_ports[HPI_MAX_ADAPTERS];