mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-11-29 16:50:13 +01:00
2021-09-30 Fred Gleason <fredg@paravelsystems.com>
* Overhauled the code for reading MPEG frame headers in 'RDWaveFile'. * Fixed a bug in the rdxport 'Import' service that could result in incorrect end marker placement when processing variable bit rate (VBR) MPEG files. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
@@ -22470,3 +22470,8 @@
|
||||
'/usr/bin/python' to '/usr/bin/python3'.
|
||||
* Added 'qt5-qtbase-devel' and 'qt5-linguist' build dependencies
|
||||
to 'rivendell.spec.in'.
|
||||
2021-09-30 Fred Gleason <fredg@paravelsystems.com>
|
||||
* Overhauled the code for reading MPEG frame headers in 'RDWaveFile'.
|
||||
* Fixed a bug in the rdxport 'Import' service that could result in
|
||||
incorrect end marker placement when processing variable bit rate
|
||||
(VBR) MPEG files.
|
||||
|
||||
@@ -83,8 +83,6 @@ RDWaveFile::RDWaveFile(QString file_name)
|
||||
head_mode_ext=0;
|
||||
head_emphasis=1;
|
||||
head_flags=0;
|
||||
pts=0;
|
||||
mpeg_id=RDWaveFile::NonMpeg;
|
||||
mpeg_frame_size=0;
|
||||
id3v1_tag=false;
|
||||
id3v2_tag[0]=false;
|
||||
@@ -262,9 +260,6 @@ bool RDWaveFile::openWave(RDWaveData *data)
|
||||
}
|
||||
data_length=wave_file.size()-data_start;
|
||||
sample_length=1152*(data_length/mpeg_frame_size);
|
||||
ext_time_length=(unsigned)(1000.0*(double)sample_length/
|
||||
(double)samples_per_sec);
|
||||
time_length=ext_time_length/1000;
|
||||
lseek(wave_file.handle(),data_start,SEEK_SET);
|
||||
format_chunk=true;
|
||||
}
|
||||
@@ -321,9 +316,6 @@ bool RDWaveFile::openWave(RDWaveData *data)
|
||||
}
|
||||
data_start=id3v2_offset[0];
|
||||
sample_length=1152*(data_length/mpeg_frame_size);
|
||||
ext_time_length=
|
||||
(unsigned)(1000.0*(double)sample_length/(double)samples_per_sec);
|
||||
time_length=ext_time_length/1000;
|
||||
data_chunk=true;
|
||||
lseek(wave_file.handle(),data_start,SEEK_SET);
|
||||
format_chunk=true;
|
||||
@@ -807,8 +799,6 @@ void RDWaveFile::closeWave(int samples)
|
||||
head_mode_ext=0;
|
||||
head_emphasis=1;
|
||||
head_flags=0;
|
||||
pts=0;
|
||||
mpeg_id=RDWaveFile::NonMpeg;
|
||||
mpeg_frame_size=0;
|
||||
id3v1_tag=false;
|
||||
id3v2_tag[0]=false;
|
||||
@@ -1559,13 +1549,6 @@ unsigned short RDWaveFile::getHeadFlags() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned long RDWaveFile::getPTS() const
|
||||
{
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
bool RDWaveFile::getCartChunk() const
|
||||
{
|
||||
return cart_chunk;
|
||||
@@ -1762,14 +1745,6 @@ QString RDWaveFile::getCartTimerLabel(int index) const
|
||||
return QString("");
|
||||
}
|
||||
|
||||
/*
|
||||
void RDWaveFile::setCartTimerLabel(int index,QString label)
|
||||
{
|
||||
if(index<MAX_TIMERS) {
|
||||
cart_timer_label[index]=label;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned RDWaveFile::getCartTimerSample(int index) const
|
||||
{
|
||||
@@ -1779,14 +1754,6 @@ unsigned RDWaveFile::getCartTimerSample(int index) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void RDWaveFile::setCartTimerSample(int index,unsigned sample)
|
||||
{
|
||||
if(index<MAX_TIMERS) {
|
||||
cart_timer_sample[index]=sample;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
QString RDWaveFile::getCartURL() const
|
||||
{
|
||||
@@ -2222,11 +2189,6 @@ QString RDWaveFile::formatText(RDWaveFile::Format fmt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum Format {Pcm8=0,Pcm16=1,Float32=2,MpegL1=3,MpegL2=4,MpegL3=5,
|
||||
DolbyAc2=6,DolbyAc3=7,Vorbis=8,Pcm24=9};
|
||||
enum Type {Unknown=0,Wave=1,Mpeg=2,Ogg=3,Atx=4,Tmc=5,Flac=6,Ambos=7,
|
||||
Aiff=8,M4A=9};
|
||||
|
||||
|
||||
QString RDWaveFile::typeText(RDWaveFile::Type type)
|
||||
{
|
||||
@@ -2666,8 +2628,6 @@ bool RDWaveFile::GetFmt(int fd)
|
||||
head_mode_ext=fmt_chunk_data[26]+256*fmt_chunk_data[27];
|
||||
head_emphasis=fmt_chunk_data[28]+256*fmt_chunk_data[29];
|
||||
head_flags=fmt_chunk_data[30]+256*fmt_chunk_data[31];
|
||||
pts=fmt_chunk_data[32]+256*fmt_chunk_data[33]+65536*
|
||||
fmt_chunk_data[34]+16777216*fmt_chunk_data[35];
|
||||
}
|
||||
|
||||
if(format_tag==WAVE_FORMAT_MPEGLAYER3) {
|
||||
@@ -3671,6 +3631,262 @@ void RDWaveFile::ReadId3Metadata()
|
||||
}
|
||||
|
||||
|
||||
bool RDWaveFile::GetMpegHeader(int fd,int offset)
|
||||
{
|
||||
//
|
||||
// See:
|
||||
//
|
||||
// http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
|
||||
// https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
|
||||
//
|
||||
// for helpful information regarding the arcana of interpreting MPEG
|
||||
// header data structures. Sometimes, fasting and prayer can help too!
|
||||
//
|
||||
|
||||
//
|
||||
// Bitrate table
|
||||
//
|
||||
// __bitrates[VERSION_INDEX][LAYER_INDEX][BITRATE_INDEX]
|
||||
//
|
||||
// N.B. Bitrate values in this table are in thousands of bits per second.
|
||||
// Certain other data structures in this class require bits per second!
|
||||
//
|
||||
static int __bitrates[4][4][16]={
|
||||
{ // *** MPEG 2.5 ***
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Reserved Layer
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1}, // Layer III
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1}, // Layer II
|
||||
{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,-1} // Layer I
|
||||
},
|
||||
|
||||
{ // *** Invalid MPEG Version ***
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Reserved Layer
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Layer III
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Layer II
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} // Layer I
|
||||
},
|
||||
|
||||
{ // *** MPEG 2 ***
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Reserved Layer
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1}, // Layer III
|
||||
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1}, // Layer II
|
||||
{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,-1} // Layer I
|
||||
},
|
||||
|
||||
{ // *** MPEG 1 ***
|
||||
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // Reserved Layer
|
||||
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1}, // Layer III
|
||||
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,-1},// Layer II
|
||||
{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,-1} // Layer I
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Sample Rate Table
|
||||
//
|
||||
// __samplerates[VERSION_INDEX][SAMPRATE_INDEX]
|
||||
static int __samplerates[4][4]={
|
||||
{11025,12000,8000,-1}, // *** MPEG 2.5 ***
|
||||
{-1,-1,-1,-1}, // *** Invalid MPEG Version ***
|
||||
{22050,24000,16000,-1}, // *** MPEG 2 ***
|
||||
{44100,48000,32000,-1} // *** MPEG 1 ***
|
||||
};
|
||||
|
||||
//
|
||||
// Channels table
|
||||
//
|
||||
// __channels[MODE_INDEX]
|
||||
static int __channels[4]={2,2,2,1};
|
||||
|
||||
//
|
||||
// Head Mode Table
|
||||
//
|
||||
// __head_modes[MODE_INDEX];
|
||||
static int __head_modes[4]={ACM_MPEG_STEREO,ACM_MPEG_JOINTSTEREO,
|
||||
ACM_MPEG_DUALCHANNEL,ACM_MPEG_SINGLECHANNEL};
|
||||
|
||||
//
|
||||
// Layer Numbers Table
|
||||
//
|
||||
// __layer_numbers[LAYER_INDEX]
|
||||
static int __layer_numbers[4]={0,3,2,1};
|
||||
|
||||
//
|
||||
// Samples per MPEG Frame Table
|
||||
//
|
||||
// __samples_per_frames[VERSION_INDEX][LAYER_INDEX]
|
||||
static int __samples_per_frame[4][4]={
|
||||
{0,576,1152,384}, // *** MPEG 2.5 ***
|
||||
{0,0,0,384}, // *** Invalid MPEG Version ***
|
||||
{0,576,1152,384}, // *** MPEG 2 ***
|
||||
{0,1152,1152,384} // *** MPEG 1 ***
|
||||
};
|
||||
|
||||
//
|
||||
// Side Data Offset Table (Layer III only)
|
||||
//
|
||||
// __side_data_offset[VERSION_INDEX][MODE]
|
||||
static int __side_data_offset[4][4]={
|
||||
{17,17,17,9}, // *** MPEG 2.5 ***
|
||||
{0,0,0,0}, // *** Invalid MPEG Version ***
|
||||
{17,17,17,9}, // *** MPEG 2 ***
|
||||
{32,32,32,17} // *** MPEG 1 ***
|
||||
};
|
||||
|
||||
char header[4];
|
||||
char *frame=NULL;
|
||||
ssize_t n;
|
||||
// off_t frame_start;
|
||||
int version_index;
|
||||
int layer_index;
|
||||
int bitrate_index;
|
||||
int samprate_index;
|
||||
int padding=0;
|
||||
int mode_index;
|
||||
int frame_size;
|
||||
int total_frame_quan=-1;
|
||||
|
||||
lseek(fd,offset,SEEK_SET);
|
||||
if((n=read(fd,header,4))!=4) {
|
||||
return false;
|
||||
}
|
||||
// frame_start=lseek(fd,0,SEEK_CUR)-4;
|
||||
|
||||
//
|
||||
// Sync bits
|
||||
//
|
||||
if(((0xFF&header[0])!=0xFF)||((0xE0&header[1])!=0xE0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// MPEG Audio Version ID
|
||||
//
|
||||
version_index=(0x18&header[1])>>3;
|
||||
if(version_index==0x01) { // Illegal Version ID
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Layer
|
||||
//
|
||||
layer_index=(0x06&header[1])>>1;
|
||||
if(layer_index==0x00) { // Illegal Layer
|
||||
return false;
|
||||
}
|
||||
head_layer=__layer_numbers[layer_index];
|
||||
|
||||
//
|
||||
// Bitrate
|
||||
//
|
||||
bitrate_index=(0xF0&header[2])>>4;
|
||||
if(__bitrates[version_index][layer_index][bitrate_index]<0) {
|
||||
return false;
|
||||
}
|
||||
head_bit_rate=1000*__bitrates[version_index][layer_index][bitrate_index];
|
||||
|
||||
//
|
||||
// Samplerate
|
||||
//
|
||||
samprate_index=(0x0C&header[2])>>2;
|
||||
if((__samplerates[version_index][samprate_index]<0)&&(bitrate_index!=0)) {
|
||||
return false;
|
||||
}
|
||||
samples_per_sec=__samplerates[version_index][samprate_index];
|
||||
|
||||
//
|
||||
// Padding bit
|
||||
//
|
||||
padding=(0x02&header[2])>>1;
|
||||
|
||||
//
|
||||
// Mode
|
||||
//
|
||||
mode_index=(0xC0&header[3])>>6;
|
||||
head_mode=__head_modes[mode_index];
|
||||
channels=__channels[mode_index];
|
||||
|
||||
//
|
||||
// Flags
|
||||
//
|
||||
head_flags=0;
|
||||
if((0x01&header[2])!=0) {
|
||||
head_flags|=ACM_MPEG_PRIVATEBIT;
|
||||
}
|
||||
if((header[3]&0x08)!=0) {
|
||||
head_flags|=ACM_MPEG_COPYRIGHT;
|
||||
}
|
||||
if((header[3]&0x04)!=0) {
|
||||
head_flags|=ACM_MPEG_ORIGINALHOME;
|
||||
}
|
||||
if(version_index==3) {
|
||||
head_flags|=ACM_MPEG_ID_MPEG1;
|
||||
}
|
||||
|
||||
//
|
||||
// Frame Size
|
||||
//
|
||||
if(layer_index==3) { // Layer I
|
||||
frame_size=(12000*__bitrates[version_index][layer_index][bitrate_index]/
|
||||
__samplerates[version_index][samprate_index]+padding)*4;
|
||||
}
|
||||
else { // Layers II and III
|
||||
frame_size=(144000*__bitrates[version_index][layer_index][bitrate_index]/
|
||||
__samplerates[version_index][samprate_index])+padding;
|
||||
}
|
||||
|
||||
//
|
||||
// Load the frame data
|
||||
//
|
||||
frame=new char[frame_size];
|
||||
if((n=read(fd,frame,frame_size-4))!=(frame_size-4)) {
|
||||
delete frame;
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Look for the Xing/Info tag (for VBR data)
|
||||
//
|
||||
if(((frame[__side_data_offset[version_index][mode_index]]=='X')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+1]=='i')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+2]=='n')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+3]=='g'))||
|
||||
((frame[__side_data_offset[version_index][mode_index]]=='I')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+1]=='n')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+2]=='f')&&
|
||||
(frame[__side_data_offset[version_index][mode_index]+3]=='o'))) {
|
||||
if((frame[__side_data_offset[version_index][mode_index]+7]&0x01)==0x01) {
|
||||
total_frame_quan=
|
||||
16777216*frame[__side_data_offset[version_index][mode_index]+8]+
|
||||
65536*frame[__side_data_offset[version_index][mode_index]+9]+
|
||||
256*frame[__side_data_offset[version_index][mode_index]+10]+
|
||||
frame[__side_data_offset[version_index][mode_index]+11];
|
||||
time_length=
|
||||
total_frame_quan*__samples_per_frame[version_index][layer_index]/
|
||||
__samplerates[version_index][samprate_index];
|
||||
ext_time_length=1000*total_frame_quan*
|
||||
__samples_per_frame[version_index][layer_index]/
|
||||
__samplerates[version_index][samprate_index];
|
||||
}
|
||||
}
|
||||
if(total_frame_quan<0) {
|
||||
//
|
||||
// No VBR tag, assume CBR
|
||||
//
|
||||
sample_length=1152.0*((double)data_length/(144.0*(double)head_bit_rate/
|
||||
(double)samples_per_sec));
|
||||
ext_time_length=1000.0*(double)sample_length/(double)samples_per_sec;
|
||||
time_length=ext_time_length/1000;
|
||||
}
|
||||
mpeg_frame_size=144*head_bit_rate/samples_per_sec;
|
||||
|
||||
delete frame;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool RDWaveFile::GetMpegHeader(int fd,int offset)
|
||||
{
|
||||
unsigned char buffer[4];
|
||||
@@ -4221,7 +4437,7 @@ bool RDWaveFile::GetMpegHeader(int fd,int offset)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int RDWaveFile::GetAtxOffset(int fd)
|
||||
{
|
||||
|
||||
791
lib/rdwavefile.h
791
lib/rdwavefile.h
@@ -1,6 +1,6 @@
|
||||
// rdwavefile.h
|
||||
//
|
||||
// A class for handling Microsoft WAV files.
|
||||
// A class for handling audio files.
|
||||
//
|
||||
// (C) Copyright 2002-2021 Fred Gleason <fredg@paravelsystems.com>
|
||||
//
|
||||
@@ -22,14 +22,16 @@
|
||||
#ifndef RDWAVEFILE_H
|
||||
#define RDWAVEFILE_H
|
||||
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <qobject.h>
|
||||
#include <qstring.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qfile.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#ifdef HAVE_VORBIS
|
||||
#include <vorbis/vorbisfile.h>
|
||||
@@ -37,10 +39,9 @@
|
||||
#endif // HAVE_VORBIS
|
||||
|
||||
#include <rdmp4.h>
|
||||
|
||||
#include <rdwavedata.h>
|
||||
#include <rdringbuffer.h>
|
||||
#include <rdsettings.h>
|
||||
#include <rdwavedata.h>
|
||||
|
||||
//
|
||||
// Number of timers allowed in the CartChunk structure.
|
||||
@@ -93,18 +94,6 @@
|
||||
#define DEFAULT_LEVL_POINTS 1
|
||||
#define DEFAULT_LEVL_BLOCK_SIZE 1152
|
||||
|
||||
|
||||
/**
|
||||
* @short A class for handling Microsoft WAV files.
|
||||
* @author Fred Gleason <fredg@wava.com>
|
||||
*
|
||||
* RDWaveFile provides an abstraction of a Microsoft RIFF-based WAV file.
|
||||
* In addition to 'FMT' and 'DATA' chunks, chunk types of particular
|
||||
* interest to broadcast applications are supported, including those
|
||||
* specified by the Broadcast Wave File specification (EBU Tech Document
|
||||
* 3285, with suppliments) and the CartChunk specification (currently
|
||||
* proposed to become AES standard AES-46).
|
||||
**/
|
||||
class RDWaveFile
|
||||
{
|
||||
public:
|
||||
@@ -112,912 +101,152 @@ class RDWaveFile
|
||||
DolbyAc2=6,DolbyAc3=7,Vorbis=8,Pcm24=9};
|
||||
enum Type {Unknown=0,Wave=1,Mpeg=2,Ogg=3,Atx=4,Tmc=5,Flac=6,Ambos=7,
|
||||
Aiff=8,M4A=9};
|
||||
enum MpegID {NonMpeg=0,Mpeg1=1,Mpeg2=2};
|
||||
|
||||
/**
|
||||
* Create an RDWaveFile object.
|
||||
* @param file_name The name of the WAV file to load into the object.
|
||||
**/
|
||||
RDWaveFile(QString file_name="");
|
||||
|
||||
/**
|
||||
* Destroy an RDWaveFile object.
|
||||
**/
|
||||
~RDWaveFile();
|
||||
|
||||
/**
|
||||
* Get the file type.
|
||||
**/
|
||||
RDWaveFile::Type type() const;
|
||||
|
||||
/**
|
||||
* Assign a WAV file name.
|
||||
* @param file_name The WAV filename to assign.
|
||||
**/
|
||||
void nameWave(QString file_name);
|
||||
|
||||
/**
|
||||
* Open the WAV file for recording. If the file already exists, it's
|
||||
* prior contents will be overwritten. If not, a new file will be
|
||||
* created.
|
||||
*
|
||||
* It is important that all desired meta-data chunks be enabled (using
|
||||
* the set<name>Chunk() family of methods) before invoking createWav().
|
||||
* Once the WAV file is created, new meta-data chunks cannot be added or
|
||||
* removed, although the contents of existing ones can be updated.
|
||||
* At a minimum, the 'FMT' chunk will need to have it's parameters
|
||||
* (sample rate, channels, etc) defined, or this method will return an
|
||||
* error.
|
||||
*
|
||||
* Returns true if WAV file was created successfully, otherwise false.
|
||||
**/
|
||||
bool createWave(RDWaveData *data=NULL,unsigned ptr_offset=0);
|
||||
|
||||
/**
|
||||
* Open the WAV file for playback. A WAV file name must first have
|
||||
* been assigned, either in the constructor or by means of nameWav().
|
||||
*
|
||||
* Setting 'allow_broken=true' will permit even patently-broken files
|
||||
* (like the raw files from an AMR-100 receiver, that have no FMT chunk)
|
||||
* to be opened to allow the metadata to be read.
|
||||
**/
|
||||
bool openWave(RDWaveData *data=NULL);
|
||||
|
||||
/**
|
||||
* Close the WAV file. Any pending DATA chunk or meta-data writes
|
||||
* will be applied, and DATA and FACT chunk size structures updated
|
||||
* accordingly.
|
||||
**/
|
||||
void closeWave(int samples=-1);
|
||||
|
||||
/**
|
||||
* Reset the record pointer on the WAV file to zero. Erases any audio
|
||||
* data previously recorded, but otherwise leaves things (format settings,
|
||||
* meta-data) as they were.
|
||||
**/
|
||||
void resetWave();
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a FMT chunk, otherwise false.
|
||||
**/
|
||||
bool getFormatChunk() const;
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a FACT chunk, otherwise false.
|
||||
**/
|
||||
bool getFactChunk() const;
|
||||
|
||||
/**
|
||||
* Returns the length of the audio in samples.
|
||||
**/
|
||||
unsigned getSampleLength() const;
|
||||
|
||||
/**
|
||||
* Returns the length of the audio in seconds.
|
||||
**/
|
||||
unsigned getTimeLength() const;
|
||||
|
||||
/**
|
||||
* Returns the length of the audio in milliseconds.
|
||||
**/
|
||||
unsigned getExtTimeLength() const;
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a DATA chunk, otherwise false.
|
||||
**/
|
||||
bool getDataChunk() const;
|
||||
|
||||
/**
|
||||
* Returns the length of the contents of the DATA chunk, in bytes.
|
||||
**/
|
||||
unsigned getDataLength() const;
|
||||
|
||||
/**
|
||||
* Read a block of data from the DATA chunk, using the current
|
||||
* encoding type.
|
||||
* @param buf The buffer in which to place the data.
|
||||
* @param count The maximum number of bytes to transfer.
|
||||
* Returns the number of bytes read.
|
||||
**/
|
||||
int readWave(void *buf,int count);
|
||||
|
||||
/**
|
||||
* Write a block of data to the DATA chunk.
|
||||
* @param buf The buffer from which to take the data.
|
||||
* @param count The number of bytes to transfer.
|
||||
* Returns the number of bytes written.
|
||||
**/
|
||||
int writeWave(void *buf,int count);
|
||||
|
||||
/**
|
||||
* Set the DATA chunk file pointer.
|
||||
* @param offset The value to which to set the pointer. The exact meaning
|
||||
* depends upon the value of the 'whence' parameters, below:
|
||||
* @param whence If SEEK_SET, set the file pointer to the value given
|
||||
* in 'offset. If SEEK_CUR, set the pointer to the value given in 'offset',
|
||||
* plus the current value.
|
||||
* Returns If successful, return the current pointer position, relative to
|
||||
* the start of the DATA chunk, otherwise -1.
|
||||
**/
|
||||
int seekWave(int offset,int whence);
|
||||
|
||||
void getSettings(RDSettings *settings);
|
||||
void setSettings(const RDSettings *settings);
|
||||
|
||||
/**
|
||||
* Returns true if energy data is available.
|
||||
**/
|
||||
bool hasEnergy();
|
||||
|
||||
/**
|
||||
* Returns the size of the energy data, or zero if none available.
|
||||
**/
|
||||
unsigned energySize();
|
||||
|
||||
/**
|
||||
* Returns energy data. For stereo files, this will be
|
||||
* interleaved LEFT>>RIGHT>>LEFT>>... .
|
||||
* @param frame The frame to reference.
|
||||
**/
|
||||
unsigned short energy(unsigned frame);
|
||||
|
||||
/**
|
||||
* Read a block of energy data.
|
||||
* @param buf The buffer in which to place the data.
|
||||
* @param count The maximum number of bytes to transfer.
|
||||
* Returns the number of bytes read.
|
||||
**/
|
||||
int readEnergy(unsigned short buf[],int count);
|
||||
|
||||
/**
|
||||
* Find the first instance of energy at or above the specified level.
|
||||
* @param level The level, in dbFS * 100.
|
||||
* Returns: The location in samples from file start, or -1 to indicate
|
||||
* failure.
|
||||
**/
|
||||
int startTrim(int level);
|
||||
|
||||
/**
|
||||
* Find the last instance of energy at or above the specified level.
|
||||
* @param level The level, in dbFS * 100.
|
||||
* Returns: The location in samples from file start, or -1 to indicate
|
||||
* failure.
|
||||
**/
|
||||
int endTrim(int level);
|
||||
|
||||
/**
|
||||
* Returns the filename of the WAV file.
|
||||
**/
|
||||
QString getName() const;
|
||||
|
||||
/**
|
||||
* Returns the FormatTag of the WAV file, as defined in the 'FMT' chunk.
|
||||
* Values currently understood by RDWaveFile are:
|
||||
* WAVE_FORMAT_PCM Linear PCM Data
|
||||
* WAVE_FORMAT_IEEE_FLOAT IEEE Floating Point Data
|
||||
* WAVE_FORMAT_MPEG MPEG-1 Encoded Data
|
||||
**/
|
||||
unsigned short getFormatTag() const;
|
||||
|
||||
/**
|
||||
* Set the format tag in the FMT chunk for a WAV file to be recorded.
|
||||
* Values currently understood by RDWaveFile are:
|
||||
* WAVE_FORMAT_PCM Linear PCM Data
|
||||
* WAVE_FORMAT_MPEG MPEG-1 Encoded Data
|
||||
* @param format The encoding format.
|
||||
**/
|
||||
void setFormatTag(unsigned short format);
|
||||
|
||||
/**
|
||||
* Returns the number of audio channels recorded in the WAV file, as
|
||||
* represented by the 'FMT chunk.
|
||||
**/
|
||||
unsigned short getChannels() const;
|
||||
|
||||
/**
|
||||
* Sets the number of channels in the FMT chunk for a WAV file to be
|
||||
* recorded. Currently supported values are '1' or '2'.
|
||||
* @param chan Number of channels.
|
||||
**/
|
||||
void setChannels(unsigned short chan);
|
||||
|
||||
/**
|
||||
* Returns the sampling rate of the audio recorded in the WAV file, as
|
||||
* represented by the 'FMT chunk, in samples per second.
|
||||
**/
|
||||
unsigned getSamplesPerSec() const;
|
||||
|
||||
/**
|
||||
* Sets the sampling rate in the FMT chunk for a WAV file to be recorded.
|
||||
* @param rate The sampling rate in samples per second.
|
||||
**/
|
||||
void setSamplesPerSec(unsigned rate);
|
||||
|
||||
/**
|
||||
* Returns the average data rate of the audio recorded in the WAV file, as
|
||||
* represented by the 'FMT chunk, in bytes per second.
|
||||
**/
|
||||
unsigned getAvgBytesPerSec() const;
|
||||
|
||||
/**
|
||||
* Returns the 'atomic' sample size of the audio recorded in the WAV file,
|
||||
* as represented by the 'FMT' chunk. In the case of a non-homogenous or
|
||||
* bit-padded MPEG file, this will be set to '1'.
|
||||
**/
|
||||
unsigned short getBlockAlign() const;
|
||||
|
||||
/**
|
||||
* Returns the bits per audio sample for PCM files, otherwise a '0'.
|
||||
**/
|
||||
unsigned short getBitsPerSample() const;
|
||||
|
||||
/**
|
||||
* Set the number of bits per sample for PCM files in the FMT chunk
|
||||
* for a WAV file to be recorded. For MPEG files, this should be set
|
||||
* to '0'.
|
||||
* @param bits Number of bits per audio sample, or '0' for an MPEG file.
|
||||
**/
|
||||
void setBitsPerSample(unsigned short bits);
|
||||
|
||||
/**
|
||||
* Returns the MPEG-1 Layer (1, 2 or 3) for an MPEG-1 file, otherwise a '0'.
|
||||
**/
|
||||
unsigned short getHeadLayer() const;
|
||||
|
||||
/**
|
||||
* Set the MPEG-1 Layer for MPEG files in the FMT chunk for a WAV file
|
||||
* to be recorded. Layers 1, 2 and 3 are supported. For PCM files,
|
||||
* this should be set to '0'.
|
||||
* @param layer MPEG-1 encoding layer, or '0' for a PCM file.
|
||||
**/
|
||||
void setHeadLayer(unsigned short layer);
|
||||
|
||||
/**
|
||||
* Returns the bit rate for an MPEG-1 file in bits per second, otherwise
|
||||
* a '0'.
|
||||
**/
|
||||
unsigned getHeadBitRate() const;
|
||||
|
||||
/**
|
||||
* Set the bit rate for an MPEG-1 file in the FMT chunk for a WAV file
|
||||
* to be recorded. This needs to be one of the "official" rates as
|
||||
* defined in the MPEG-1 standard. Valid rates are:
|
||||
* LAYER 1: 32000, 64000, 96000,128000,160000,192000,224000,
|
||||
* 256000,288000,320000,352000,384000,416000,448000
|
||||
*
|
||||
* LAYER 2: 32000, 48000, 56000, 64000, 80000, 96000,112000,
|
||||
* 128000,160000,192000,224000,256000,320000,384000
|
||||
*
|
||||
* LAYER 3: 32000, 40000, 48000, 56000, 64000, 80000, 96000,
|
||||
* 112000,128000,160000,192000,224000,256000,320000
|
||||
*
|
||||
* @param rate MPEG bitrate, in bits per second, or '0' for a PCM file.
|
||||
**/
|
||||
void setHeadBitRate(unsigned rate);
|
||||
|
||||
/**
|
||||
* Returns the MPEG-1 Mode for an MPEG-1 file, otherwise a '0'. Possible
|
||||
* modes are:
|
||||
* ACM_MPEG_STEREO Stereo
|
||||
* ACM_MPEG_JOINTSTEREO Joint Stereo
|
||||
* ACM_MPEG_DUALCHANNEL Dual Channel
|
||||
* ACM_MPEG_SINGLECHANNEL Mono
|
||||
**/
|
||||
unsigned short getHeadMode() const;
|
||||
|
||||
/**
|
||||
* Set the MPEG-1 mode for an MPEG file in the FMT chunk for a WAV
|
||||
* file to be recorded. This value is a series of flags bitwise-OR'd
|
||||
* together. The corresponding flag should be set if one or more
|
||||
* MPEG-1 frames in that mode are present in the audio data.
|
||||
*
|
||||
* Valid mode flags are:
|
||||
* ACM_MPEG_STEREO Stereo
|
||||
* ACM_MPEG_JOINTSTEREO Joint Stereo
|
||||
* ACM_MPEG_DUALCHANNEL Dual Channel
|
||||
* ACM_MPEG_SINGLECHANNEL Mono
|
||||
*
|
||||
* @param mode The bitwise-OR'd mode flags for MPEG files, or a '0' for PCM
|
||||
* files.
|
||||
**/
|
||||
void setHeadMode(unsigned short mode);
|
||||
|
||||
/**
|
||||
* Returns the extended mode flags for an MPEG-1 file, otherwise a '0'.
|
||||
**/
|
||||
unsigned getHeadModeExt() const;
|
||||
|
||||
/**
|
||||
* Returns the request preemphasis for an MPEG-1 file, otherwise a '0'.
|
||||
**/
|
||||
unsigned getHeadEmphasis() const;
|
||||
|
||||
/**
|
||||
* Returns the MPEG-1 flags for an MPEG-1 file, otherwise a '0'.
|
||||
**/
|
||||
unsigned short getHeadFlags() const;
|
||||
|
||||
/**
|
||||
* Set the MPEG-1 flags for an MPEG file. All appropriate flags should
|
||||
* be bitwise-OR'd together. Valid flags include:
|
||||
* ACM_MPEG_PRIVATEBIT Private Bit
|
||||
* ACM_MPEG_COPYRIGHT Copyright Bit
|
||||
* ACM_MPEG_ORIGINALHOME Original Home Bit
|
||||
* ACM_MPEG_PROTECTIONBIT Protection Bit
|
||||
* ACM_MPEG_ID_MPEG1 MPEG-1 ID Bit
|
||||
*
|
||||
* @param flags The MPEG-1 flags to set.
|
||||
**/
|
||||
void setHeadFlags(unsigned short flags);
|
||||
|
||||
/**
|
||||
* Not currently implemented.
|
||||
**/
|
||||
unsigned long getPTS() const;
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a CART chunk, otherwise false.
|
||||
**/
|
||||
bool getCartChunk() const;
|
||||
|
||||
/**
|
||||
* Enable a CartChunk structure. The default is to not create a
|
||||
* CartChunk structure in the WAV file to be recorded. For more
|
||||
* information on CartChunk and it's capabilities, see
|
||||
* http://www.cartchunk.org/.
|
||||
* @param state true = Enable cart chunk structure, false = disable
|
||||
**/
|
||||
void setCartChunk(bool state);
|
||||
|
||||
/**
|
||||
* Returns the version of the CartChunk standard used in the WAV file.
|
||||
**/
|
||||
unsigned getCartVersion() const;
|
||||
|
||||
/**
|
||||
* Returns the contents of the TITLE field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartTitle() const;
|
||||
|
||||
/**
|
||||
* Set the TITLE field on the WAV file's CartChunk.
|
||||
* @param string The value for the TITLE field.
|
||||
**/
|
||||
void setCartTitle(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ARTIST field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartArtist() const;
|
||||
|
||||
/**
|
||||
* Set the ARTIST field on the WAV file's CartChunk.
|
||||
* @param string The value for the ARTIST field.
|
||||
**/
|
||||
void setCartArtist(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the CutID field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartCutID() const;
|
||||
|
||||
/**
|
||||
* Set the CutID field on the WAV file's CartChunk.
|
||||
* @param string The value for the CutID field.
|
||||
**/
|
||||
void setCartCutID(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ClientID field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartClientID() const;
|
||||
|
||||
/**
|
||||
* Set the ClientID field on the WAV file's CartChunk.
|
||||
* @param string The value for the ClientID field.
|
||||
**/
|
||||
void setCartClientID(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the CATEGORY field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartCategory() const;
|
||||
|
||||
/**
|
||||
* Set the Category field on the WAV file's CartChunk.
|
||||
* @param string The value for the Category field.
|
||||
**/
|
||||
void setCartCategory(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the CLASSIFICATION field in the WAV file's
|
||||
* CART chunk.
|
||||
**/
|
||||
QString getCartClassification() const;
|
||||
|
||||
/**
|
||||
* Set the Classification field on the WAV file's CartChunk.
|
||||
* @param string The value for the Cclassification field.
|
||||
**/
|
||||
void setCartClassification(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the OUTCUE field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartOutCue() const;
|
||||
|
||||
/**
|
||||
* Set the OutCue field on the WAV file's CartChunk.
|
||||
* @param string The value for the OutCue field.
|
||||
**/
|
||||
void setCartOutCue(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the STARTDATE field in the WAV file's CART chunk.
|
||||
**/
|
||||
QDate getCartStartDate() const;
|
||||
|
||||
/**
|
||||
* Set the StartDate field on the WAV file's CartChunk.
|
||||
* @param date The value for the StartDate field.
|
||||
**/
|
||||
void setCartStartDate(QDate date);
|
||||
|
||||
/**
|
||||
* Returns the contents of the STARTTIME field in the WAV file's CART chunk.
|
||||
**/
|
||||
QTime getCartStartTime() const;
|
||||
|
||||
/**
|
||||
* Set the StartTime field on the WAV file's CartChunk.
|
||||
* @param time The value for the StartTime field.
|
||||
**/
|
||||
void setCartStartTime(QTime time);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ENDDATE field in the WAV file's CART chunk.
|
||||
**/
|
||||
QDate getCartEndDate() const;
|
||||
|
||||
/**
|
||||
* Set the EndDate field on the WAV file's CartChunk.
|
||||
* @param date The value for the EndDate field.
|
||||
**/
|
||||
void setCartEndDate(QDate date);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ENDTIME field in the WAV file's CART chunk.
|
||||
**/
|
||||
QTime getCartEndTime() const;
|
||||
|
||||
/**
|
||||
* Set the EndTime field on the WAV file's CartChunk.
|
||||
* @param time The value for the EndTime field.
|
||||
**/
|
||||
void setCartEndTime(QTime time);
|
||||
|
||||
/**
|
||||
* Returns the contents of the PRODUCER APPLICATION ID field in the WAV
|
||||
* file's CART chunk.
|
||||
**/
|
||||
QString getCartProducerAppID() const;
|
||||
|
||||
/**
|
||||
* Returns the contents of the PRODUCER APPLICATION VERSION field in the
|
||||
* WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartProducerAppVer() const;
|
||||
|
||||
/**
|
||||
* Returns the contents of the USERDEF field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartUserDef() const;
|
||||
|
||||
/**
|
||||
* Set the UserDef field on the WAV file's CartChunk.
|
||||
* @param string The value for the UserRef field.
|
||||
**/
|
||||
void setCartUserDef(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the LEVELREF field in the WAV file's CART chunk.
|
||||
**/
|
||||
unsigned getCartLevelRef() const;
|
||||
|
||||
/**
|
||||
* Set the LevelRef field on the WAV file's CartChunk.
|
||||
* @param level The value for the LevelRef field.
|
||||
**/
|
||||
void setCartLevelRef(unsigned level);
|
||||
|
||||
/**
|
||||
* Retrieve the label for one of the eight CartChunk timers.
|
||||
* @param index The index number of the timer to access (0 - 7).
|
||||
* Returns the label of the corresponding timer.
|
||||
**/
|
||||
QString getCartTimerLabel(int index) const;
|
||||
|
||||
/**
|
||||
* Retrieve the sample value for one of the eight CartChunk timers.
|
||||
* @param index The index number of the timer to access (0 - 7).
|
||||
* Returns the sample value of the corresponding timer.
|
||||
**/
|
||||
unsigned getCartTimerSample(int index) const;
|
||||
|
||||
/**
|
||||
* Returns the contents of the URL field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartURL() const;
|
||||
|
||||
/**
|
||||
* Set the URL field on the WAV file's CartChunk.
|
||||
* @param string The value for the URL field.
|
||||
**/
|
||||
void setCartURL(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the TAGTEXT field in the WAV file's CART chunk.
|
||||
**/
|
||||
QString getCartTagText() const;
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a BEXT chunk, otherwise false.
|
||||
**/
|
||||
bool getBextChunk() const;
|
||||
|
||||
/**
|
||||
* Enable a BWF Bext structure. The default is to not create a
|
||||
* Bext structure in the WAV file to be recorded. For more
|
||||
* information on the BWF format and it's capabilities, see
|
||||
* http://www.sr.se/utveckling/tu/bwf/.
|
||||
* @param state true = Enable Bext structure, false = disable
|
||||
**/
|
||||
void setBextChunk(bool state);
|
||||
|
||||
/**
|
||||
* Returns the contents of the DESCRIPTION field in the WAV file's BEXT
|
||||
* chunk.
|
||||
**/
|
||||
QString getBextDescription() const;
|
||||
|
||||
/**
|
||||
* Set the Description field on the WAV file's Bext structure.
|
||||
* @param string The value for the Description field.
|
||||
**/
|
||||
void setBextDescription(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ORIGINATOR field in the WAV file's BEXT
|
||||
* chunk.
|
||||
**/
|
||||
QString getBextOriginator() const;
|
||||
|
||||
/**
|
||||
* Set the Originator field on the WAV file's Bext structure.
|
||||
* @param string The value for the Originator field.
|
||||
**/
|
||||
void setBextOriginator(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ORIGINATOR REFERENCE field in the WAV
|
||||
* file's BEXT chunk.
|
||||
**/
|
||||
QString getBextOriginatorRef() const;
|
||||
|
||||
/**
|
||||
* Set the Originator Reference field on the WAV file's Bext structure.
|
||||
* @param string The value for the Originator Reference field.
|
||||
**/
|
||||
void setBextOriginatorRef(QString string);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ORIGINATION DATE field in the WAV file's BEXT
|
||||
* chunk.
|
||||
**/
|
||||
QDate getBextOriginationDate() const;
|
||||
|
||||
/**
|
||||
* Set the Origination Date field on the WAV file's Bext structure.
|
||||
* @param date The value for the Origination Date field.
|
||||
**/
|
||||
void setBextOriginationDate(QDate date);
|
||||
|
||||
/**
|
||||
* Returns the contents of the ORIGINATION TIME field in the WAV file's BEXT
|
||||
* chunk.
|
||||
**/
|
||||
QTime getBextOriginationTime() const;
|
||||
|
||||
/**
|
||||
* Set the Origination Time field on the WAV file's Bext structure.
|
||||
* @param time The value for the Origination Time field.
|
||||
**/
|
||||
void setBextOriginationTime(QTime time);
|
||||
|
||||
/**
|
||||
* Returns the lower 32 bits of the BWF Time Reference field.
|
||||
**/
|
||||
unsigned getBextTimeReferenceLow() const;
|
||||
|
||||
/**
|
||||
* Sets the lower 32 bits of the BWF Time Reference field.
|
||||
* @param sample The sample value for the lower 32 bits
|
||||
**/
|
||||
void setBextTimeReferenceLow(unsigned sample);
|
||||
|
||||
/**
|
||||
* Returns the upper 32 bits of the BWF Time Reference field.
|
||||
**/
|
||||
unsigned getBextTimeReferenceHigh() const;
|
||||
|
||||
/**
|
||||
* Sets the upper 32 bits of the BWF Time Reference field.
|
||||
* @param sample The sample value for the upper 32 bits
|
||||
**/
|
||||
void setBextTimeReferenceHigh(unsigned sample);
|
||||
|
||||
/**
|
||||
* Returns the version of the BWF standard used by the WAV file.
|
||||
**/
|
||||
unsigned short getBextVersion() const;
|
||||
|
||||
/**
|
||||
* Gets the SMPTE Unique Material Identifier (UMD) in the WAV file's
|
||||
* BEXT chunk. See SMPTE Standard 330M-2000 for more info.
|
||||
* @param buf A 64 byte long buffer in which to place the UMD
|
||||
**/
|
||||
void getBextUMD(unsigned char *buf) const;
|
||||
|
||||
/**
|
||||
* Sets the SMPTE Unique Material Identifier (UMD) in the WAV file's
|
||||
* BEXT chunk. See SMPTE Standard 330M-2000 for more info.
|
||||
* @param buf A 64 byte long buffer containing the UMD
|
||||
**/
|
||||
void setBextUMD(unsigned char *buf);
|
||||
|
||||
/**
|
||||
* Returns the contents of the CODING HISTORY field from the WAV files'
|
||||
* BEXT chunk.
|
||||
**/
|
||||
QString getBextCodingHistory() const;
|
||||
|
||||
/**
|
||||
* Set the Coding History field on the WAV file's Bext structure.
|
||||
* NOTE: This can only be set prior to calling createWave()! If
|
||||
* called after createWave(), it will be silently ignored.
|
||||
* @param string The value for the Coding History field.
|
||||
**/
|
||||
void setBextCodingHistory(QString string);
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a MEXT chunk, otherwise false.
|
||||
**/
|
||||
bool getMextChunk() const;
|
||||
|
||||
/**
|
||||
* Enable a BWF Mext structure. The default is to not create a
|
||||
* Mext structure in the WAV file to be recorded. For more
|
||||
* information on the BWF format and it's capabilities, see
|
||||
* http://www.sr.se/utveckling/tu/bwf/.
|
||||
* @param state true = Enable Mext structure, false = disable
|
||||
**/
|
||||
void setMextChunk(bool state);
|
||||
|
||||
/**
|
||||
* Returns true if file is tagged as containing homogenous data, otherwise
|
||||
* false.
|
||||
**/
|
||||
bool getMextHomogenous() const;
|
||||
|
||||
/**
|
||||
* Returns true if the padding bit is used (and hence the MPEG frame size
|
||||
* can vary between frames), otherwise false.
|
||||
**/
|
||||
bool getMextPaddingUsed() const;
|
||||
|
||||
/**
|
||||
* Returns true if the file contains frames with the padding bits all
|
||||
* set to '0' and a sample rate of 22.025 or 44.1 kHz. According to
|
||||
* MPEG-1, such files are deprecated (because the overall bit rate is
|
||||
* not one of the standard MPEG rates).
|
||||
**/
|
||||
bool getMextHackedBitRate() const;
|
||||
|
||||
/**
|
||||
* Returns true if the file contains free format frames, otherwise false.
|
||||
**/
|
||||
bool getMextFreeFormat() const;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes in a frame for homogenous data, otherwise
|
||||
* zero. If the padding bit is used, this will be the frame size for
|
||||
* frames with the padding bit set to '0'. For frames with the padding
|
||||
* bit set to '1', the frame size will be four bytes longer for Layer 1
|
||||
* and one byte longer for Layer 2 and Layer 3.
|
||||
**/
|
||||
int getMextFrameSize() const;
|
||||
|
||||
/**
|
||||
* Returns the minimal number of known bytes for ancillary data in the
|
||||
* full sound file. The value is relative from the end of the audio frame.
|
||||
**/
|
||||
int getMextAncillaryLength() const;
|
||||
|
||||
/**
|
||||
* Returns true if the ancillary data contains left or mono channel energy
|
||||
* information, otherise false.
|
||||
**/
|
||||
bool getMextLeftEnergyPresent() const;
|
||||
|
||||
/**
|
||||
* Returns true if the ancillary data contains right channel energy
|
||||
* information, otherwise false.
|
||||
**/
|
||||
bool getMextRightEnergyPresent() const;
|
||||
|
||||
/**
|
||||
* Returns true if the ancillary data contains private data, otherwise
|
||||
* false.
|
||||
**/
|
||||
bool getMextPrivateDataPresent() const;
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded as containing
|
||||
* homogenous or non-homogenous MPEG-1 data.
|
||||
* @param state True = Data is homogenous, false = data is non-homogenous
|
||||
**/
|
||||
void setMextHomogenous(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* the status of the MPEG-1 padding bit.
|
||||
* @param state True = padding bit is used, false = padding bit is ignored
|
||||
**/
|
||||
void setMextPaddingUsed(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to indicate frames with
|
||||
* padding bits all set to '0' and a sample rate of 22.025 or 44.1 kHz.
|
||||
* According to MPEG-1, such files are deprecated (because the overall
|
||||
* bit rate is not one of the standard MPEG rates).
|
||||
* @param state True = hacked bit rate used, false = proper bit rate used
|
||||
**/
|
||||
void setMextHackedBitRate(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* free format MPEG-1 frame.
|
||||
* @param state True = free format frames, false = constant bit rate frames
|
||||
**/
|
||||
void setMextFreeFormat(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* the number of bytes in a frame for homogenous data, otherwise
|
||||
* zero. If the padding bit is used, this will be the frame size for
|
||||
* frames with the padding bit set to '0'. For frames with the padding
|
||||
* bit set to '1', the frame size will be four bytes longer for Layer 1
|
||||
* and one byte longer for Layer 2 and Layer 3.
|
||||
**/
|
||||
void setMextFrameSize(int size);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* the minimal number of known bytes for ancillary data in the
|
||||
* full sound file. The value is relative from the end of the audio frame.
|
||||
**/
|
||||
void setMextAncillaryLength(int length);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* if the ancillary data contains left or mono channel energy
|
||||
* information.
|
||||
* @param state True = left energy data is present, false = is not present
|
||||
**/
|
||||
void setMextLeftEnergyPresent(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* if the ancillary data contains rightchannel energy
|
||||
* information.
|
||||
* @param state True = right energy data is present, false = is not present
|
||||
**/
|
||||
void setMextRightEnergyPresent(bool state);
|
||||
|
||||
/**
|
||||
* Set the BWF Mext structure in the WAV file to be recorded to indicate
|
||||
* if the ancillary data contains private data.
|
||||
* @param state True = private data present, false = no private data
|
||||
**/
|
||||
void setMextPrivateDataPresent(bool state);
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a LEVL chunk, otherwise false.
|
||||
**/
|
||||
bool getLevlChunk() const;
|
||||
|
||||
/**
|
||||
* Enable a BWF Levl structure. The default is to not create a
|
||||
* Levl structure in the WAV file to be recorded. For more
|
||||
* information on the BWF format and it's capabilities, see
|
||||
* http://www.sr.se/utveckling/tu/bwf/.
|
||||
* @param state true = Enable Levl structure, false = disable
|
||||
**/
|
||||
void setLevlChunk(bool state);
|
||||
|
||||
/**
|
||||
* Get the version of the LEVL chunk data.
|
||||
**/
|
||||
int getLevlVersion() const;
|
||||
|
||||
/**
|
||||
* Set the version of the LEVL chunk data.
|
||||
* @param ver The version number to set.
|
||||
**/
|
||||
void setLevlVersion(unsigned ver);
|
||||
|
||||
/**
|
||||
* Get the number of audio samples per peak value of the LEVL chunk.
|
||||
**/
|
||||
int getLevlBlockSize() const;
|
||||
|
||||
/**
|
||||
* Set the block size of the LEVL chunk data.
|
||||
* @param ver The block size to set.
|
||||
**/
|
||||
void setLevlBlockSize(unsigned size);
|
||||
|
||||
/**
|
||||
* Get the number of channels of peak values.
|
||||
**/
|
||||
int getLevlChannels() const;
|
||||
|
||||
/**
|
||||
* Get the 'peak-of-peaks' value.
|
||||
**/
|
||||
unsigned short getLevlPeak() const;
|
||||
|
||||
/**
|
||||
* Get the timestamp of the LEVL chunk.
|
||||
**/
|
||||
QDateTime getLevlTimestamp() const;
|
||||
|
||||
/**
|
||||
* Set the encoding quality (for OggVorbis only)
|
||||
**/
|
||||
void setEncodeQuality(float qual);
|
||||
|
||||
/**
|
||||
* Get serial number (for OggVorbis only)
|
||||
**/
|
||||
int getSerialNumber() const;
|
||||
|
||||
/**
|
||||
* Set serial number (for OggVorbis only)
|
||||
**/
|
||||
void setSerialNumber(int serial);
|
||||
|
||||
/**
|
||||
* Returns true if the WAV file contains a SCOT chunk, otherwise false.
|
||||
**/
|
||||
bool getScotChunk() 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;
|
||||
void setNormalizeLevel(double level);
|
||||
|
||||
static QString formatText(Format fmt);
|
||||
static QString typeText(Type type);
|
||||
|
||||
|
||||
private:
|
||||
RDWaveFile::Type GetType(int fd);
|
||||
bool IsWav(int fd);
|
||||
@@ -1099,9 +328,7 @@ class RDWaveFile
|
||||
unsigned head_mode_ext; // Extra mode parameters (for joint stereo)
|
||||
unsigned head_emphasis; // De-emphasis
|
||||
unsigned short head_flags; // MPEG header flags
|
||||
unsigned long pts; // The MPEG PTS
|
||||
unsigned ptr_offset_msecs;
|
||||
RDWaveFile::MpegID mpeg_id;
|
||||
int mpeg_frame_size;
|
||||
bool id3v1_tag;
|
||||
bool id3v2_tag[2];
|
||||
|
||||
Reference in New Issue
Block a user