2015-08-30 Fred Gleason <fredg@paravelsystems.com>

* Added PCM24 play-out and capture support for JACK in
	'cae/cae_jack.cpp' and 'cae/cae.h'.
This commit is contained in:
Fred Gleason 2015-08-30 16:13:09 -04:00
parent 398408476c
commit e961971c86
3 changed files with 62 additions and 6 deletions

View File

@ -14857,3 +14857,6 @@
enumeration in 'lib/rdcae.h'.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Added PCM24 to 'lib/export_settings_dialog.cpp'.
2015-08-30 Fred Gleason <fredg@paravelsystems.com>
* Added PCM24 play-out and capture support for JACK in
'cae/cae_jack.cpp' and 'cae/cae.h'.

View File

@ -267,6 +267,8 @@ class MainObject : public QObject
RDWaveFile *jack_record_wave[RD_MAX_STREAMS];
RDWaveFile *jack_play_wave[RD_MAX_STREAMS];
short *jack_wave_buffer;
int *jack_wave32_buffer;
uint8_t *jack_wave24_buffer;
jack_default_audio_sample_t *jack_sample_buffer;
soundtouch::SoundTouch *jack_st_conv[RD_MAX_STREAMS];
short jack_input_volume_db[RD_MAX_STREAMS];

View File

@ -2,9 +2,7 @@
//
// The JACK Driver for the Core Audio Engine component of Rivendell
//
// (C) Copyright 2002-2004 Fred Gleason <fredg@paravelsystems.com>
//
// $Id: cae_jack.cpp,v 1.59.4.6 2012/11/30 16:14:58 cvs Exp $
// (C) Copyright 2002-2015 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
@ -649,6 +647,8 @@ void MainObject::jackInit(RDStation *station)
//
JackInitCallback();
jack_wave_buffer=new short[RINGBUFFER_SIZE];
jack_wave32_buffer=new int[RINGBUFFER_SIZE];
jack_wave24_buffer=new uint8_t[RINGBUFFER_SIZE];
jack_sample_buffer=new jack_default_audio_sample_t[RINGBUFFER_SIZE];
//
@ -884,6 +884,13 @@ bool MainObject::jackLoadRecord(int card,int stream,int coding,int chans,
jack_record_wave[stream]->setBitsPerSample(16);
break;
case 4: // PCM24
jack_record_wave[stream]->setFormatTag(WAVE_FORMAT_PCM);
jack_record_wave[stream]->setChannels(chans);
jack_record_wave[stream]->setSamplesPerSec(samprate);
jack_record_wave[stream]->setBitsPerSample(24);
break;
case 2: // MPEG Layer 2
if(!InitTwoLameEncoder(card,stream,chans,samprate,bitrate)) {
delete jack_record_wave[stream];
@ -1395,11 +1402,26 @@ void MainObject::WriteJackBuffer(int stream,jack_default_audio_sample_t *buffer,
jack_samples_recorded[stream]+=frames;
switch(jack_record_wave[stream]->getFormatTag()) {
case WAVE_FORMAT_PCM:
switch(jack_record_wave[stream]->getBitsPerSample()) {
case 16: // PCM16
n=len/sizeof(jack_default_audio_sample_t);
src_float_to_short_array(buffer,jack_wave_buffer,n);
jack_record_wave[stream]->writeWave(jack_wave_buffer,n*sizeof(short));
break;
case 24: // PCM24
n=len/sizeof(jack_default_audio_sample_t);
src_float_to_int_array(buffer,jack_wave32_buffer,n);
for(unsigned i=0;i<n;i++) {
for(unsigned j=0;j<3;j++) {
jack_wave24_buffer[3*i+j]=((uint8_t *)jack_wave32_buffer)[4*i+j+1];
}
}
jack_record_wave[stream]->writeWave(jack_wave24_buffer,n*3);
break;
}
break;
case WAVE_FORMAT_MPEG:
#ifdef HAVE_TWOLAME
for(unsigned i=0;i<frames;i+=1152) {
@ -1451,6 +1473,35 @@ void MainObject::FillJackOutputStream(int stream)
}
switch(jack_play_wave[stream]->getFormatTag()) {
case WAVE_FORMAT_PCM:
switch(jack_play_wave[stream]->getBitsPerSample()) {
case 16: // PMC16
free=(int)free/jack_output_channels[stream]*jack_output_channels[stream];
n=jack_play_wave[stream]->readWave(jack_wave_buffer,sizeof(short)*free)/
sizeof(short);
if((n!=free)&&(jack_st_conv[stream]==NULL)) {
jack_eof[stream]=true;
jack_stop_timer[stream]->stop();
}
src_short_to_float_array(jack_wave_buffer,jack_sample_buffer,n);
break;
case 24: // PMC24
free=(int)free/jack_output_channels[stream]*jack_output_channels[stream];
n=jack_play_wave[stream]->readWave(jack_wave24_buffer,3*free)/3;
if((n!=free)&&(jack_st_conv[stream]==NULL)) {
jack_eof[stream]=true;
jack_stop_timer[stream]->stop();
}
for(int i=0;i<n;i++) {
for(unsigned j=0;j<3;j++) {
((uint8_t *)jack_wave32_buffer)[4*i+j+1]=jack_wave24_buffer[3*i+j];
}
}
src_int_to_float_array(jack_wave32_buffer,jack_sample_buffer,n);
break;
}
break;
case WAVE_FORMAT_VORBIS:
free=(int)free/jack_output_channels[stream]*jack_output_channels[stream];
n=jack_play_wave[stream]->readWave(jack_wave_buffer,sizeof(short)*free)/