So, here's the seperate thread for ATL improvements. Just to summarize what I was doing so far:
I started a new MPEGAudioEx.pas nearly from scratch and TMPEGAudioFrame and its subclasses do already perform the functions to read and decode frame headers and side information and to synchronize with a given stream.
For now MPEGAudioEx is working with stream objects only, but in order to be compatible to the old ATL the TMPEGAudio object will provide the same public methods and properties as the old one does. This will include a ReadFromFile method which takes a file name as the only parameter.
There are several questions which need to be answered:
1. Should a buffered file component be implemented and used internally?
2. Should a TAG manager component be written to enable reading of all known tags on all audio file type classes?
3. Should helper classes like TBitwiseStreamReader and possible TBufferedFileStream be seperated and put into a new helper unit?
IMHO all questions should be answered with Yes.
To summarize the capabilities of MPEGAudioEx here is a full class list and important, newly invented methods:
CLASSES
TBitwiseStreamReader = class;
TMPEGAudioFrame = class;
TMPEGAudioHeader = class;
TMPEGAudioSideInfoChannel = class;
TMPEGAudioSideInfoGranuleMono = class;
TMPEGAudioSideInfoGranuleStereo = class;
TMPEGAudioSideInfoMono = class;
TMPEGAudioSideInfoNormalWindow = class;
TMPEGAudioSideInfoSCFSI = class;
TMPEGAudioSideInfoShortWindow = class;
TMPEGAudioSideInfoStereo = class;
METHODS
function ReadFromStream(Stream: TStream): Boolean; overload;
function ReadFromStream(Stream: TStream;
Offset: Integer): Boolean; overload;
function ReadFromStream(Stream: TStream;
Offset, SyncDistance, SubsequentFrames: Integer): Boolean; overload;
ReadFromStream is part of TMPEGAudioFrame and is able to:
- read a frame from the current position of a stream
- read a frame from a given position of a stream
- synchronize with a stream, given max. search distance & min. number of valid subsequent frames
When using a TMemoryStream (i.e. load all data from an MP3 file to the memory stream) it does take about 110ms to decode all headers and side information in case of a 14mb 192kbit file (prebuffering excluded). This means that it would take just around 8 seconds to scan 1gb for corrupt data (which in nearly all cases can be found by detecting synchronization loss) including decoding only, reading file data excluded.
Tested on a P4 2,4 GHz machine. Here is a log of my personal test program:
Loading file took 391ms
First frame found at: 1418
Resynchronization lost at position 8645022
Last frame at: 8645149
Scanning all frames took 61ms