📄 mpgtools.pas
字号:
- I must apology to those who asked help about using this unit and I
point them to "short example provided in documentation". I
overseeked that I added that example after I published version 1.5
and that it was not available until now.
- TMPEGAudio now inherits TObject instead of TComponent.
- Fixed bug not recognizing MPEG file properly reported by Jean
Nicolle. It showed up that I had a bug but also that method used for
validation was not good enough. Not just it was not able to
recognize each MPEG file as such, but often recognized files which
surely were not MPEG as MPEG. Now it checks for two frame headers
in a row, which significantly reduces false recognitions. Any
suggestions about improvements are welcome.
- Added FirstValidFrameHeaderPosition property as result of previous
bugfix.
- Added Macro and Text property as replacement for Textilize method.
Textilize method is still there and will not be removed. These two
properties just may speed things up if you do not often change
macros or MPEG data. This resulted with some small but numbered
changes in property and method definitions, but nothing changed in
syntax and functionality.
- Few macro tag items changed and added to support new properties and
structure changes.
- TMPEGData.FileName field changed due to suggestion of Torben
Weibert. Now it is string 255 chars long. Request was to make this
field very long string, but I could not manage to do that without
loosing compatibility with Delphi 1. I hope filepaths longer than
255 characters are rare. If anyone needs it longer, and does not
care about TMPEGData record length, he may simply change definition
for this field.
- Dealing with files not containing TAG changed a bit. If MPEG file
does not contain TAG then TMPEGAudio.Data.Title field will be filled
with MPEG filename (without path). This is same behaviour as
WinAmp's.
- Data structure of TMPEGData changed to version 1.2.
o Padding field added so we can now calculate frame size.
o SampleRate field type changed to LongInt to make it more
compatible with other languages and compiler versions. Real type
was very bad choice. WARNING! Now this field contains integer
value of sampling rate in Hz not in kHz like previous versions.
o FrameLength added. It stores framesize in bytes.
o Version field now contains index to MPEG Version, not exact
version number. This is done to support MPEG Version 2.5 which now
has index of 3. Apropriate constants definition provided.
- Finally I found out how to make TMPEGData record size independent of
compiler version. Problem was not just with real type. I founded
that Integer type length also changes. In Delphi 1 it is 2 bytes,
but in Delphi 3 it is 4 bytes long. Since I needed two byte values
in few fields, i replaced Integer type with word and everything is
now ok. I am suspicious about LongInt (currently it is 4 bytes
long). Anyone with Delphi 4, let me know is it still 4 bytes long?
Funniest bug is TDateTime type. I am used to it since Borland Pascal
where it was 8 bytes long record. In Delphi they changed it to real.
Yes I was aware of that, but... Well, now I use LongInt instead.
Note that TMPEGAudio.FileDateTime property still returns value as
TDateTime. Conversion is done internaly. Remember that
TMPEGAudio.FileDateTime and TMPEGAudio.Data.FileDateTime are not
same type any more. If you need to read or write to
TMPEGAudio.Data.FileDateTime directly, use FileDatetoDateTime() and
DateTimetoFileDate() conversion functions provided with Delphi.
- MPEG_VERSION* constants added due to support MPEG Version 2.5 files.
- MPEG_VERSIONS constant array added to describe MPEG Version
- MPEG_SAMPLE_RATES adjusted to support MPEG Audio Version 2.5 files
- MPEG_BIT_RATES adjusted to support MPEG Audio Version 2.5 files
- Added support for reading MPEG Audio files of Version 2.5. I have
not tested it since I do not have any MPEG file of this version.
- TMPEGAudio class is polished. It may be assumed finished. I think
there will be no major changes in it.
- This unit version presents TMPEGAudioList class. It should free you
of using TList and dealing with pointers and typecasting. It is
descendent of TList class and uses TMPEGAudio as base data structure.
It is not well documented yet, but I am sure you will understand it
by looking at class definition. Do not use it. It is here just to
show you the basic idea. I cannot guarantee it will not be changed.
Feel free to share your ideas about it with me. If you notice bad
coding practice I used, do not hestitate to say it.
- TMPEGAudioList.AddFromMPEGFile method is adjusted to recognize all
three TMPEGData versions. It will return values according to the
newest structure definition.
- I have opened MPGTools support mail list. Anyone who wants
membership may send me a mail. It is one way list for now. You will
receive only news about updates I send. If you like, I can make all
members receive messages other members sent to the list.
- Together with this unit version I am publishing soruces of two
simple applications TAG Editor and MPEG List to demonstrate how to
use it.
- Few typo's corrected. I am also sure I made few new typo's.
1.5 (23. August 1998)
- The first public version released
}
interface
{$DEFINE UseDialogs}
uses SysUtils, WinTypes, WinProcs, Classes, Messages, Controls,
{$IFDEF UseDialogs}Dialogs, {$ENDIF}INIFiles;
const
UnitVersion = '1.8'; { current version of this unit }
MaxStyles = 125; { number of supported Genre codes.
If code is greater it will be assumed unknown }
{ MPEG version indexes }
MPEG_VERSION_UNKNOWN = 0; { Unknown }
MPEG_VERSION_1 = 1; { Version 1 }
MPEG_VERSION_2 = 2; { Version 2 }
MPEG_VERSION_25 = 3; { Version 2.5 }
{ Description of MPEG version index }
MPEG_VERSIONS : array[0..3] of string = ('Unknown', '1.0', '2.0', '2.5');
{ Channel mode (number of channels) in MPEG file }
MPEG_MD_STEREO = 0; { Stereo }
MPEG_MD_JOINT_STEREO = 1; { Stereo }
MPEG_MD_DUAL_CHANNEL = 2; { Stereo }
MPEG_MD_MONO = 3; { Mono }
{ Description of number of channels }
MPEG_MODES : array[0..3] of string = ('Stereo', 'Joint-Stereo',
'Dual-Channel', 'Single-Channel');
{ Description of layer value }
MPEG_LAYERS : array[0..3] of string = ('Unknown', 'I', 'II', 'III');
{
Sampling rates table.
You can read mpeg sampling frequency as
MPEG_SAMPLE_RATES[mpeg_version_index][samplerate_index]
}
MPEG_SAMPLE_RATES : array[1..3] of array[0..3] of word =
{ Version 1 }
((44100, 48000, 32000, 0),
{ Version 2 }
(22050, 24000, 16000, 0),
{ Version 2.5 }
(11025, 12000, 8000, 0));
{
Predefined bitrate table.
Right bitrate is MPEG_BIT_RATES[mpeg_version_index][layer][bitrate_index]
}
MPEG_BIT_RATES : array[1..3] of array[1..3] of array[0..15] of word =
{ Version 1, Layer I }
(((0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0),
{ Version 1, Layer II }
(0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0),
{ Version 1, Layer III }
(0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0)),
{ Version 2, Layer I }
((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0),
{ Version 2, Layer II }
(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0),
{ Version 2, Layer III }
(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)),
{ Version 2.5, Layer I }
((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0),
{ Version 2.5, Layer II }
(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0),
{ Version 2.5, Layer III }
(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)));
{ Types of MPEG AUDIO DATAFILE }
MPEG_DF_CUSTOM = 0;
MPEG_DF_CATALOGUE = 1;
MPEG_DF_ORDER_FORM = 2;
{ Description of MPEG AUDIO DATAFILE type }
MPEG_DATAFILE_TYPES : array[0..2] of string = ('Custom','Catalogue',
'Order form');
{ Sign for MPEG Audio Datafile. This is used in MPEG Audio Datafile
header to identify file as such. First eight bytes (i.e #9'MP3DATA')
are file id, and rest two bytes are version and subversion numbers.
Do not change it. }
MPEG_DATAFILE_SIGN : string[9] = 'MP3DATA'+#01+#02;
{ File types that unit can recognize and read }
FT_ERROR = -1; { Specified file does not exist,
or error openning file }
FT_UNKNOWN = 0; { Unknown file type }
FT_WINAMP_PLAYLIST = 1; { WinAmp playlist (*.m3u) }
FT_MPEG_DATAFILE = 2; { MPEG Audio Datafile (*.m3d) }
FT_MPEG_AUDIO = 3; { MPEG Audio (*.mp*) }
FT_PLS_PLAYLIST = 4; { PLS Playlist (*.pls) }
{ Global variable containing delimiter used to separate artist from title
in file name }
FILENAMEDATADELIMITER : char = '-';
{ Xing VBR header flags }
XH_FRAMES_FLAG = 1;
XH_BYTES_FLAG = 2;
XH_TOC_FLAG = 4;
XH_VBR_SCALE_FLAG = 8;
var
{ Descriptions of Genre codes. Unit fills this array on initialization. }
MusicStyle : array[0..MaxStyles] of string;
type
{ Xing VBR Header data structure }
TXHeadData = record
flags : Integer; { from Xing header data }
frames : Integer; { total bit stream frames from Xing header data }
bytes : Integer; { total bit stream bytes from Xing header data }
vbrscale : Integer; { encoded vbr scale from Xing header data }
end;
String3 = string[3];
String4 = string[4];
String30 = string[30];
String20 = string[20];
String79 = string[79];
String255 = string[255];
{ MEGAUDIODATAFILE v1.1 header for Catalogue record definition. Same
header counts for v1.2 header. Do not use this type definition
directly. Use TMPEGDataCatalogue instead. }
TMPEGDataCatalogue1v1 = packed record
Title : string[30]; { Catalogue title }
Publisher : string[30]; { Catalogue publisher name }
City : String[30]; { Publisher's contact info }
ZIP : String[10];
Country : String[20];
Address : String[30];
Phone: String[15];
Fax: string[15];
Email: string[30];
WWWURL: string[30];
end;
{ Old header for Catalogue record used in MPEGAUDIODATAFILE v1.0
definition. Obsolete. Used internaly to make unit able to read old
file version. However, unit will never create old version file. }
TMPEGDataCatalogue1v0 = record
Title : string[30];
Publisher : string[30];
City : String[30];
ZIP : String[10];
Country : String[20];
Address : String[30];
Phone: String[15];
Fax: string[15];
Email: string[30];
WWWURL: string[30];
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -