PDA

View Full Version : dMC R12 and above



Spoon
11-07-2005, 03:35 PM
There is a new codec design undergoing writing for dMC r12 and above, why the change? they are needed for the more advanced things dbpoweramp needs to do in the future, this design should be one of the most / if not the most advanced codec designs in existance (developed using years of experiance)...enough blagging, here is the design:



*ifndef dBCodecH
*define dBCodecH

*include <mmreg.h>

// << FIX ME - ?? ALLOW EXTERNAL file reader / writer - external definitions

//-----------------------------------------------------------------
/* Header acessing dBpowerAMPs Codecs, note all extern C

Definitions: ID Tag - an item that can be read and set (including ReplayGain and Album Art)
AudioProps - read only items (such as encoder used, channel mapping)
<in> = input into Codec, <out> = value sent back to dBpowerAMP

Requirements for all Codecs:
WAVEFORMATEXTENSIBLE is used for all encoders / decoders (can have a WAVEFORMATEX within that, ie wfxex.Format.wFormatTag can be WAVE_FORMAT_PCM)
Decoders:
Only pass out WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT (or those types in WAVE_FORMAT_EXTENSIBLE)
Any 'standard' frequency, any channel count (well upto 10)
8, 16, 24, 32 bit (IEEE float is 32 bit)
ALL Encoders must expect the above type of data (plus buffers that are NULL, 0 bytes)
*/
//-----------------------------------------------------------------

