mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-11-03 23:53:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			745 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			745 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//   rdhpirecordstream.cpp
 | 
						|
//
 | 
						|
//   A class for recording Microsoft WAV files.
 | 
						|
//
 | 
						|
//   (C) Copyright 2002-2018 Fred Gleason <fredg@paravelsystems.com>
 | 
						|
//
 | 
						|
//   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
 | 
						|
//   published by the Free Software Foundation.
 | 
						|
//
 | 
						|
//   This program is distributed in the hope that it will be useful,
 | 
						|
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
//   GNU General Public License for more details.
 | 
						|
//
 | 
						|
//   You should have received a copy of the GNU General Public
 | 
						|
//   License along with this program; if not, write to the Free Software
 | 
						|
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
//
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <syslog.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <qobject.h>
 | 
						|
#include <qwidget.h>
 | 
						|
#include <qstring.h>
 | 
						|
#include <qdatetime.h>
 | 
						|
 | 
						|
#include <rdhpirecordstream.h>
 | 
						|
 | 
						|
RDHPIRecordStream::RDHPIRecordStream(RDHPISoundCard *card,QWidget *parent) 
 | 
						|
  :QObject(parent),RDWaveFile()
 | 
						|
{ 
 | 
						|
  int quan;
 | 
						|
  uint16_t type[HPI_MAX_ADAPTERS];
 | 
						|
  struct hpi_format fmt;
 | 
						|
  uint32_t dma_size=0;
 | 
						|
 | 
						|
  if(getenv(DEBUG_VAR)==NULL) {
 | 
						|
    debug=false;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    debug=true;
 | 
						|
    printf("RDHPIRecordStream: debugging enabled\n");
 | 
						|
  }
 | 
						|
  if(getenv(XRUN_VAR)==NULL) {
 | 
						|
    xrun=false;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    xrun=true;
 | 
						|
    printf("RDHPIRecordStream: xrun notification enabled\n");
 | 
						|
  }
 | 
						|
 | 
						|
  sound_card=card;
 | 
						|
 | 
						|
  card_number=-1;
 | 
						|
  stream_number=-1;
 | 
						|
  is_ready=false;
 | 
						|
  is_recording=false;
 | 
						|
  is_paused=false;
 | 
						|
  stopping=false;
 | 
						|
  record_started=false;
 | 
						|
  record_length=0;
 | 
						|
  is_open=false;
 | 
						|
  pdata=NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get Adapter Indices
 | 
						|
  //
 | 
						|
#if HPI_VER < 0x00030600
 | 
						|
  for(unsigned i=0;i<HPI_MAX_ADAPTERS;i++) {
 | 
						|
    card_index[i]=i;
 | 
						|
  }
 | 
						|
#else
 | 
						|
  LogHpi(HPI_SubSysGetNumAdapters(NULL,&quan),__LINE__);
 | 
						|
  for(int i=0;i<quan;i++) {
 | 
						|
    LogHpi(HPI_SubSysGetAdapter(NULL,i,card_index+i,type+i),__LINE__);
 | 
						|
  }
 | 
						|
#endif  // HPI_VER
 | 
						|
 | 
						|
  //
 | 
						|
  // 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()));
 | 
						|
 | 
						|
  length_timer=new QTimer(this);
 | 
						|
  connect(length_timer,SIGNAL(timeout()),this,SLOT(pause()));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
RDHPIRecordStream::~RDHPIRecordStream()
 | 
						|
{
 | 
						|
  if(pdata!=NULL) {
 | 
						|
    delete pdata;
 | 
						|
  }
 | 
						|
} 
 | 
						|
 | 
						|
 | 
						|
QString RDHPIRecordStream::errorString(RDHPIRecordStream::Error err)
 | 
						|
{
 | 
						|
  QString str;
 | 
						|
 | 
						|
  switch(err) {
 | 
						|
  case RDHPIRecordStream::Ok:
 | 
						|
    return QString(tr("Ok"));
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDHPIRecordStream::NoFile:
 | 
						|
    return QString(tr("Unable to create/open file"));
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDHPIRecordStream::NoStream:
 | 
						|
    return QString(tr("Input stream unavailable"));
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDHPIRecordStream::AlreadyOpen:
 | 
						|
    return QString(tr("Stream is already open"));
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    str=QString(tr("Unknown Error:"));
 | 
						|
    return QString().sprintf("%s %d\n",(const char *)str,err);
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
RDHPIRecordStream::Error RDHPIRecordStream::createWave()
 | 
						|
{
 | 
						|
  if(is_open) {
 | 
						|
    return RDHPIRecordStream::AlreadyOpen;
 | 
						|
  }
 | 
						|
  if(!RDWaveFile::createWave()) {
 | 
						|
    return RDHPIRecordStream::NoFile;
 | 
						|
  }
 | 
						|
  if(!GetStream()) {
 | 
						|
    closeWave();
 | 
						|
    return RDHPIRecordStream::NoStream;
 | 
						|
  }
 | 
						|
  is_open=true;
 | 
						|
  return RDHPIRecordStream::Ok;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
RDHPIRecordStream::Error RDHPIRecordStream::createWave(QString filename)
 | 
						|
{
 | 
						|
  if(is_open) {
 | 
						|
    return RDHPIRecordStream::AlreadyOpen;
 | 
						|
  }
 | 
						|
  setName(filename);
 | 
						|
  return createWave();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::closeWave()
 | 
						|
{
 | 
						|
  if(!is_open) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if(getState()!=RDHPIRecordStream::Stopped) {
 | 
						|
    stop();
 | 
						|
  }
 | 
						|
  RDWaveFile::closeWave(samples_recorded);
 | 
						|
  FreeStream();
 | 
						|
  is_open=false;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDHPIRecordStream::formatSupported(RDWaveFile::Format format)
 | 
						|
{
 | 
						|
#if HPI_VER < HPI_VERSION_CONSTRUCTOR(3L,10,0)
 | 
						|
  HPI_FORMAT hformat;
 | 
						|
#else
 | 
						|
  struct hpi_format hformat;
 | 
						|
#endif
 | 
						|
  hpi_handle_t histream;
 | 
						|
  bool found=false;
 | 
						|
 | 
						|
  if(card_number<0) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if(format==RDWaveFile::Vorbis) {
 | 
						|
#ifdef HAVE_VORBIS
 | 
						|
    return true;
 | 
						|
#endif  // HAVE_VORBIS
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if(!is_open) {
 | 
						|
    for(int i=0;i<sound_card->getCardInputStreams(card_number);i++) {
 | 
						|
      if(LogHpi(HPI_InStreamOpen(NULL,card_index[card_number],i,&histream),
 | 
						|
		__LINE__)==0) {
 | 
						|
	found=true;
 | 
						|
	break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if(!found) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if(HPI_InStreamHostBufferAllocate(NULL,histream,dma_buffer_size));
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    histream=hpi_stream;
 | 
						|
  }
 | 
						|
  switch(format) {
 | 
						|
  case RDWaveFile::Pcm8:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_PCM8_UNSIGNED,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDWaveFile::Pcm16:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_PCM16_SIGNED,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDWaveFile::Pcm24:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_PCM24_SIGNED,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDWaveFile::MpegL1:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L1,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDWaveFile::MpegL2:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L2,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  case RDWaveFile::MpegL3:
 | 
						|
    LogHpi(HPI_FormatCreate(&hformat,getChannels(),HPI_FORMAT_MPEG_L3,
 | 
						|
			    getSamplesPerSec(),getHeadBitRate(),0),__LINE__);
 | 
						|
    state=LogHpi(HPI_InStreamQueryFormat(NULL,histream,&hformat),__LINE__);
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    state=1;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  if(!is_open) {
 | 
						|
    if(HPI_InStreamHostBufferFree(NULL,histream));
 | 
						|
    LogHpi(HPI_InStreamClose(NULL,histream),__LINE__);
 | 
						|
  }
 | 
						|
  if(state!=0) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDHPIRecordStream::formatSupported()
 | 
						|
{
 | 
						|
  switch(getFormatTag()) {
 | 
						|
  case WAVE_FORMAT_PCM:
 | 
						|
    switch(getBitsPerSample()) {
 | 
						|
    case 8:
 | 
						|
      return formatSupported(RDWaveFile::Pcm8);
 | 
						|
      break;
 | 
						|
 | 
						|
    case 16:
 | 
						|
      return formatSupported(RDWaveFile::Pcm16);
 | 
						|
      break;
 | 
						|
 | 
						|
    case 24:
 | 
						|
      return formatSupported(RDWaveFile::Pcm24);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case WAVE_FORMAT_MPEG:
 | 
						|
    switch(getHeadLayer()) {
 | 
						|
    case 1:
 | 
						|
      return formatSupported(RDWaveFile::MpegL1);
 | 
						|
      break;
 | 
						|
 | 
						|
    case 2:
 | 
						|
      return formatSupported(RDWaveFile::MpegL2);
 | 
						|
      break;
 | 
						|
 | 
						|
    case 3:
 | 
						|
      return formatSupported(RDWaveFile::MpegL3);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int RDHPIRecordStream::getCard() const
 | 
						|
{
 | 
						|
  return card_number;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::setCard(int card)
 | 
						|
{
 | 
						|
  if(!is_recording) {
 | 
						|
    card_number=card;
 | 
						|
    if(debug) {
 | 
						|
      printf("RDHPIRecordStream: using card %d\n",card_number);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int RDHPIRecordStream::getStream() const
 | 
						|
{
 | 
						|
  return stream_number;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::setStream(int stream)
 | 
						|
{
 | 
						|
  stream_number=stream;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDHPIRecordStream::haveInputVOX() const
 | 
						|
{
 | 
						|
  return sound_card->haveInputStreamVOX(card_number,stream_number);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
RDHPIRecordStream::RecordState RDHPIRecordStream::getState()
 | 
						|
{
 | 
						|
  if(is_recording) {
 | 
						|
    if(record_started) {
 | 
						|
      return RDHPIRecordStream::RecordStarted;
 | 
						|
    }
 | 
						|
    return RDHPIRecordStream::Recording;
 | 
						|
  }
 | 
						|
  if(is_paused) {
 | 
						|
    return RDHPIRecordStream::Paused;
 | 
						|
  }
 | 
						|
  if(is_ready) {
 | 
						|
    return RDHPIRecordStream::RecordReady;
 | 
						|
  }
 | 
						|
  return RDHPIRecordStream::Stopped;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int RDHPIRecordStream::getPosition() const
 | 
						|
{
 | 
						|
  if((!is_recording)&&(!is_ready)&&(!is_paused)) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
  return samples_recorded;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
unsigned RDHPIRecordStream::samplesRecorded() const
 | 
						|
{
 | 
						|
  return samples_recorded;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDHPIRecordStream::recordReady()
 | 
						|
{
 | 
						|
  hpi_err_t hpi_error=0;
 | 
						|
  char hpi_text[200];
 | 
						|
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: received recordReady()\n");
 | 
						|
  }
 | 
						|
  if(!is_open) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if((!is_recording)&&(!is_paused)) {
 | 
						|
    resetWave();
 | 
						|
    if(LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,
 | 
						|
				    &state,&buffer_size,&data_recorded,
 | 
						|
				    &samples_recorded,&reserved),__LINE__)!=0) {
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: HPI_InStreamGetInfoEx() failed\n");
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    fragment_size=buffer_size/4;
 | 
						|
    if(fragment_size>192000) {  // ALSA Compatibility Limitation
 | 
						|
      fragment_size=192000;
 | 
						|
    }
 | 
						|
    fragment_time=(1000*fragment_size)/(getAvgBytesPerSec());
 | 
						|
    if(pdata!=NULL) {
 | 
						|
      delete pdata;
 | 
						|
    }
 | 
						|
    pdata=(uint8_t *)malloc(fragment_size);
 | 
						|
    if(pdata==NULL) {
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: couldn't allocate buffer\n");
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    switch(getFormatTag()) {
 | 
						|
    case WAVE_FORMAT_PCM:
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: using PCM%d format\n",
 | 
						|
	       getBitsPerSample());
 | 
						|
      }
 | 
						|
      switch(getBitsPerSample()) {
 | 
						|
      case 8:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_PCM8_UNSIGNED,
 | 
						|
					  getSamplesPerSec(),0,0),__LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      case 16:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_PCM16_SIGNED,
 | 
						|
					  getSamplesPerSec(),0,0),__LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      case 24:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_PCM24_SIGNED,
 | 
						|
					  getSamplesPerSec(),0,0),__LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      case 32:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_PCM32_SIGNED,
 | 
						|
					  getSamplesPerSec(),0,0),__LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      default:
 | 
						|
	if(debug) {
 | 
						|
	  printf("RDHPIRecordStream: unsupported sample size\n");
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case WAVE_FORMAT_MPEG:
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: using MPEG-1 Layer %d\n",getHeadLayer());
 | 
						|
      }
 | 
						|
      switch(getHeadLayer()) {
 | 
						|
      case 1:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_MPEG_L1,getSamplesPerSec(),
 | 
						|
					  getHeadBitRate(),getHeadFlags()),
 | 
						|
			 __LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      case 2:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_MPEG_L2,getSamplesPerSec(),
 | 
						|
					  getHeadBitRate(),getHeadFlags()),
 | 
						|
			 __LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      case 3:
 | 
						|
	hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					  HPI_FORMAT_MPEG_L3,getSamplesPerSec(),
 | 
						|
					  getHeadBitRate(),getHeadFlags()),
 | 
						|
			 __LINE__);
 | 
						|
	break;
 | 
						|
 | 
						|
      default:
 | 
						|
	hpi_error=LogHpi(HPI_AdapterClose(NULL,card_index[card_number]),
 | 
						|
			 __LINE__);
 | 
						|
	if(debug) {
 | 
						|
	  printf("RDHPIRecordStream: invalid MPEG-1 layer\n");
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
      }
 | 
						|
      if(getMextChunk()) {
 | 
						|
	setMextHomogenous(true);
 | 
						|
	setMextPaddingUsed(false);
 | 
						|
	setMextHackedBitRate(true);
 | 
						|
	setMextFreeFormat(false);
 | 
						|
	setMextFrameSize(144*getHeadBitRate()/getSamplesPerSec());
 | 
						|
	setMextAncillaryLength(5);
 | 
						|
	setMextLeftEnergyPresent(true);
 | 
						|
	if(getChannels()>1) {
 | 
						|
	  setMextRightEnergyPresent(true);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
	  setMextRightEnergyPresent(false);
 | 
						|
	}
 | 
						|
	setMextPrivateDataPresent(false);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case WAVE_FORMAT_VORBIS:
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: using OggVorbis\n");
 | 
						|
      }
 | 
						|
      hpi_error=LogHpi(HPI_FormatCreate(&format,getChannels(),
 | 
						|
					HPI_FORMAT_PCM16_SIGNED,
 | 
						|
					getSamplesPerSec(),0,0),__LINE__);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: invalid format tag\n");
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if((hpi_error=LogHpi(HPI_InStreamQueryFormat(NULL,hpi_stream,
 | 
						|
						 &format),__LINE__))!=0) {
 | 
						|
      if(debug) {
 | 
						|
	HPI_GetErrorText(hpi_error,hpi_text);
 | 
						|
	printf("Num: %d\n",hpi_error);
 | 
						|
	printf("RDHPIRecordStream: %s\n",hpi_text);
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  }
 | 
						|
#if HPI_VER < 0x00030500
 | 
						|
  LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,fragment_size),__LINE__);
 | 
						|
#endif
 | 
						|
  hpi_error=LogHpi(HPI_InStreamSetFormat(NULL,hpi_stream,&format),__LINE__);
 | 
						|
  hpi_error=LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
 | 
						|
//  clock->start(2*fragment_time/3);
 | 
						|
  clock->start(RDHPIRECORDSTREAM_CLOCK_INTERVAL);
 | 
						|
  is_ready=true;
 | 
						|
  is_recording=false;
 | 
						|
  is_paused=false;
 | 
						|
  stopping=false;
 | 
						|
  emit isStopped(false);
 | 
						|
  emit ready();
 | 
						|
  emit stateChanged(card_number,stream_number,1);  // RecordReady
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: emitted isStopped(false)\n");
 | 
						|
    printf("RDHPIRecordStream: emitted ready()\n");
 | 
						|
    printf("RDHPIRecordStream: emitted stateChanged(%d,%d,RDHPIRecordStream::RecordReady)\n",card_number,stream_number);
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::record()
 | 
						|
{
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: received record()\n");
 | 
						|
  }
 | 
						|
  if(!is_open) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if(!is_ready) {
 | 
						|
    recordReady();
 | 
						|
  }
 | 
						|
  record_started=false;
 | 
						|
  LogHpi(HPI_InStreamReset(NULL,hpi_stream),__LINE__);
 | 
						|
  LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
 | 
						|
  is_recording=true;
 | 
						|
  is_paused=false;
 | 
						|
  emit isStopped(false);
 | 
						|
  emit recording();
 | 
						|
  emit stateChanged(card_number,stream_number,0);  // Recording
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: emitted isStopped(false)\n");
 | 
						|
    printf("RDHPIRecordStream: emitted recording()\n");
 | 
						|
    printf("RDHPIRecordStream: emitted stateChanged(%d,%d,RDHPIRecordStream::Recording)\n",card_number,stream_number);
 | 
						|
  }
 | 
						|
  tickClock();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::pause()
 | 
						|
{
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: received pause()\n");
 | 
						|
  }
 | 
						|
  if(!is_recording) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  LogHpi(HPI_InStreamStop(NULL,hpi_stream),__LINE__);
 | 
						|
  tickClock();
 | 
						|
  LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size,
 | 
						|
			       &data_recorded,&samples_recorded,&reserved),
 | 
						|
	 __LINE__);
 | 
						|
  is_recording=false;
 | 
						|
  is_paused=true;
 | 
						|
  LogHpi(HPI_InStreamStart(NULL,hpi_stream),__LINE__);
 | 
						|
  emit paused();
 | 
						|
  emit stateChanged(card_number,stream_number,2);  // Paused
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: emitted paused()\n");
 | 
						|
    printf("RDHPIRecordStream: emitted stateChanged(%d,%d,RDHPIRecordStream::Paused)\n",card_number,stream_number);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::stop()
 | 
						|
{
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: received stop()\n");
 | 
						|
  }
 | 
						|
  if(is_ready|is_recording|is_paused) {
 | 
						|
    LogHpi(HPI_InStreamStop(NULL,hpi_stream),__LINE__);
 | 
						|
    tickClock();
 | 
						|
    clock->stop();
 | 
						|
    is_recording=false;
 | 
						|
    is_paused=false;
 | 
						|
    is_ready=false;
 | 
						|
    if(pdata!=NULL) {
 | 
						|
      delete pdata;
 | 
						|
      pdata=NULL;
 | 
						|
    }
 | 
						|
    emit isStopped(true);
 | 
						|
    emit stopped();
 | 
						|
    emit stateChanged(card_number,stream_number,RDHPIRecordStream::Stopped);
 | 
						|
    emit position(0);
 | 
						|
    if(debug) {
 | 
						|
      printf("RDHPIRecordStream: emitted isStopped(true)\n");
 | 
						|
      printf("RDHPIRecordStream: emitted stopped()\n");
 | 
						|
      printf("RDHPIRecordStream: emitted stateChanged(%d,%d,RDHPIRecordStream::Stopped)\n",card_number,stream_number);
 | 
						|
      printf("RDHPIRecordStream: emitted position(0)\n");
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::setInputVOX(int gain)
 | 
						|
{
 | 
						|
  sound_card->setInputStreamVOX(card_number,stream_number,gain);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::setRecordLength(int length)
 | 
						|
{
 | 
						|
  record_length=length;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::tickClock()
 | 
						|
{
 | 
						|
  LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,
 | 
						|
			       &state,&buffer_size,&data_recorded,
 | 
						|
			       &samples_recorded,&reserved),__LINE__);
 | 
						|
  if((!record_started)&&(is_recording)) {
 | 
						|
    if(samples_recorded>0) {
 | 
						|
      if(record_length>0) {
 | 
						|
        length_timer->start(record_length,true);
 | 
						|
      }
 | 
						|
      emit recordStart();
 | 
						|
      emit stateChanged(card_number,stream_number,4);  // RecordStarted
 | 
						|
      if(debug) {
 | 
						|
	printf("RDHPIRecordStream: emitted recordStart()\n");
 | 
						|
	printf("RDHPIRecordStream: emitted stateChanged(%d,%d,RDHPIRecordStream::RecordStarted)\n",card_number,stream_number);
 | 
						|
      }
 | 
						|
      record_started=true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  while(data_recorded>fragment_size) {
 | 
						|
#if HPI_VER > 0x00030500
 | 
						|
    LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,fragment_size),__LINE__);
 | 
						|
#else
 | 
						|
    LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data),__LINE__);
 | 
						|
#endif
 | 
						|
    if(is_recording) {
 | 
						|
      writeWave(pdata,fragment_size);
 | 
						|
    }
 | 
						|
    LogHpi(HPI_InStreamGetInfoEx(NULL,hpi_stream,&state,&buffer_size,
 | 
						|
				 &data_recorded,&samples_recorded,&reserved),
 | 
						|
	   __LINE__);
 | 
						|
  }
 | 
						|
  if(state==HPI_STATE_STOPPED) {
 | 
						|
#if HPI_VER > 0x00030500
 | 
						|
    LogHpi(HPI_InStreamReadBuf(NULL,hpi_stream,pdata,data_recorded),__LINE__);
 | 
						|
#else
 | 
						|
    LogHpi(HPI_DataCreate(&hpi_data,&format,pdata,data_recorded),__LINE__);
 | 
						|
    LogHpi(HPI_InStreamRead(NULL,hpi_stream,&hpi_data),__LINE__);
 | 
						|
#endif
 | 
						|
    if(is_recording) {
 | 
						|
      writeWave(pdata,data_recorded);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  emit position(samples_recorded);
 | 
						|
  if(debug) {
 | 
						|
    printf("RDHPIRecordStream: emitted position(%u)\n",
 | 
						|
	   (unsigned)samples_recorded);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDHPIRecordStream::GetStream()
 | 
						|
{
 | 
						|
  hpi_err_t hpi_err;
 | 
						|
  char hpi_text[100];
 | 
						|
 | 
						|
  if((hpi_err=
 | 
						|
      LogHpi(HPI_InStreamOpen(NULL,card_index[card_number],stream_number,
 | 
						|
			      &hpi_stream),__LINE__))!=0) {
 | 
						|
    if(debug) {
 | 
						|
      HPI_GetErrorText(hpi_err,hpi_text);
 | 
						|
      fprintf(stderr,"*** HPI Error: %s ***\n",hpi_text);
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  if(HPI_InStreamHostBufferAllocate(NULL,hpi_stream,dma_buffer_size));
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void RDHPIRecordStream::FreeStream()
 | 
						|
{
 | 
						|
  if(HPI_InStreamHostBufferFree(NULL,hpi_stream));
 | 
						|
  LogHpi(HPI_InStreamClose(NULL,hpi_stream),__LINE__);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
hpi_err_t RDHPIRecordStream::LogHpi(hpi_err_t err,int lineno)
 | 
						|
{
 | 
						|
  char err_txt[200];
 | 
						|
 | 
						|
  if(err!=0) {
 | 
						|
    HPI_GetErrorText(err,err_txt);
 | 
						|
    syslog(LOG_NOTICE,"HPI Error: %s, %s line %d",err_txt,__FILE__,lineno);
 | 
						|
  }
 | 
						|
  return err;
 | 
						|
}
 |