title
Products            Buy            Support Forum            Professional            About            Codec Central
 

dMC R12 and above

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Spoon
    Administrator
    • Apr 2002
    • 44583

    dMC R12 and above

    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:

    Code:
    #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.
    Spoon
    www.dbpoweramp.com
Working...

]]>