extern "C" {

struct STdBCodecGetSet; struct STdBOpenEncoder; struct STdBAudioInfo; // forward declarations (see real below)
struct STdBOpenDecoder; struct STdBAudioBlock;

//================================================== =============================
//================================================== =============================
//================================================== =============================
// DECODER DECODER DECODER DECODER DECODER DECODER DECODER
//================================================== =============================
//================================================== =============================
//================================================== =============================
namespace dBDecoder {
//================================================== =============================
// Creates a Decoder, returned value is used in functions, return=NULL is error
//================================================== =============================
typedef void *(* Create)(void);

//================================================== =============================
// Destroys a Decoder, returns != 0 if ok
//================================================== =============================
typedef int (* Destroy)(void *Decoder);

//================================================== =============================
// Get settings / values from codec, returns !=0 if got ok
// See below for common supported decoder items
//================================================== =============================
typedef int (* Get)(void *Decoder, wchar_t *Getting, STdBCodecGetSet &Pass);

//================================================== =============================
// Set settings / values from codec, returns !=0 if set ok
// See below for common supported decoder items
// NB IDTags are set through Set
//================================================== =============================
typedef int (* Set)(void *Decoder, wchar_t *Setting, STdBCodecGetSet &Pass);

//================================================== =============================
// Opens a file, returns !=0 if opened ok, codec writes errors to error handle
// NB IDTags + general length etc information are read through open
//================================================== =============================
typedef int (* Open)(void *Decoder, STdBOpenDecoder &Pass);

//================================================== =============================
// Decode a block of data *** BLOCKS SHOULD BE ALWAYS nBlockAlign sized ***
// return 0 if error, errors should be written to hError (all other items out in DecodeBlock)
//================================================== =============================
typedef int (* DecodeBlock)(void *Decoder, STdBAudioBlock &AudioBlock);

//================================================== =============================
// Skips to position ie 1000 for 1 second in, decoder should kill any caching
// return 0 if error
//================================================== =============================
typedef int (* SetPosition)(void *Decoder, __int64 TimePosmS);

//================================================== =============================
// Deletes tag(s) from file, Elements ie 'Element1\0Element2\0\0'
// if no elements then ALL ID Tags are deleted
// returns true if deleted ok
//================================================== =============================
typedef int (* DeleteATag)(void *Decoder, wchar_t *FileName, wchar_t *Elements);

};

//================================================== =============================
//================================================== =============================
//================================================== =============================
// ENCODER ENCODER ENCODER ENCODER ENCODER ENCODER ENCODER
//================================================== =============================
//================================================== =============================
//================================================== =============================
namespace dBEncoder {

// ** See 'Requirements for all Codecs' above
// ** Encoder must expect ID Tags from list below (including DATA items, such as RIFF chunks)

//================================================== =============================
// Creates an Encoder, returned value is used in functions, return=NULL is error
//================================================== =============================
typedef void *(* Create)(void);

//================================================== =============================
// Destroy Encoder, returns != 0 if ok
//================================================== =============================
typedef int (* Destroy)(void *Encoder);

//================================================== =========================
// Called to Show the configuration settings on the main form
//================================================== =========================
typedef void (* ShowConfigBit)(void *Encoder, HWND OnForm);

//================================================== =========================
// Called to RemoveConfigBit the configuration settings from the main form
//================================================== =========================
typedef void (* RemoveConfigBit)(void *Encoder, HWND OnForm);

//================================================== =============================
// Open Encoder, return != 0 if opened for decoding ok (audioprops + idtags, etc check return for value for !=0)
//================================================== =============================
typedef int (* Open)(void *Encoder, STdBOpenEncoder &OpenEncoder);

//================================================== =============================
// Close Encoder, return != 0 if opened ok: Creation order Create, Open, Close, Destroy
//================================================== =============================
typedef int (* Close)(void *Encoder);

//================================================== =============================
// Encode a block of data
// return 0 if error, errors should be written to hError (all other items out in DecodeBlock)
//================================================== =============================
typedef int (* EncodeBlock)(void *Encoder, STdBAudioBlock &AudioBlock);

//================================================== =============================
// Get settings / values from codec, returns !=0 if got ok
// See below for common supported encoder items
//================================================== =============================
typedef int (* Get)(void *Encoder, wchar_t *Getting, STdBCodecGetSet &Pass);

//================================================== =============================
// Set settings / values from codec, returns !=0 if set ok
// See below for common supported encoder items
//================================================== =============================
typedef int (* Set)(void *Encoder, wchar_t *Setting, STdBCodecGetSet &Pass);
};


//================================================== =============================
//================================================== =============================
//================================================== =============================
// In out Structures, In out Structures, In out Structures, In out Structures
//================================================== =============================
//================================================== =============================
//================================================== =============================

//---general items struct: used by Get / Set----
struct STdBCodecGetSet {
int Index;
int Item1;
__int64 Item2;
__int64 Item3;
wchar_t *Item4;
wchar_t *Item5;
wchar_t *Item6;
void *Item7;
};

//------used to describe an audio format--------
struct STdBAudioInfo { // NB by default dB sets all items to 0/NULL
WAVEFORMATEXTENSIBLE WFXEx; // ONLY uncompressed audio allowed here
int bps; // Average bitrate (in bits per second) ie 192000
__int64 Lengthmsec; // Time length in mili seconds (length of audio block, or entire file Decoder::Open)
__int64 FileSize; // only used by Decoder::Open, size in bytes of compressed data
int Blank0; // not used
void *Blank1; // not used
};

//---------------Passed to Decoder::Open-----------------
*define DECODE_WANT_TODECODE 1 // if (ShouldReturn & DECODE_WANT_TODECODE) then must be ready for Decode::DecodeBlock)
*define DECODE_WANT_AUDIOINFO 2
*define DECODE_WANT_IDTAGS 4
*define DECODE_WANT_AUDIOPROPS 8

struct STdBOpenDecoder { // NB by default dB sets all items to 0/NULL
wchar_t *FileName; // <in> filename (with extension)
HANDLE hError; // <in> file handle for errors, can be NULL - if write should write 'Line describing problem\r\n', no filenames
HANDLE hInformation; // <in> file handle for Information pass back to main prog, can be NULL - as above
HANDLE hDebug; // <in> file handle for Debugging, can be NULL - as above
int ShouldReturn; // <in> combination of DECODE_ items above
STdBAudioInfo AudioInfo; // <out> if ShouldReturn & DECODE_WANT_AUDIOINFO fill in
void *IDTags; // <out> if ShouldReturn & DECODE_WANT_IDTAGS then return 'Packed IDTag Datablock' (see below), return NULL if no tags
// returned string is owned by Decoder and is valid until next call / Destroy
DWORD IDTagByteSize; // <out> size in bytes of data pointed to by IDTags (used more as a safety, to stop mem overflows)
void *AudioProps; // <out> if ShouldReturn & DECODE_WANT_AUDIOPROPS then return encoded as IDTags properties on the file, see 'Common AudioProps' below for standard items
DWORD AudioPropsByteSize;// <out> size in bytes of data pointed to by AudioProps (used more as a safety, to stop mem overflows)
int Blank0; // not used
int Blank1; // not used
void *Blank2; // not used
void *Blank3; // not used
};

struct STdBOpenEncoder {
wchar_t *FileName; // <in> filename (with extension)
HANDLE hError; // <in> file handle for errors, can be NULL - if write should write 'Line describing problem\r\n', no filenames
HANDLE hInformation; // <in> file handle for Information pass back to main prog, can be NULL - as above
HANDLE hDebug; // <in> file handle for Debugging, can be NULL - as above
STdBAudioInfo AudioInfo; // <in> Describing audio stream
};

//--------An Audio Block, from Decode::DecodeBlock and sent to Encoder---------
struct STdBAudioBlock // NB by default dB sets all items to 0/NULL
{
void *pData; // <out> can be NULL, data block is owned by decoder and is valid until next call or class destroy
DWORD DataBytes; // <out> Datasize as pointed to by pData
STdBAudioInfo AudioInfo;// <out> Describes audio data
__int64 PositionMiliSec;// <out> Start position of block in Mili Seconds
int IsLast; // <out> when !=0 is last data block
int Blank0; // not used
int Blank1; // not used
void *Blank2; // not used
void *Blank3; // not used
};


//================================================== =============================
/* Common Decoder 'Get' items, all other items in STdBCodecGetSet = 0 (both in + out)

'Decodes'
Index: <in> 0..1..2 until Item4 returns NULL
Item4: <out> wide string .mp3
Item5: <out> wide string mp3 (*.mp3)

'Decoder Description'
Item4: <out> wide string ie 'mpeg Decoder', could be NULL

'Copyright License'
Item4: <out> wide string that appears in dBpowerAMPs about box ie 'Code Licensed from (c) 2004 bla bla', could be NULL

'Property Elements' // SEE 'Common AudioProps' below, used so dBpowerAMP knows what elements to expect - only use for presenting possibles to user (in call to Open)
Item4: <out> wide str example 'Encoder\rEncoder Settings' (can be NULL)

'Default Property Elements' // Items to show as default in popup, other items have to be ticked by user
Item4: <out> wide str example 'Encoder\rSomething' (can be NULL)

'ID Tag Options'
Index: <in> Main Item Index (change in this changes Item4) 0..1..2 until Item4 returns NULL
Item1: <in> Sub Item Index (change 0..1..2 until Item6 returns 0)
Item4: <out> wide str Option Title (corresponds to Index) example 'Tag Creation'
Item5: <out> wide str Option Registry String 'FlacTagCreation' // real reg path is HKCU\Software\Illustrate\dbpoweramp\Tagging
Item6: <out> option Value (for Sub Item Index) ie 'ID3v2'

'Options'
Index: <in> Main Item Index (change in this changes Item4) 0..1..2 until Item4 returns NULL
Item1: <in> Sub Item Index (change 0..1..2 until Item6 returns 0)
Item4: <out> wide str Option Title (corresponds to Index) example 'Decode To'
Item5: <out> wide str Option Registry String 'CodecOptions\\Mp3DecodeTo' // real reg path is HKCU\Software\Illustrate\dbpoweramp\[plus any set by itself]
Item6: <out> option Value (for Sub Item Index) ie 'IEEE Float'

'Protected'
Item4: <in> wide str filename
Item1: <out> 1=file is DRM protected, 0=not

'NonSeekable'
Item4: <in> wide str filename
Item1: <out> 1=file is not-seekable (perhaps internet stream), 0=seekable (normal file)

'ShouldDisableSameFolder'
Item1: <out> 1=Disable dMC Convert To 'Same Folder' as used by CD Ripper, 0=no disable

Common Decoder 'Set' items, all other items in STdBCodecGetSet = 0 (both in + out), all are optional (do not rely on them)

'IDTags' set ID Tags [NOTE: File COULD BE OPEN FOR READING OR NOT]
Item1: <in> Length of Data block (pointed by Item7)
Item7: <in> Packed IDTag Datablock (see below)

'Program'
Item4: <in> wide string of program using ie 'dMC' 'Sveta' 'dAP'

'Set Decode Range' ** positions might be outside of stream
Item2: <in> Position to decode from in miliseconds (for say a cue sheet)
Item3: <in> Position to decode to in mSec

'Dither'
<< FIX ME - so can set 'windowing type'
*/
//================================================== =============================
//================================================== =============================
/* Common Encoder 'Get' items, all other items in STdBCodecGetSet = 0 (both in + out)

'Extension'
Item4: <out> Extension used by encoder ie '.mp3', '.IGNORE' is a special one (output is virtual, on rename page will not offer a real filename)

'MangleOutFileName'
set by Music Converter to get a final filename // << FIX ME
// << FIX ME ?? have a function where 1 file goes in and can give multiple files out??

'OutputNotReal'
Item1: <out> 1=Disable dMC 'Convert To'+'Delete Source File'+'Add to dAP'+ Does not check file overwrite, 0=normal

'NoTryToIDTag'
Item1: <out> 1=dMC does not call input decder after encoding to set ID Tags, 0=normal

'Options'
Index: <in> Main Item Index (change in this changes Item4) 0..1..2 until Item4 returns NULL
Item1: <in> Sub Item Index (change 0..1..2 until Item6 returns 0)
Item4: <out> wide str Option Title (corresponds to Index) example 'Decode To'
Item5: <out> wide str Option Registry String 'CodecOptions\\Mp3DecodeTo' // real reg path is HKCU\Software\Illustrate\dbpoweramp\[plus any set by itself]
Item6: <out> option Value (for Sub Item Index) ie 'IEEE Float'

'SendRawUnCompressed' [Note: Called Between Encoder::Create and Encoder::Open]
Item4: <in> Converting From File
Item5: <out> Converting To File
Item1: <out> 1=Send Raw (not decoded Files) 0=compress as data stream (normal)

Common Encoder 'Set' items, all other items in STdBCodecGetSet = 0 (both in + out)

'Profile' [Note: Called straight after Encoder::Create]
Item4: <in> a wide str, ie 'Sveta' - each encoder should save its settings unique to a profile

'Encoded From' [Note: Called straight after Encoder::Create]
Item4: <in> wide string of program using ie 'Audio CD', 'Lossy', 'Lossless'

'ProFreq'
<no settings> if called then use professional frequency conversion

'ChannelMap'
<< FIX ME - advanced user selectable mapping

'Dither'
<< FIX ME - so can set 'windowing type'

'IDTags' [NOTE: Called Once between Encoder::Create and Encoder::Open (not when showing Config)]
Item1: <in> Length of Data block (pointed by Item7)
Item7: <in> Packed IDTag Datablock (see below)
*/
//================================================== =============================


//================================================== =============================
/* Packed IDTag Datablock (as returned from decoder, or sent to encoder)
A Raw item is:
int TagElementCount
...0 to < TagElementCount
int ElementTotalSize ((Element chars + 1[null]) * 2) + ((Value chars + 1[null]) * 2) + datalength
ELEMENT\0
VALUE\0
Any Bytes left from ElementTotalSize are Data (raw bytes)
..next item

-------Common ID Tag Elements (upper or lower case):-----------
artist ie Madonna (or performer) multi artists split with Artist1\rArtist2
album ie Immaculate
title ie Like a virgin
genre ie Pop multi genres split with Genre1\rGenre2
year ie 2003 or 2003 08 31 or 2003 January
track ie 14
comment ie Any waffle

disc ie 2 CD 2
disccount ie 4 (4 disc set)
rating 1 to 10
playcount Times played ie 57
bpm beats per minute
composer ie Motzart
label publisher

albumart data should point to either jpg or png
cdtoc data points to raw CD TOC

riff_x riff data item (riff_1 is first, riff_2 next), << FIX ME - comprises complete riff chunk, including identifier such as 'BTXT'
only WAVE subchunks need to be saved, also save 'fmt ' and 'data' ('fmt '[4 byte len all 0]) so order of riff chunks can be reproduced

replaygain_track_gain replay gain info << FIX ME - in string??
replaygain_track_peak
replaygain_album_gain
replaygain_album_peak

MD5 Hash An MD5 hash of orignal data

--------Common AudioProps items (case can be upper or lower case):--------

Encoder Encoder used, such as Lame 3.97
Encoder Settings Settings of Encoder, such as CBR 128Kbps, PCM, IEEE Float, ADPCM
ID Tag Type of ID Tag used in file, ie ID3v2.2 & ID3v1.1
Channel Mapping Left, Right, Centre
Riff Chunks 'fmt ' size xx bytes 'data' size xx bytes
Sample Count 563899 Samples per second (channel independant, ie CD quality is 44,100 sample/sec)
*/

//================================================== =============================
//================================================== =============================
}; // end Extern "C"

*endif



So what does this mean for pre-dmc 12 releases? an emulation layer will be written for the codecs to make then backwards compatible with older dmcs, but only when there is a new dmc up a running.