2016-07-12 Fred Gleason <fredg@paravelsystems.com>

* Implemented storage of RDXML data structures within a 'rdxl' chunk
	in WAV files.
This commit is contained in:
Fred Gleason 2016-07-12 14:36:17 -04:00
parent fc332c3655
commit b64b01b148
6 changed files with 116 additions and 7 deletions

View File

@ -15281,3 +15281,6 @@
2016-07-12 Fred Gleason <fredg@paravelsystems.com> 2016-07-12 Fred Gleason <fredg@paravelsystems.com>
* Added an '--xml' switch to rdimport(1) in * Added an '--xml' switch to rdimport(1) in
'utils/rdimport/rdimport.cpp' and 'utils/rdimport/rdimport.h'. 'utils/rdimport/rdimport.cpp' and 'utils/rdimport/rdimport.h'.
2016-07-12 Fred Gleason <fredg@paravelsystems.com>
* Implemented storage of RDXML data structures within a 'rdxl' chunk
in WAV files.

View File

@ -109,12 +109,24 @@ RDWaveData *RDAudioConvert::sourceWaveData() const
} }
QString RDAudioConvert::sourceRdxl() const
{
return conv_src_rdxl;
}
void RDAudioConvert::setDestinationWaveData(RDWaveData *wavedata) void RDAudioConvert::setDestinationWaveData(RDWaveData *wavedata)
{ {
conv_dst_wavedata=wavedata; conv_dst_wavedata=wavedata;
} }
void RDAudioConvert::setDestinationRdxl(const QString &xml)
{
conv_dst_rdxl=xml;
}
void RDAudioConvert::setRange(int start_pt,int end_pt) void RDAudioConvert::setRange(int start_pt,int end_pt)
{ {
conv_start_point=start_pt; conv_start_point=start_pt;
@ -1602,6 +1614,7 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage3Layer2Wav(SNDFILE *src_sf,
wave->setMextChunk(true); wave->setMextChunk(true);
wave->setCartChunk(conv_dst_wavedata!=NULL); wave->setCartChunk(conv_dst_wavedata!=NULL);
wave->setLevlChunk(true); wave->setLevlChunk(true);
wave->setRdxlContents(conv_dst_rdxl);
unlink(dstfile); unlink(dstfile);
if(!wave->createWave(conv_dst_wavedata,conv_start_point)) { if(!wave->createWave(conv_dst_wavedata,conv_start_point)) {
return RDAudioConvert::ErrorNoDestination; return RDAudioConvert::ErrorNoDestination;
@ -1789,6 +1802,7 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage3Pcm16(SNDFILE *src_sf,
wave->setBitsPerSample(16); wave->setBitsPerSample(16);
wave->setBextChunk(true); wave->setBextChunk(true);
wave->setCartChunk(conv_dst_wavedata!=NULL); wave->setCartChunk(conv_dst_wavedata!=NULL);
wave->setRdxlContents(conv_dst_rdxl);
if((conv_dst_wavedata!=NULL)&&(conv_settings->normalizationLevel()!=0)) { if((conv_dst_wavedata!=NULL)&&(conv_settings->normalizationLevel()!=0)) {
wave->setCartLevelRef(32768* wave->setCartLevelRef(32768*
exp10((double)conv_settings->normalizationLevel()/20.0)); exp10((double)conv_settings->normalizationLevel()/20.0));
@ -1831,6 +1845,7 @@ RDAudioConvert::ErrorCode RDAudioConvert::Stage3Pcm24(SNDFILE *src_sf,
wave->setBitsPerSample(24); wave->setBitsPerSample(24);
wave->setBextChunk(true); wave->setBextChunk(true);
wave->setCartChunk(conv_dst_wavedata!=NULL); wave->setCartChunk(conv_dst_wavedata!=NULL);
wave->setRdxlContents(conv_dst_rdxl);
if((conv_dst_wavedata!=NULL)&&(conv_settings->normalizationLevel()!=0)) { if((conv_dst_wavedata!=NULL)&&(conv_settings->normalizationLevel()!=0)) {
wave->setCartLevelRef(32768* wave->setCartLevelRef(32768*
exp10((double)conv_settings->normalizationLevel()/20.0)); exp10((double)conv_settings->normalizationLevel()/20.0));

View File

@ -54,7 +54,9 @@ class RDAudioConvert : public QObject
void setDestinationFile(const QString &filename); void setDestinationFile(const QString &filename);
void setDestinationSettings(RDSettings *settings); void setDestinationSettings(RDSettings *settings);
RDWaveData *sourceWaveData() const; RDWaveData *sourceWaveData() const;
QString sourceRdxl() const;
void setDestinationWaveData(RDWaveData *wavedata); void setDestinationWaveData(RDWaveData *wavedata);
void setDestinationRdxl(const QString &xml);
void setRange(int start_pt,int end_pt); void setRange(int start_pt,int end_pt);
void setSpeedRatio(float ratio); void setSpeedRatio(float ratio);
RDAudioConvert::ErrorCode convert(); RDAudioConvert::ErrorCode convert();
@ -108,6 +110,8 @@ class RDAudioConvert : public QObject
RDSettings *conv_settings; RDSettings *conv_settings;
RDWaveData *conv_src_wavedata; RDWaveData *conv_src_wavedata;
RDWaveData *conv_dst_wavedata; RDWaveData *conv_dst_wavedata;
QString conv_src_rdxl;
QString conv_dst_rdxl;
float conv_peak_sample; float conv_peak_sample;
int conv_src_converter; int conv_src_converter;
void *conv_mad_handle; void *conv_mad_handle;

View File

@ -32,6 +32,7 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <arpa/inet.h>
#include <id3/tag.h> #include <id3/tag.h>
#include <id3/misc_support.h> #include <id3/misc_support.h>
@ -44,6 +45,7 @@
#include <qdatetime.h> #include <qdatetime.h>
#include <rd.h> #include <rd.h>
#include <rdcart.h>
#include <rdwavefile.h> #include <rdwavefile.h>
#include <rdconf.h> #include <rdconf.h>
#include <rdmp4.h> #include <rdmp4.h>
@ -172,6 +174,7 @@ RDWaveFile::RDWaveFile(QString file_name)
atx_offset=0; atx_offset=0;
scot_chunk=false; scot_chunk=false;
av10_chunk=false; av10_chunk=false;
rdxl_chunk=false;
ptr_offset_msecs=0; ptr_offset_msecs=0;
} }
@ -284,6 +287,7 @@ bool RDWaveFile::openWave(RDWaveData *data)
GetScot(wave_file.handle()); GetScot(wave_file.handle());
GetAv10(wave_file.handle()); GetAv10(wave_file.handle());
GetAir1(wave_file.handle()); GetAir1(wave_file.handle());
GetRdxl(wave_file.handle());
break; break;
case RDWaveFile::Aiff: case RDWaveFile::Aiff:
@ -561,6 +565,9 @@ bool RDWaveFile::createWave(RDWaveData *data,unsigned ptr_offset)
WriteChunk(wave_file.handle(),"mext",mext_chunk_data, WriteChunk(wave_file.handle(),"mext",mext_chunk_data,
MEXT_CHUNK_SIZE); MEXT_CHUNK_SIZE);
} }
if(!rdxl_contents.isEmpty()) {
WriteChunk(wave_file.handle(),"rdxl",rdxl_contents);
}
wave_type=RDWaveFile::Wave; wave_type=RDWaveFile::Wave;
write(wave_file.handle(),"data\0\0\0\0",8); write(wave_file.handle(),"data\0\0\0\0",8);
data_start=lseek(wave_file.handle(),0,SEEK_CUR); data_start=lseek(wave_file.handle(),0,SEEK_CUR);
@ -878,6 +885,7 @@ void RDWaveFile::closeWave(int samples)
serial_number=-1; serial_number=-1;
atx_offset=0; atx_offset=0;
av10_chunk=false; av10_chunk=false;
rdxl_chunk=false;
} }
@ -2127,6 +2135,23 @@ bool RDWaveFile::getAIR1Chunk() const
} }
bool RDWaveFile::getRdxlChunk() const
{
return rdxl_chunk;
}
QString RDWaveFile::getRdxlContents() const
{
return rdxl_contents;
}
void RDWaveFile::setRdxlContents(const QString &xml)
{
rdxl_contents=xml;
}
RDWaveFile::Type RDWaveFile::GetType(int fd) RDWaveFile::Type RDWaveFile::GetType(int fd)
{ {
@ -2442,6 +2467,21 @@ void RDWaveFile::WriteChunk(int fd,const char *cname,unsigned char *buf,
} }
void RDWaveFile::WriteChunk(int fd,const char *cname,const QString &contents)
{
unsigned char size_buf[4];
size_buf[0]=contents.length()&0xff;
size_buf[1]=(contents.length()>>8)&0xff;
size_buf[2]=(contents.length()>>16)&0xff;
size_buf[3]=(contents.length()>>24)&0xff;
lseek(fd,0,SEEK_END);
write(fd,cname,4);
write(fd,size_buf,4);
write(fd,contents,contents.length());
}
bool RDWaveFile::GetFmt(int fd) bool RDWaveFile::GetFmt(int fd)
{ {
unsigned chunk_size; unsigned chunk_size;
@ -3028,6 +3068,33 @@ bool RDWaveFile::GetAir1(int fd)
} }
bool RDWaveFile::GetRdxl(int fd)
{
off_t pos;
unsigned chunk_size=0;
char *chunk=NULL;
if((pos=FindChunk(fd,"rdxl",&chunk_size))<0) {
return false;
}
lseek(fd,SEEK_SET,pos);
chunk=new char[chunk_size+1];
memset(chunk,0,chunk_size+1);
read(fd,chunk,chunk_size);
rdxl_contents=QString(chunk);
delete chunk;
if(wave_data!=NULL) {
std::vector<RDWaveData> wavedatas;
if(RDCart::readXml(&wavedatas,rdxl_contents)>1) {
*wave_data=wavedatas[1];
}
}
return true;
}
bool RDWaveFile::GetComm(int fd) bool RDWaveFile::GetComm(int fd)
{ {
unsigned chunk_size; unsigned chunk_size;

View File

@ -77,6 +77,7 @@
#define AV10_CHUNK_SIZE 512 #define AV10_CHUNK_SIZE 512
#define AIR1_CHUNK_SIZE 2048 #define AIR1_CHUNK_SIZE 2048
#define COMM_CHUNK_SIZE 18 #define COMM_CHUNK_SIZE 18
#define RDXL_CHUNK_SIZE 4
// //
// Maximum Header Size for ATX Files // Maximum Header Size for ATX Files
@ -1005,6 +1006,13 @@ class RDWaveFile
bool getAIR1Chunk() const; bool getAIR1Chunk() const;
/**
* Returns true if the WAV file contains an RDXL chunk, otherwise false.
**/
bool getRdxlChunk() const;
QString getRdxlContents() const;
void setRdxlContents(const QString &xml);
double getNormalizeLevel() const; double getNormalizeLevel() const;
void setNormalizeLevel(double level); void setNormalizeLevel(double level);
@ -1024,6 +1032,7 @@ class RDWaveFile
unsigned char *chunk,size_t size,bool big_end=false); unsigned char *chunk,size_t size,bool big_end=false);
void WriteChunk(int fd,const char *cname,unsigned char *buf,unsigned size, void WriteChunk(int fd,const char *cname,unsigned char *buf,unsigned size,
bool big_end=false); bool big_end=false);
void WriteChunk(int fd,const char *cname,const QString &contents);
bool GetFmt(int fd); bool GetFmt(int fd);
bool GetFact(int fd); bool GetFact(int fd);
bool GetCart(int fd); bool GetCart(int fd);
@ -1034,6 +1043,7 @@ class RDWaveFile
bool GetScot(int fd); bool GetScot(int fd);
bool GetAv10(int fd); bool GetAv10(int fd);
bool GetAir1(int fd); bool GetAir1(int fd);
bool GetRdxl(int fd);
bool GetComm(int fd); bool GetComm(int fd);
bool ReadListElement(unsigned char *buffer,unsigned *offset,unsigned size); bool ReadListElement(unsigned char *buffer,unsigned *offset,unsigned size);
bool ReadTmcMetadata(int fd); bool ReadTmcMetadata(int fd);
@ -1199,6 +1209,9 @@ class RDWaveFile
bool AIR1_chunk; bool AIR1_chunk;
unsigned char AIR1_chunk_data[AIR1_CHUNK_SIZE]; unsigned char AIR1_chunk_data[AIR1_CHUNK_SIZE];
bool rdxl_chunk;
QString rdxl_contents;
double normalize_level; double normalize_level;
bool av10_chunk; bool av10_chunk;

View File

@ -99,10 +99,22 @@ void Xport::Export()
XmlExit("No such cart",404); XmlExit("No such cart",404);
} }
//
// Audio Settings
//
RDSettings *settings=new RDSettings();
settings->setFormat((RDSettings::Format)format);
settings->setChannels(channels);
settings->setSampleRate(sample_rate);
settings->setBitRate(bit_rate);
settings->setQuality(quality);
settings->setNormalizationLevel(normalization_level);
// //
// Generate Metadata // Generate Metadata
// //
RDWaveData *wavedata=NULL; RDWaveData *wavedata=NULL;
QString rdxl;
float speed_ratio=1.0; float speed_ratio=1.0;
if(enable_metadata!=0) { if(enable_metadata!=0) {
wavedata=new RDWaveData(); wavedata=new RDWaveData();
@ -115,6 +127,7 @@ void Xport::Export()
if(cart->enforceLength()) { if(cart->enforceLength()) {
speed_ratio=(float)cut->length()/(float)cart->forcedLength(); speed_ratio=(float)cut->length()/(float)cart->forcedLength();
} }
rdxl=cart->xml(true,settings,cutnum);
delete cut; delete cut;
delete cart; delete cart;
} }
@ -127,18 +140,12 @@ void Xport::Export()
uint8_t data[2048]; uint8_t data[2048];
QString tmpdir=RDTempDir(); QString tmpdir=RDTempDir();
QString tmpfile=tmpdir+"/exported_audio"; QString tmpfile=tmpdir+"/exported_audio";
RDSettings *settings=new RDSettings();
settings->setFormat((RDSettings::Format)format);
settings->setChannels(channels);
settings->setSampleRate(sample_rate);
settings->setBitRate(bit_rate);
settings->setQuality(quality);
settings->setNormalizationLevel(normalization_level);
RDAudioConvert *conv=new RDAudioConvert(xport_config->stationName()); RDAudioConvert *conv=new RDAudioConvert(xport_config->stationName());
conv->setSourceFile(RDCut::pathName(cartnum,cutnum)); conv->setSourceFile(RDCut::pathName(cartnum,cutnum));
conv->setDestinationFile(tmpfile); conv->setDestinationFile(tmpfile);
conv->setDestinationSettings(settings); conv->setDestinationSettings(settings);
conv->setDestinationWaveData(wavedata); conv->setDestinationWaveData(wavedata);
conv->setDestinationRdxl(rdxl);
conv->setRange(start_point,end_point); conv->setRange(start_point,end_point);
conv->setSpeedRatio(speed_ratio); conv->setSpeedRatio(speed_ratio);
switch(conv_err=conv->convert()) { switch(conv_err=conv->convert()) {