// rdwavefile.h // // A class for handling audio files. // // (C) Copyright 2002-2021 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Library 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. // // #ifndef RDWAVEFILE_H #define RDWAVEFILE_H #include #include #include #include #include #include #include #include #ifdef HAVE_VORBIS #include #include #endif // HAVE_VORBIS #include #include #include #include // // Number of timers allowed in the CartChunk structure. // The official number is '8'. // #define MAX_TIMERS 8 // // Define this if we should guesstimate the overall sample count // of a MPEG file with a missing or zeroed 'fact' chunk. (Technically, // such a file is invalid, but there are lots of them floating // around out there nonetheless.) Otherwise, return '0' for the // sample count. // #define MPEG_FACT_FUDGE // // The default mode bits for new WAV files. // #define WAVE_MODE_BITS 0644 /* * Chunk Sizes */ #define FMT_CHUNK_SIZE 40 #define FACT_CHUNK_SIZE 4 #define CART_CHUNK_SIZE 2048 #define BEXT_CHUNK_SIZE 602 #define MEXT_CHUNK_SIZE 12 #define LEVL_CHUNK_SIZE 128 #define SCOT_CHUNK_SIZE 424 #define AV10_CHUNK_SIZE 512 #define AIR1_CHUNK_SIZE 2048 #define COMM_CHUNK_SIZE 18 #define RDXL_CHUNK_SIZE 4 // // Maximum Header Size for ATX Files #define MAX_ATX_HEADER_SIZE 512 // // The size of the MPEG Ring Buffer // #define MPEG_BUFFER_SIZE 32768 // // Default Values // #define DEFAULT_LEVL_FORMAT 2 #define DEFAULT_LEVL_POINTS 1 #define DEFAULT_LEVL_BLOCK_SIZE 1152 /** * @short A class for handling Microsoft WAV files. * @author Fred Gleason * * 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 AES standard AES-46 (aka CartChunk). **/ class RDWaveFile { public: 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}; /** * 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 setChunk() 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); bool IsMpeg(int fd); bool IsOgg(int fd); bool IsAtx(int fd); bool IsTmc(int fd); bool IsFlac(int fd); bool IsAiff(int fd); bool IsM4A(int fd); off_t FindChunk(int fd,const char *chunk_name,unsigned *chunk_size, bool big_end=false); bool GetChunk(int fd,const char *chunk_name,unsigned *chunk_size, unsigned char *chunk,size_t size,bool big_end=false); void WriteChunk(int fd,const char *cname,unsigned char *buf,unsigned size, bool big_end=false); void WriteChunk(int fd,const char *cname,const QString &contents); bool GetFmt(int fd); bool GetFact(int fd); bool GetCart(int fd); bool GetBext(int fd); bool GetMext(int fd); bool GetLevl(int fd); bool GetList(int fd); bool GetScot(int fd); bool GetAv10(int fd); bool GetAir1(int fd); bool GetRdxl(int fd); bool GetComm(int fd); bool ReadListElement(unsigned char *buffer,unsigned *offset,unsigned size); bool ReadTmcMetadata(int fd); void ReadTmcTag(const QString tag,const QString value); bool GetLine(int fd,char *buffer,int max_len); void ReadId3Metadata(); bool GetMpegHeader(int fd,int offset); int GetAtxOffset(int fd); bool GetFlacStreamInfo(); void ReadFlacMetadata(); bool MakeFmt(); bool MakeCart(unsigned ptr_offset); bool MakeBext(); bool MakeMext(); bool MakeLevl(); void WriteDword(unsigned char *,unsigned,unsigned); void WriteSword(unsigned char *,unsigned,unsigned short); unsigned ReadDword(unsigned char *,unsigned); unsigned short ReadSword(unsigned char *,unsigned); void GetEnergy(); unsigned LoadEnergy(); bool ReadNormalizeLevel(QString wave_file_name); bool ReadEnergyFile(QString wave_file_name); void GrowAlloc(size_t size); #ifdef HAVE_VORBIS int WriteOggPage(ogg_page *page); #endif // HAVE_VORBIS int WriteOggBuffer(char *buf,int size); unsigned FrameOffset(int msecs) const; QString wave_file_name; QFile wave_file; RDWaveData *wave_data; bool recordable; // Allow DATA chunk writes? unsigned time_length; // Audio length in secs unsigned ext_time_length; // Audio length in msec bool format_chunk; // Does 'fmt ' chunk exist? bool comm_chunk; // Does 'COMM' chunk exist? unsigned char comm_chunk_data[COMM_CHUNK_SIZE]; unsigned short format_tag; // Encoding Format unsigned short channels; // Number of channels unsigned samples_per_sec; // Samples/sec/channel unsigned avg_bytes_per_sec; // Average bytes/sec overall unsigned short block_align; // Data block size unsigned short bits_per_sample; // Bits per mono sample (PCM only) unsigned short cb_size; // Number of bytes of extended data unsigned short head_layer; // The MPEG audio layer unsigned head_bit_rate; // MPEG bit rate, in byte/sec unsigned short head_mode; // MPEG stream mode 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; int mpeg_frame_size; bool id3v1_tag; bool id3v2_tag[2]; unsigned id3v2_offset[2]; unsigned char fmt_chunk_data[FMT_CHUNK_SIZE]; int fmt_size; // Size of FMT chunk bool fact_chunk; // Does 'fact' chunk exist? unsigned sample_length; // Audio length in samples unsigned char fact_chunk_data[FACT_CHUNK_SIZE]; bool data_chunk; // Does 'data' chunk exist? int data_start; // Start position of WAV data unsigned data_length; // Length of raw audio data bool cart_chunk; // Does 'cart' chunk exist? unsigned cart_version; // CartChunk Version field QString cart_title; // CartChunk Title field QString cart_artist; // CartChunk Artist field QString cart_cut_id; // CartChunk CutID field QString cart_client_id; // CartChunk ClientID field QString cart_category; // CartChunk Category field QString cart_classification; // CartChunk Classification field QString cart_out_cue; // CartChunk OutCue Field QDate cart_start_date; // CartChunk StartDate field QTime cart_start_time; // CartChunk StartTime field QDate cart_end_date; // CartChunk EndDate field QTime cart_end_time; // CartChunk EndTime field QString cart_producer_app_id; // CartChunk ProducerAppID field QString cart_producer_app_ver; // CartChunk ProducerAppVersion field QString cart_user_def; // CartChunk UserDef field unsigned cart_level_ref; // CartChunk dwLevelReference field QString cart_timer_label[MAX_TIMERS]; // CartChunk CartTimer labels unsigned cart_timer_sample[MAX_TIMERS]; // CarChunk CartTimer samples QString cart_url; // CartChunk URL field QString cart_tag_text; // CartChunk TagText field unsigned char cart_chunk_data[CART_CHUNK_SIZE]; bool bext_chunk; // Does the chunk exist? QString bext_description; // BWF Description of sound sequence QString bext_originator; // BWF Name of originator QString bext_originator_ref; // BWF Reference of the originator QDate bext_origination_date; // BWF Origination date QTime bext_origination_time; // BWF Origination time unsigned bext_time_reference_low; // BWF Sample count since midnight, low unsigned bext_time_reference_high; // BWF Sample count since midnight, high unsigned short bext_version; // BWF Version of the BWF unsigned char bext_umid[64]; // BWF SMPTE UMD QString bext_coding_history; // BWF Coding History unsigned char bext_chunk_data[BEXT_CHUNK_SIZE]; unsigned char *bext_coding_data; unsigned bext_coding_size; bool mext_chunk; // Does the chunk exist? bool mext_homogenous; // Is the data homogenous? bool mext_padding_used; // Is the padding bit used? bool mext_rate_hacked; // Is padding not used for a 22 or 44 sr? bool mext_free_format; // Is it free format? int mext_frame_size; // Size of MPEG frame, n/c padding int mext_anc_length; // Ancillary data length bool mext_left_energy; // Does anc data contain left/mono energy bool mext_right_energy; // Does anc data contain right energy? bool mext_ancillary_private; // Does anc data contain private data? unsigned char mext_chunk_data[MEXT_CHUNK_SIZE]; bool has_energy; // Can we produce energy data? unsigned char levl_chunk_data[LEVL_CHUNK_SIZE]; unsigned levl_size; // Size of LEVL chunk bool levl_chunk; // Does LEVL chunk exist? int levl_version; // Version int levl_format; // Peak Data Format int levl_points; // Points per Peak int levl_block_size; // Frames per Peak Value int levl_channels; // Channels unsigned levl_frames; // Total Peaks unsigned levl_peak_offset; // Pointer to peak-of-peaks unsigned short levl_peak_value; // Value of peak-of-peaks unsigned levl_block_offset; // Offset to start of peaks QDateTime levl_timestamp; // Timestamp unsigned short levl_block_ptr; unsigned levl_istate; short levl_accum; QString cutString(char *,unsigned,unsigned); QDate cutDate(char *,unsigned); QTime cutTime(char *,unsigned); std::vector energy_data; bool energy_loaded; unsigned energy_ptr; int wave_id; RDWaveFile::Type wave_type; unsigned char *cook_buffer; int cook_buffer_size; float encode_quality; int serial_number; int atx_offset; bool scot_chunk; unsigned char scot_chunk_data[SCOT_CHUNK_SIZE]; QString scot_title; QString scot_artist; QString scot_etc; int scot_year; QString scot_cut_number; int scot_intro_length; int scot_eom_length; QDate scot_start_date; QTime scot_start_time; QDate scot_end_date; QTime scot_end_time; bool AIR1_chunk; unsigned char AIR1_chunk_data[AIR1_CHUNK_SIZE]; bool rdxl_chunk; QString rdxl_contents; double normalize_level; bool av10_chunk; unsigned char av10_chunk_data[AV10_CHUNK_SIZE]; #ifdef HAVE_VORBIS OggVorbis_File vorbis_file; vorbis_info vorbis_inf; vorbis_block vorbis_blk; vorbis_dsp_state vorbis_dsp; ogg_stream_state ogg_stream; ogg_page ogg_pg; ogg_packet ogg_pack; #endif // HAVE_VORBIS #ifdef HAVE_MP4_LIBS DLMP4 dlmp4; #endif }; /* * Cart Chunk Stuff */ #define CART_VERSION "0101" #define CART_DEFAULT_END_YEAR 2099 #define CART_DEFAULT_END_MONTH 12 #define CART_DEFAULT_END_DAY 31 #define CART_DEFAULT_END_HOUR 23 #define CART_DEFAULT_END_MINUTE 59 #define CART_DEFAULT_END_SECOND 59 #define CART_DEFAULT_LEVEL_REF 0x8000 /* * BWF Stuff */ #define BWF_VERSION 1 /* * WAVE Format Categories * (From RFC2361) */ #define WAVE_FORMAT_PCM 0x0001 #define WAVE_FORMAT_ADPCM 0x0002 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_VSELP 0x0004 #define WAVE_FORMAT_IBM_CVSD 0x0005 #define WAVE_FORMAT_ALAW 0x0006 #define WAVE_FORMAT_MULAW 0x0007 #define WAVE_FORMAT_OKI_ADPCM 0x0010 #define WAVE_FORMAT_DVI_ADPCM 0x0011 #define WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 #define WAVE_FORMAT_SIERRA_ADPCM 0x0013 #define WAVE_FORMAT_G723_ADPCM 0x0014 #define WAVE_FORMAT_DIGISTD 0x0015 #define WAVE_FORMAT_DIGIFIX 0x0016 #define WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 #define WAVE_FORMAT_MEDIAVISION_ADPCM 0x0018 #define WAVE_FORMAT_CU_CODEC 0x0019 #define WAVE_FORMAT_YAMAHA_ADPCM 0x0020 #define WAVE_FORMAT_SONARC 0x0021 #define WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 #define WAVE_FORMAT_ECHOSC1 0x0023 #define WAVE_FORMAT_AUDIOFILE_AF36 0x0024 #define WAVE_FORMAT_APTX 0x0025 #define WAVE_FORMAT_AUDIOFILE_AF10 0x0026 #define WAVE_FORMAT_PROSODY_1612 0x0027 #define WAVE_FORMAT_LRC 0x0028 #define WAVE_FORMAT_DOLBY_AC2 0x0030 #define WAVE_FORMAT_GSM610 0x0031 #define WAVE_FORMAT_MSNAUDIO 0x0032 #define WAVE_FORMAT_ANTEX_ADPCME 0x0033 #define WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 #define WAVE_FORMAT_DIGIREAL 0x0035 #define WAVE_FORMAT_DIGIADPCM 0x0036 #define WAVE_FORMAT_CONTROL_RES_CR10 0x0037 #define WAVE_FORMAT_NMS_VBXADPCM 0x0038 #define WAVE_FORMAT_ROLAND_RDAC 0x0039 #define WAVE_FORMAT_ECHOSC3 0x003A #define WAVE_FORMAT_ROCKWELL_ADPCM 0x003B #define WAVE_FORMAT_ROCKWELL_DIGITALK 0x003C #define WAVE_FORMAT_XEBEC 0x003D #define WAVE_FORMAT_G721_ADPCM 0x0040 #define WAVE_FORMAT_G728_CELP 0x0041 #define WAVE_FORMAT_MSG723 0x0042 #define WAVE_FORMAT_MPEG 0x0050 #define WAVE_FORMAT_RT24 0x0052 #define WAVE_FORMAT_PAC 0x0053 #define WAVE_FORMAT_MPEGLAYER3 0x0055 #define WAVE_FORMAT_LUCENT_G723 0x0059 #define WAVE_FORMAT_CIRRUS 0x0060 #define WAVE_FORMAT_ESPCM 0x0061 #define WAVE_FORMAT_VOXWARE 0x0062 #define WAVE_FORMAT_CANOPUS_ATRAC 0x0063 #define WAVE_FORMAT_G726_ADPCM 0x0064 #define WAVE_FORMAT_G722_ADPCM 0x0065 #define WAVE_FORMAT_DSAT 0x0066 #define WAVE_FORMAT_DSAT_DISPLAY 0x0067 #define WAVE_FORMAT_VOXWARE_BYTE_ALIGNED 0x0069 #define WAVE_FORMAT_VOXWARE_AC8 0x0070 #define WAVE_FORMAT_VOXWARE_AC10 0x0071 #define WAVE_FORMAT_VOXWARE_AC16 0x0072 #define WAVE_FORMAT_VOXWARE_AC20 0x0073 #define WAVE_FORMAT_VOXWARE_RT24 0x0074 #define WAVE_FORMAT_VOXWARE_RT29 0x0075 #define WAVE_FORMAT_VOXWARE_RT29HW 0x0076 #define WAVE_FORMAT_VOXWARE_VR12 0x0077 #define WAVE_FORMAT_VOXWARE_VR18 0x0078 #define WAVE_FORMAT_VOXWARE_TQ40 0x0079 #define WAVE_FORMAT_SOFTSOUND 0x0080 #define WAVE_FORMAT_VOXWARE_TQ60 0x0081 #define WAVE_FORMAT_MSRT24 0x0082 #define WAVE_FORMAT_G729A 0x0083 #define WAVE_FORMAT_MVI_MV12 0x0084 #define WAVE_FORMAT_DF_G726 0x0085 #define WAVE_FORMAT_DF_GSM610 0x0086 #define WAVE_FORMAT_ISIAUDIO 0x0088 #define WAVE_FORMAT_ONLIVE 0x0089 #define WAVE_FORMAT_SBC24 0x0091 #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 #define WAVE_FORMAT_ZYXEL_ADPCM 0x0097 #define WAVE_FORMAT_PHILIPS_LPCBB 0x0098 #define WAVE_FORMAT_PACKED 0x0099 #define WAVE_FORMAT_RHETOREX_ADPCM 0x0100 #define WAVE_FORMAT_IRAT 0x0101 #define WAVE_FORMAT_VIVO_G723 0x0111 #define WAVE_FORMAT_VIVO_SIREN 0x0112 #define WAVE_FORMAT_DIGITAL_G723 0x0123 #define WAVE_FORMAT_CREATIVE_ADPCM 0x0200 #define WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 #define WAVE_FORMAT_ CREATIVE_FASTSPEECH10 0x0203 #define WAVE_FORMAT_QUARTERDECK 0x0220 #define WAVE_FORMAT_FM_TOWNS_SND 0x0300 #define WAVE_FORMAT_BTV_DIGITAL 0x0400 #define WAVE_FORMAT_VME_VMPCM 0x0680 #define WAVE_FORMAT_OLIGSM 0x1000 #define WAVE_FORMAT_OLIADPCM 0x1001 #define WAVE_FORMAT_OLICELP 0x1002 #define WAVE_FORMAT_OLISBC 0x1003 #define WAVE_FORMAT_OLIOPR 0x1004 #define WAVE_FORMAT_LH_CODEC 0x1100 #define WAVE_FORMAT_NORRIS 0x1400 #define WAVE_FORMAT_ISIAUDIO2 0x1401 #define WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS 0x1500 #define WAVE_FORMAT_DVM 0x2000 /* * OggVorbis/FLAC Formats * * FIXME: These are made up out of thin air -- if a real registered number * exists, we should use that instead. */ #define WAVE_FORMAT_VORBIS 0xFFFF #define WAVE_FORMAT_FLAC 0xFFFE #define WAVE_FORMAT_M4A 0xFFFD /* * Proprietary Format Categories * (Not supported) */ #define MS_FORMAT_ADPCM 0x0002 #define ITU_FORMAT_G711_ALAW 0x0006 #define ITU_FORMAT_G711_MLAW 0x0007 #define IMA_FORMAT_ADPCM 0x0011 #define ITU_FORMAT_G723_ADPCM 0x0016 #define GSM_FORMAT_610 0x0031 #define ITU_FORMAT_G721_ADPCM 0x0040 #define IBM_FORMAT_MULAW 0x0101 #define IBM_FORMAT_ALAW 0x0102 #define IBM_FORMAT_ADPCM 0x0103 /* * MPEG Defines * * fwHeadLayer Flags */ #define ACM_MPEG_LAYER1 0x0001 #define ACM_MPEG_LAYER2 0x0002 #define ACM_MPEG_LAYER3 0x0004 /* * fwHeadMode Flags */ #define ACM_MPEG_STEREO 0x0001 #define ACM_MPEG_JOINTSTEREO 0x0002 #define ACM_MPEG_DUALCHANNEL 0x0004 #define ACM_MPEG_SINGLECHANNEL 0x0008 /* * fwHeadFlags Flags */ #define ACM_MPEG_PRIVATEBIT 0x0001 #define ACM_MPEG_COPYRIGHT 0x0002 #define ACM_MPEG_ORIGINALHOME 0x0004 #define ACM_MPEG_PROTECTIONBIT 0x0008 #define ACM_MPEG_ID_MPEG1 0x0010 #endif // RDWAVEFILE_H