Initial revision

CQTexperiment
vspader 2005-06-02 18:16:43 +00:00
commit 655c5d7093
997 changed files with 348887 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

27
AppController.h Normal file
View File

@ -0,0 +1,27 @@
/* AppController */
#import <Cocoa/Cocoa.h>
#import "PlaylistController.h"
@interface AppController : NSObject
{
IBOutlet PlaylistController *playlistController;
IBOutlet NSPanel *infoPanel;
IBOutlet NSWindow *mainWindow;
}
- (IBAction)addFiles:(id)sender;
- (IBAction)delEntries:(id)sender;
- (IBAction)showInfo:(id)sender;
- (IBAction)savePlaylist:(id)sender;
- (IBAction)savePlaylistAs:(id)sender;
- (IBAction)loadPlaylist:(id)sender;
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo;
//Fun stuff
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames;
@end

142
AppController.m Normal file
View File

@ -0,0 +1,142 @@
#import "AppController.h"
@implementation AppController
- (IBAction)addFiles:(id)sender
{
NSOpenPanel *p;
p = [NSOpenPanel openPanel];
[p setCanChooseDirectories:YES];
[p setAllowsMultipleSelection:YES];
// [p beginSheetForDirectory:nil file:nil types:[`listController acceptableFileTypes] modalForWindow:mainWindow modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
// [p beginForDirectory:nil file:nil types:[playlistController acceptableFileTypes] modelessDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
if ([p runModalForTypes:[playlistController acceptableFileTypes]] == NSOKButton)
{
[playlistController addPaths:[p filenames] sort:NO];
}
}
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
if (returnCode == NSOKButton)
{
[playlistController addPaths:[panel filenames] sort:NO];
}
[panel release];
}
- (IBAction)delEntries:(id)sender
{
[playlistController remove:self];
}
- (IBAction)showInfo:(id)sender
{
[infoPanel makeKeyAndOrderFront:self];
}
- (PlaylistEntry *)currentEntry
{
return [playlistController currentEntry];
}
- (BOOL)application:(NSApplication *)sender delegateHandlesKey:(NSString *)key
{
// DBLog(@"W00t");
return [key isEqualToString:@"currentEntry"];
}
- (void)awakeFromNib
{
// DBLog(@"AWAKe");
NSString *filename = @"~/Library/Application Support/Cog/Default.playlist";
[playlistController loadPlaylist:[filename stringByExpandingTildeInPath]];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
// DBLog(@"QUITTING");
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *folder = @"~/Library/Application Support/Cog/";
folder = [folder stringByExpandingTildeInPath];
if ([fileManager fileExistsAtPath: folder] == NO)
{
[fileManager createDirectoryAtPath: folder attributes: nil];
}
NSString *fileName = @"Default.playlist";
[playlistController savePlaylist:[folder stringByAppendingPathComponent: fileName]];
}
- (IBAction)savePlaylist:(id)sender
{
if ([playlistController playlistFilename] == nil)
[self savePlaylistAs:sender];
[playlistController savePlaylist:[playlistController playlistFilename]];
}
- (IBAction)savePlaylistAs:(id)sender
{
NSSavePanel *p;
p = [NSSavePanel savePanel];
[p setAllowedFileTypes:[playlistController acceptablePlaylistTypes]];
if ([p runModalForDirectory:nil file:[[playlistController playlistFilename] lastPathComponent]] == NSOKButton)
{
[playlistController setPlaylistFilename:[p filename]];
[playlistController savePlaylist:[p filename]];
}
}
- (IBAction)loadPlaylist:(id)sender
{
NSOpenPanel *p;
p = [NSOpenPanel openPanel];
[p setCanChooseDirectories:NO];
[p setAllowsMultipleSelection:NO];
if ([p runModalForTypes:[playlistController acceptablePlaylistTypes]] == NSOKButton)
{
[playlistController setPlaylistFilename:[p filename]];
[playlistController loadPlaylist:[p filename]];
}
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
// if (flag == NO)
[mainWindow makeKeyAndOrderFront:self];
return NO;
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if ([playlistController addPaths:[NSArray arrayWithObject:filename] sort:NO] != 1)
return NO;
return YES;
}
- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames
{
[playlistController addPaths:filenames sort:YES];
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}
@end

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

3
Changelog Normal file
View File

@ -0,0 +1,3 @@
Awesomized id3v2 and tagging support courtesy of TagLib.
Dramatically improved performance of monkeys audio codec.
minor bug fixes.

114
Cog.scriptSuite Normal file
View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppleEventCode</key>
<string>CoRo</string>
<key>Classes</key>
<dict>
<key>NSApplication</key>
<dict>
<key>AppleEventCode</key>
<string>capp</string>
<key>Attributes</key>
<dict>
<key>currentEntry</key>
<dict>
<key>AppleEventCode</key>
<string>CoCE</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>PlaylistEntry</string>
</dict>
</dict>
<key>Superclass</key>
<string>NSCoreSuite.NSApplication</string>
</dict>
<key>PlaylistEntry</key>
<dict>
<key>AppleEventCode</key>
<string>CoPE</string>
<key>Attributes</key>
<dict>
<key>album</key>
<dict>
<key>AppleEventCode</key>
<string>CoAl</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
<key>artist</key>
<dict>
<key>AppleEventCode</key>
<string>CoAr</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
<key>genre</key>
<dict>
<key>AppleEventCode</key>
<string>CoGe</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
<key>length</key>
<dict>
<key>AppleEventCode</key>
<string>CoLe</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSNumber&lt;Double&gt;</string>
</dict>
<key>bitRate</key>
<dict>
<key>AppleEventCode</key>
<string>CoBi</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSNumber&lt;Int&gt;</string>
</dict>
<key>title</key>
<dict>
<key>AppleEventCode</key>
<string>CoTi</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
<key>track</key>
<dict>
<key>AppleEventCode</key>
<string>CoTr</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
<key>year</key>
<dict>
<key>AppleEventCode</key>
<string>CoYe</string>
<key>ReadOnly</key>
<string>YES</string>
<key>Type</key>
<string>NSString</string>
</dict>
</dict>
<key>Superclass</key>
<string>NSCoreSuite.AbstractObject</string>
</dict>
</dict>
<key>Name</key>
<string>Cog</string>
</dict>
</plist>

100
Cog.scriptTerminology Normal file
View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Classes</key>
<dict>
<key>NSApplication</key>
<dict>
<key>Attributes</key>
<dict>
<key>currentEntry</key>
<dict>
<key>Description</key>
<string>The currently playing entry.</string>
<key>Name</key>
<string>currententry</string>
</dict>
</dict>
<key>Description</key>
<string>Cog's top level scripting object.</string>
<key>Name</key>
<string>application</string>
<key>PluralName</key>
<string>applications</string>
</dict>
<key>PlaylistEntry</key>
<dict>
<key>Attributes</key>
<dict>
<key>album</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>album</string>
</dict>
<key>artist</key>
<dict>
<key>Description</key>
<string>The artist of the entry.</string>
<key>Name</key>
<string>artist</string>
</dict>
<key>genre</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>genre</string>
</dict>
<key>length</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>length</string>
</dict>
<key>bitRate</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>bitRate</string>
</dict>
<key>title</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>title</string>
</dict>
<key>track</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>track</string>
</dict>
<key>year</key>
<dict>
<key>Description</key>
<string>This is the... whatever.</string>
<key>Name</key>
<string>year</string>
</dict>
</dict>
<key>Description</key>
<string>A playlist entry.</string>
<key>Name</key>
<string>playlistentry</string>
<key>PluralName</key>
<string>playlistentries</string>
</dict>
</dict>
<key>Description</key>
<string>Cog's AppleScript interface</string>
<key>Name</key>
<string>Cog</string>
</dict>
</plist>

1709
Cog.xcode/project.pbxproj Normal file

File diff suppressed because it is too large Load Diff

1382
Cog.xcode/xugg.mode1 Normal file

File diff suppressed because it is too large Load Diff

2574
Cog.xcode/xugg.pbxuser Normal file

File diff suppressed because it is too large Load Diff

7
Cog_Prefix.pch Normal file
View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'Cog' target in the 'Cog' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

4
Credits.html Normal file
View File

@ -0,0 +1,4 @@
<html>
<body>
</body>
</html>

24
DBLog.c Normal file
View File

@ -0,0 +1,24 @@
/*
* NSDebug.c
* Cog
*
* Created by Zaphod Beeblebrox on 5/30/05.
* Copyright 2005 __MyCompanyName__. All rights reserved.
*
*/
#include "DBLog.h"
void DBLog(NSString *format, ...)
{
#ifdef DEBUG
va_list ap;
va_start(ap, format);
NSLogv(format, ap);
va_end(ap);
#endif
}

21
DBLog.h Normal file
View File

@ -0,0 +1,21 @@
/*
* NSDebug.h
* Cog
*
* Created by Zaphod Beeblebrox on 5/30/05.
* Copyright 2005 __MyCompanyName__. All rights reserved.
*
*/
#include <Cocoa/Cocoa.h>
#ifdef __cplusplus
extern "C"
{
#endif
void DBLog(NSString *format, ...);
#ifdef __cplusplus
};
#endif

Binary file not shown.

91
English.lproj/MainMenu.nib/classes.nib generated Normal file
View File

@ -0,0 +1,91 @@
{
IBClasses = (
{
ACTIONS = {
addFiles = id;
delEntries = id;
loadPlaylist = id;
savePlaylist = id;
savePlaylistAs = id;
showInfo = id;
};
CLASS = AppController;
LANGUAGE = ObjC;
OUTLETS = {
infoPanel = NSPanel;
mainWindow = NSWindow;
playlistController = PlaylistController;
};
SUPERCLASS = NSObject;
},
{
CLASS = DNDArrayController;
LANGUAGE = ObjC;
OUTLETS = {tableView = NSTableView; };
SUPERCLASS = NSArrayController;
},
{
ACTIONS = {cancel = id; openFeedbackWindow = id; sendFeedback = id; };
CLASS = FeedbackController;
LANGUAGE = ObjC;
OUTLETS = {
feedbackWindow = NSWindow;
fromView = NSTextField;
messageView = NSTextView;
sendingIndicator = NSProgressIndicator;
subjectView = NSTextField;
};
SUPERCLASS = NSObject;
},
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {takeRepeatFromObject = id; takeShuffleFromObject = id; };
CLASS = PlaylistController;
LANGUAGE = ObjC;
SUPERCLASS = DNDArrayController;
},
{CLASS = PlaylistEntry; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
CLASS = PlaylistView;
LANGUAGE = ObjC;
OUTLETS = {playlistController = PlaylistController; soundController = SoundController; };
SUPERCLASS = NSTableView;
},
{
ACTIONS = {
next = id;
pause = id;
pauseResume = id;
prev = id;
resume = id;
seek = id;
stop = id;
};
CLASS = SoundController;
LANGUAGE = ObjC;
OUTLETS = {
bitrateField = NSTextField;
lengthField = NSTextField;
playlistController = PlaylistController;
positionSlider = TrackingSlider;
timeField = NSTextField;
};
SUPERCLASS = NSObject;
},
{CLASS = TrackingSlider; LANGUAGE = ObjC; SUPERCLASS = NSSlider; },
{
ACTIONS = {okay = id; openUpdateWindow = id; takeBoolFromObject = id; };
CLASS = UpdateController;
LANGUAGE = ObjC;
OUTLETS = {
autoCheckButton = NSButton;
checkingIndicator = NSProgressIndicator;
okayButton = NSButton;
statusView = NSTextField;
updateWindow = NSWindow;
};
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

22
English.lproj/MainMenu.nib/info.nib generated Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>298 406 356 240 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>334 667 253 44 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBOpenObjects</key>
<array>
<integer>21</integer>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>8B15</string>
</dict>
</plist>

Binary file not shown.

91
English.lproj/MainMenu~.nib/classes.nib generated Normal file
View File

@ -0,0 +1,91 @@
{
IBClasses = (
{
ACTIONS = {
addFiles = id;
delEntries = id;
loadPlaylist = id;
savePlaylist = id;
savePlaylistAs = id;
showInfo = id;
};
CLASS = AppController;
LANGUAGE = ObjC;
OUTLETS = {
infoPanel = NSPanel;
mainWindow = NSWindow;
playlistController = PlaylistController;
};
SUPERCLASS = NSObject;
},
{
CLASS = DNDArrayController;
LANGUAGE = ObjC;
OUTLETS = {tableView = NSTableView; };
SUPERCLASS = NSArrayController;
},
{
ACTIONS = {cancel = id; openFeedbackWindow = id; sendFeedback = id; };
CLASS = FeedbackController;
LANGUAGE = ObjC;
OUTLETS = {
feedbackWindow = NSWindow;
fromView = NSTextField;
messageView = NSTextView;
sendingIndicator = NSProgressIndicator;
subjectView = NSTextField;
};
SUPERCLASS = NSObject;
},
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
ACTIONS = {takeRepeatFromObject = id; takeShuffleFromObject = id; };
CLASS = PlaylistController;
LANGUAGE = ObjC;
SUPERCLASS = DNDArrayController;
},
{CLASS = PlaylistEntry; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
CLASS = PlaylistView;
LANGUAGE = ObjC;
OUTLETS = {playlistController = PlaylistController; soundController = SoundController; };
SUPERCLASS = NSTableView;
},
{
ACTIONS = {
next = id;
pause = id;
pauseResume = id;
prev = id;
resume = id;
seek = id;
stop = id;
};
CLASS = SoundController;
LANGUAGE = ObjC;
OUTLETS = {
bitrateField = NSTextField;
lengthField = NSTextField;
playlistController = PlaylistController;
positionSlider = TrackingSlider;
timeField = NSTextField;
};
SUPERCLASS = NSObject;
},
{CLASS = TrackingSlider; LANGUAGE = ObjC; SUPERCLASS = NSSlider; },
{
ACTIONS = {okay = id; openUpdateWindow = id; takeBoolFromObject = id; };
CLASS = UpdateController;
LANGUAGE = ObjC;
OUTLETS = {
autoCheckButton = NSButton;
checkingIndicator = NSProgressIndicator;
okayButton = NSButton;
statusView = NSTextField;
updateWindow = NSWindow;
};
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

22
English.lproj/MainMenu~.nib/info.nib generated Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>298 406 356 240 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>334 667 253 44 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>437.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
<integer>21</integer>
</array>
<key>IBSystem Version</key>
<string>8B15</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,26 @@
//
// FeedbackController.h
// Cog
//
// Created by Vincent Spader on 3/26/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "FeedbackSocket.h"
@interface FeedbackController : NSObject {
IBOutlet NSWindow* feedbackWindow;
IBOutlet NSTextField* fromView;
IBOutlet NSTextField* subjectView;
IBOutlet NSTextView* messageView;
IBOutlet NSProgressIndicator *sendingIndicator;
FeedbackSocket *feedbackSocket;
}
- (IBAction)openFeedbackWindow:(id)sender;
- (IBAction)sendFeedback:(id)sender;
- (IBAction)cancel:(id)sender;
@end

View File

@ -0,0 +1,74 @@
//
// FeedbackController.m
// Cog
//
// Created by Vincent Spader on 3/26/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import "FeedbackController.h"
@implementation FeedbackController
- (IBAction)openFeedbackWindow:(id)sender
{
[fromView setStringValue:@""];
[subjectView setStringValue:@""];
[messageView setString:@""];
[feedbackWindow makeFirstResponder:fromView];
[feedbackWindow makeKeyAndOrderFront: sender];
}
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
[feedbackWindow close];
}
- (void)FeedbackErrorOccurred:(NSNotification *)aNotification
{
DBLog(@"Error sending feedback");
[sendingIndicator stopAnimation:self];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:@"Failed"];
[alert setInformativeText:@"Feedback failed to send."];
[alert beginSheetModalForWindow:feedbackWindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
- (void)FeedbackSent:(NSNotification *)aNotification
{
// DBLog(@"Feedback Sent");
[sendingIndicator stopAnimation:self];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:@"Success"];
[alert setInformativeText:@"Feedback successfully sent!"];
[alert beginSheetModalForWindow:feedbackWindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
- (IBAction)sendFeedback:(id)sender
{
// DBLog(@"Sending feedback...");
[sendingIndicator startAnimation:self];
//Using this so that if its a bad connection, it doesnt sit there looking stupid..or should it
feedbackSocket = [[FeedbackSocket alloc] init];
[feedbackSocket setDelegate:self];
[feedbackSocket sendFeedback:[fromView stringValue] subject:[subjectView stringValue] message:[messageView string]];
}
- (IBAction)cancel:(id)sender
{
[feedbackWindow close];
}
@end

27
Feedback/FeedbackSocket.h Normal file
View File

@ -0,0 +1,27 @@
//
// FeedbackSocket.h
// Cog
//
// Created by Vincent Spader on 3/27/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface FeedbackSocket : NSObject {
NSString *from;
NSString *subject;
NSString *message;
id delegate;
}
- (void)setDelegate:(id)d;
- (void)sendFeedback: (NSString *)f subject:(NSString *)s message:(NSString *)m;
- (void)setFrom:(NSString *)f;
- (void)setSubject:(NSString *)s;
- (void)setMessage:(NSString *)m;
@end

131
Feedback/FeedbackSocket.m Normal file
View File

@ -0,0 +1,131 @@
//
// FeedbackSocket.m
// Cog
//
// Created by Vincent Spader on 3/27/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import "FeedbackSocket.h"
// NSNotifications
NSString *FeedbackErrorOccurredNotification = @"FeedbackErrorOccurredNotification";
NSString *FeedbackSentNotification = @"FeedbackSentNotification";
@implementation FeedbackSocket
NSString *encodeForURL(NSString *s)
{
return [(NSString*) CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)s, NULL, NULL, kCFStringEncodingUTF8) autorelease];
}
- (void)sendFeedbackThread:(id)sender
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *f = encodeForURL(from);
NSString *s = encodeForURL(subject);
NSString *m = encodeForURL(message);
NSString *postString = [NSString stringWithFormat:@"from=%@&subject=%@&message=%@", f, s, m];
NSData *postData = [postString dataUsingEncoding:NSASCIIStringEncoding];
NSURL *url = [NSURL URLWithString:@"http://cogosx.sourceforge.net/feedback.php"];
NSMutableURLRequest *post = [NSMutableURLRequest requestWithURL:url];
[post addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[post setHTTPMethod:@"POST"];
[post setHTTPBody:postData];
NSError* error;
NSURLResponse* response;
NSData* resultData = [NSURLConnection sendSynchronousRequest:post returningResponse:&response error:&error];
NSString *resultString = [[[NSString alloc] initWithData:resultData encoding:NSASCIIStringEncoding] autorelease];
if ([resultString caseInsensitiveCompare:@"SUCCESS"] == NSOrderedSame)
{
[self performSelectorOnMainThread:@selector(returnSuccess:) withObject:nil waitUntilDone:NO];
}
else
{
[self performSelectorOnMainThread:@selector(returnFailure:) withObject:nil waitUntilDone:NO];
}
[pool release];
}
- (void)sendFeedback: (NSString *)f subject:(NSString *)s message:(NSString *)m
{
// DBLog(@"Detaching thread for feedback");
if ([f isEqualToString:@""])
{
f = @"Anonymous";
}
[self setFrom:f];
[self setSubject:s];
[self setMessage:m];
[NSThread detachNewThreadSelector:@selector(sendFeedbackThread:) toTarget:self withObject:nil];
}
- (void)returnSuccess:(id)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:FeedbackSentNotification object:self];
}
- (void)returnFailure:(id)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:FeedbackErrorOccurredNotification object:self];
}
-(void)setDelegate:(id)d
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if (delegate != nil) {
// Unregister with the notification center
[nc removeObserver:delegate name:FeedbackErrorOccurredNotification object:self];
[nc removeObserver:delegate name:FeedbackSentNotification object:self];
[delegate autorelease];
}
delegate = [d retain];
// Register the new FeedbackNotification methods for the delegate
// Only register if the delegate implements it, though
if ([delegate respondsToSelector:@selector(FeedbackErrorOccurred:)])
{
[nc addObserver:delegate selector:@selector(FeedbackErrorOccurred:) name:FeedbackErrorOccurredNotification object:self];
}
if ([delegate respondsToSelector:@selector(FeedbackSent:)])
{
[nc addObserver:delegate selector:@selector(FeedbackSent:) name:FeedbackSentNotification object:self];
}
}
- (void)setFrom:(NSString *)f
{
[f retain];
[from release];
from = f;
}
- (void)setSubject:(NSString *)s
{
[s retain];
[subject release];
subject = s;
}
- (void)setMessage:(NSString *)m
{
[m retain];
[message release];
message = m;
}
@end

BIN
Icons/add_blue.png Normal file

Binary file not shown.

BIN
Icons/add_gray.png Normal file

Binary file not shown.

BIN
Icons/bground.png Normal file

Binary file not shown.

BIN
Icons/info_blue.png Normal file

Binary file not shown.

BIN
Icons/info_gray.png Normal file

Binary file not shown.

BIN
Icons/next_blue.png Normal file

Binary file not shown.

BIN
Icons/next_gray.png Normal file

Binary file not shown.

BIN
Icons/pause_blue.png Normal file

Binary file not shown.

BIN
Icons/pause_gray.png Normal file

Binary file not shown.

BIN
Icons/play_blue.png Normal file

Binary file not shown.

BIN
Icons/play_gray.png Normal file

Binary file not shown.

BIN
Icons/prev_blue.png Normal file

Binary file not shown.

BIN
Icons/prev_gray.png Normal file

Binary file not shown.

BIN
Icons/remove_blue.png Normal file

Binary file not shown.

BIN
Icons/remove_gray.png Normal file

Binary file not shown.

BIN
Icons/repeat_blue.png Normal file

Binary file not shown.

BIN
Icons/repeat_gray.png Normal file

Binary file not shown.

BIN
Icons/shuffle_blue.png Normal file

Binary file not shown.

BIN
Icons/shuffle_gray.png Normal file

Binary file not shown.

BIN
Icons/stop_blue.png Normal file

Binary file not shown.

BIN
Icons/stop_gray.png Normal file

Binary file not shown.

BIN
Icons/wheel.icns Normal file

Binary file not shown.

90
Info.plist Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>aif</string>
<string>aiff</string>
<string>aifc</string>
</array>
<key>CFBundleTypeName</key>
<string>AIFF Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>wav</string>
<string>wave</string>
</array>
<key>CFBundleTypeName</key>
<string>Wave Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mp3</string>
</array>
<key>CFBundleTypeName</key>
<string>MP3 Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>flac</string>
</array>
<key>CFBundleTypeName</key>
<string>Flac Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>ape</string>
</array>
<key>CFBundleTypeName</key>
<string>Monkey's Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>mpc</string>
</array>
<key>CFBundleTypeName</key>
<string>Musepack Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>ogg</string>
</array>
<key>CFBundleTypeName</key>
<string>Ogg Vorbis File</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>Cog</string>
<key>CFBundleIconFile</key>
<string>wheel</string>
<key>CFBundleIdentifier</key>
<string>com.badahol.cog</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.01</string>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

BIN
Libraries/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,927 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 39;
objects = {
034768DDFF38A45A11DB9C8B = {
children = (
8D07F2C80486CC7A007CD1D0,
);
isa = PBXGroup;
name = Products;
refType = 4;
sourceTree = "<group>";
};
//030
//031
//032
//033
//034
//080
//081
//082
//083
//084
0867D690FE84028FC02AAC07 = {
buildSettings = {
};
buildStyles = (
4F0BB7EC011F40E904CA0E50,
4F0BB7ED011F40E904CA0E50,
);
hasScannedForEncodings = 1;
isa = PBXProject;
mainGroup = 0867D691FE84028FC02AAC07;
productRefGroup = 034768DDFF38A45A11DB9C8B;
projectDirPath = "";
targets = (
8D07F2BC0486CC7A007CD1D0,
);
};
0867D691FE84028FC02AAC07 = {
children = (
8EB2607A082DBCD0007A908B,
08FB77ACFE841707C02AAC07,
089C1665FE841158C02AAC07,
0867D69AFE84028FC02AAC07,
034768DDFF38A45A11DB9C8B,
);
isa = PBXGroup;
name = DecMPA;
refType = 4;
sourceTree = "<group>";
};
0867D69AFE84028FC02AAC07 = {
children = (
);
isa = PBXGroup;
name = "External Frameworks and Libraries";
refType = 4;
sourceTree = "<group>";
};
089C1665FE841158C02AAC07 = {
children = (
8D07F2C70486CC7A007CD1D0,
089C1666FE841158C02AAC07,
);
isa = PBXGroup;
name = Resources;
refType = 4;
sourceTree = "<group>";
};
089C1666FE841158C02AAC07 = {
children = (
089C1667FE841158C02AAC07,
);
isa = PBXVariantGroup;
name = InfoPlist.strings;
refType = 4;
sourceTree = "<group>";
};
089C1667FE841158C02AAC07 = {
fileEncoding = 10;
isa = PBXFileReference;
lastKnownFileType = text.plist.strings;
name = English;
path = English.lproj/InfoPlist.strings;
refType = 4;
sourceTree = "<group>";
};
08FB77ACFE841707C02AAC07 = {
children = (
8EB26003082DBC69007A908B,
8EB26004082DBC69007A908B,
8EB26005082DBC69007A908B,
8EB26006082DBC69007A908B,
8EB26007082DBC69007A908B,
8EB26008082DBC69007A908B,
8EB26013082DBC69007A908B,
8EB2602C082DBC69007A908B,
8EB2602D082DBC69007A908B,
8EB2602E082DBC69007A908B,
8EB2602F082DBC69007A908B,
8EB26030082DBC69007A908B,
8EB26031082DBC69007A908B,
8EB26032082DBC69007A908B,
8EB26033082DBC69007A908B,
8EB26034082DBC69007A908B,
);
isa = PBXGroup;
name = Source;
refType = 4;
sourceTree = "<group>";
};
//080
//081
//082
//083
//084
//4F0
//4F1
//4F2
//4F3
//4F4
4F0BB7EC011F40E904CA0E50 = {
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
ZERO_LINK = YES;
};
isa = PBXBuildStyle;
name = Development;
};
4F0BB7ED011F40E904CA0E50 = {
buildSettings = {
COPY_PHASE_STRIP = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
ZERO_LINK = NO;
};
isa = PBXBuildStyle;
name = Deployment;
};
//4F0
//4F1
//4F2
//4F3
//4F4
//8D0
//8D1
//8D2
//8D3
//8D4
8D07F2BC0486CC7A007CD1D0 = {
buildPhases = (
8D07F2BD0486CC7A007CD1D0,
8D07F2BF0486CC7A007CD1D0,
8D07F2C10486CC7A007CD1D0,
8D07F2C30486CC7A007CD1D0,
8D07F2C50486CC7A007CD1D0,
);
buildRules = (
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GCC_PREFIX_HEADER = "";
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "@executable_path/../Frameworks";
LIBRARY_STYLE = DYNAMIC;
PRODUCT_NAME = DecMPA;
WRAPPER_EXTENSION = framework;
};
dependencies = (
);
isa = PBXNativeTarget;
name = DecMPA;
productInstallPath = "$(HOME)/Library/Frameworks";
productName = DecMPA;
productReference = 8D07F2C80486CC7A007CD1D0;
productType = "com.apple.product-type.framework";
};
8D07F2BD0486CC7A007CD1D0 = {
buildActionMask = 2147483647;
files = (
8EB26083082DBDFD007A908B,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2BF0486CC7A007CD1D0 = {
buildActionMask = 2147483647;
files = (
8D07F2C00486CC7A007CD1D0,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2C00486CC7A007CD1D0 = {
fileRef = 089C1666FE841158C02AAC07;
isa = PBXBuildFile;
settings = {
};
};
8D07F2C10486CC7A007CD1D0 = {
buildActionMask = 2147483647;
files = (
8EB26039082DBC69007A908B,
8EB2603A082DBC69007A908B,
8EB2603E082DBC69007A908B,
8EB26040082DBC69007A908B,
8EB26042082DBC69007A908B,
8EB26044082DBC69007A908B,
8EB26046082DBC69007A908B,
8EB26048082DBC69007A908B,
8EB2604A082DBC69007A908B,
8EB2604C082DBC69007A908B,
8EB2604E082DBC69007A908B,
8EB26051082DBC69007A908B,
8EB26054082DBC69007A908B,
8EB26056082DBC69007A908B,
8EB26058082DBC69007A908B,
8EB2605C082DBC69007A908B,
8EB2605E082DBC69007A908B,
8EB26062082DBC69007A908B,
8EB26064082DBC69007A908B,
8EB26066082DBC69007A908B,
8EB26068082DBC69007A908B,
8EB2606A082DBC69007A908B,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2C30486CC7A007CD1D0 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2C50486CC7A007CD1D0 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2C70486CC7A007CD1D0 = {
fileEncoding = 4;
isa = PBXFileReference;
lastKnownFileType = text.plist;
path = Info.plist;
refType = 4;
sourceTree = "<group>";
};
8D07F2C80486CC7A007CD1D0 = {
explicitFileType = wrapper.framework;
includeInIndex = 0;
isa = PBXFileReference;
path = DecMPA.framework;
refType = 3;
sourceTree = BUILT_PRODUCTS_DIR;
};
//8D0
//8D1
//8D2
//8D3
//8D4
//8E0
//8E1
//8E2
//8E3
//8E4
8EB26003082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = DecMPA.cpp;
path = Files/src/DecMPA.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26004082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = DecMPAFileAccess.cpp;
path = Files/src/DecMPAFileAccess.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26005082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = DecMPAFileAccess.h;
path = Files/src/DecMPAFileAccess.h;
refType = 4;
sourceTree = "<group>";
};
8EB26006082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = DecodeEngine.h;
path = Files/src/DecodeEngine.h;
refType = 4;
sourceTree = "<group>";
};
8EB26007082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = DefInc.h;
path = Files/src/DefInc.h;
refType = 4;
sourceTree = "<group>";
};
8EB26008082DBC69007A908B = {
children = (
8EB26009082DBC69007A908B,
8EB2600A082DBC69007A908B,
8EB2600B082DBC69007A908B,
8EB2600C082DBC69007A908B,
8EB2600D082DBC69007A908B,
8EB2600E082DBC69007A908B,
8EB2600F082DBC69007A908B,
8EB26010082DBC69007A908B,
8EB26011082DBC69007A908B,
8EB26012082DBC69007A908B,
);
isa = PBXGroup;
name = frame;
path = Files/src/frame;
refType = 4;
sourceTree = "<group>";
};
8EB26009082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = audioFrame.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB2600A082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = audioFrame.h;
refType = 4;
sourceTree = "<group>";
};
8EB2600B082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = floatFrame.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB2600C082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = floatFrame.h;
refType = 4;
sourceTree = "<group>";
};
8EB2600D082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = frame.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB2600E082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = frame.h;
refType = 4;
sourceTree = "<group>";
};
8EB2600F082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = pcmFrame.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26010082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = pcmFrame.h;
refType = 4;
sourceTree = "<group>";
};
8EB26011082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = rawDataBuffer.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26012082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = rawDataBuffer.h;
refType = 4;
sourceTree = "<group>";
};
8EB26013082DBC69007A908B = {
children = (
8EB26014082DBC69007A908B,
8EB26015082DBC69007A908B,
8EB26016082DBC69007A908B,
8EB26017082DBC69007A908B,
8EB26018082DBC69007A908B,
8EB26019082DBC69007A908B,
8EB2601A082DBC69007A908B,
8EB2601B082DBC69007A908B,
8EB2601C082DBC69007A908B,
8EB2601D082DBC69007A908B,
8EB2601E082DBC69007A908B,
8EB2601F082DBC69007A908B,
8EB26020082DBC69007A908B,
8EB26021082DBC69007A908B,
8EB26022082DBC69007A908B,
8EB26023082DBC69007A908B,
8EB26024082DBC69007A908B,
8EB26025082DBC69007A908B,
8EB26026082DBC69007A908B,
8EB26027082DBC69007A908B,
8EB26028082DBC69007A908B,
8EB26029082DBC69007A908B,
8EB2602A082DBC69007A908B,
8EB2602B082DBC69007A908B,
);
isa = PBXGroup;
name = hip;
path = Files/src/hip;
refType = 4;
sourceTree = "<group>";
};
8EB26014082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = common.c;
refType = 4;
sourceTree = "<group>";
};
8EB26015082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = common.h;
refType = 4;
sourceTree = "<group>";
};
8EB26016082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = dct64_i386.c;
refType = 4;
sourceTree = "<group>";
};
8EB26017082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = dct64_i386.h;
refType = 4;
sourceTree = "<group>";
};
8EB26018082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = decode_i386.c;
refType = 4;
sourceTree = "<group>";
};
8EB26019082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = decode_i386.h;
refType = 4;
sourceTree = "<group>";
};
8EB2601A082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = DecodeEngine_Hip.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB2601B082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = HIPDefines.h;
refType = 4;
sourceTree = "<group>";
};
8EB2601C082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = huffman.h;
refType = 4;
sourceTree = "<group>";
};
8EB2601D082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = interface.c;
refType = 4;
sourceTree = "<group>";
};
8EB2601E082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = interface.h;
refType = 4;
sourceTree = "<group>";
};
8EB2601F082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = l2tables.h;
refType = 4;
sourceTree = "<group>";
};
8EB26020082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = layer1.c;
refType = 4;
sourceTree = "<group>";
};
8EB26021082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = layer1.h;
refType = 4;
sourceTree = "<group>";
};
8EB26022082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = layer2.c;
refType = 4;
sourceTree = "<group>";
};
8EB26023082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = layer2.h;
refType = 4;
sourceTree = "<group>";
};
8EB26024082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = layer3.c;
refType = 4;
sourceTree = "<group>";
};
8EB26025082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = layer3.h;
refType = 4;
sourceTree = "<group>";
};
8EB26026082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = mpg123.h;
refType = 4;
sourceTree = "<group>";
};
8EB26027082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = mpglib.h;
refType = 4;
sourceTree = "<group>";
};
8EB26028082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = tabinit.c;
refType = 4;
sourceTree = "<group>";
};
8EB26029082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = tabinit.h;
refType = 4;
sourceTree = "<group>";
};
8EB2602A082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.c;
path = VbrTag.c;
refType = 4;
sourceTree = "<group>";
};
8EB2602B082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = VbrTag.h;
refType = 4;
sourceTree = "<group>";
};
8EB2602C082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = IFileAccess.h;
path = Files/src/IFileAccess.h;
refType = 4;
sourceTree = "<group>";
};
8EB2602D082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = MemBuffer.h;
path = Files/src/MemBuffer.h;
refType = 4;
sourceTree = "<group>";
};
8EB2602E082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = MPADecoder.cpp;
path = Files/src/MPADecoder.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB2602F082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = MPADecoder.h;
path = Files/src/MPADecoder.h;
refType = 4;
sourceTree = "<group>";
};
8EB26030082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = MPAFrameFinder.cpp;
path = Files/src/MPAFrameFinder.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26031082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = MPAFrameFinder.h;
path = Files/src/MPAFrameFinder.h;
refType = 4;
sourceTree = "<group>";
};
8EB26032082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = MPAInfo.cpp;
path = Files/src/MPAInfo.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26033082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = MPAInfo.h;
path = Files/src/MPAInfo.h;
refType = 4;
sourceTree = "<group>";
};
8EB26034082DBC69007A908B = {
children = (
8EB26035082DBC69007A908B,
8EB26036082DBC69007A908B,
8EB26037082DBC69007A908B,
8EB26038082DBC69007A908B,
);
isa = PBXGroup;
name = mpegAudioFrame;
path = Files/src/mpegAudioFrame;
refType = 4;
sourceTree = "<group>";
};
8EB26035082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = dxHead.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26036082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = dxHead.h;
refType = 4;
sourceTree = "<group>";
};
8EB26037082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
path = mpegAudioHeader.cpp;
refType = 4;
sourceTree = "<group>";
};
8EB26038082DBC69007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
path = mpegAudioHeader.h;
refType = 4;
sourceTree = "<group>";
};
8EB26039082DBC69007A908B = {
fileRef = 8EB26003082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2603A082DBC69007A908B = {
fileRef = 8EB26004082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2603E082DBC69007A908B = {
fileRef = 8EB26009082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26040082DBC69007A908B = {
fileRef = 8EB2600B082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26042082DBC69007A908B = {
fileRef = 8EB2600D082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26044082DBC69007A908B = {
fileRef = 8EB2600F082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26046082DBC69007A908B = {
fileRef = 8EB26011082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26048082DBC69007A908B = {
fileRef = 8EB26014082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2604A082DBC69007A908B = {
fileRef = 8EB26016082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2604C082DBC69007A908B = {
fileRef = 8EB26018082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2604E082DBC69007A908B = {
fileRef = 8EB2601A082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26051082DBC69007A908B = {
fileRef = 8EB2601D082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26054082DBC69007A908B = {
fileRef = 8EB26020082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26056082DBC69007A908B = {
fileRef = 8EB26022082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26058082DBC69007A908B = {
fileRef = 8EB26024082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2605C082DBC69007A908B = {
fileRef = 8EB26028082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2605E082DBC69007A908B = {
fileRef = 8EB2602A082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26062082DBC69007A908B = {
fileRef = 8EB2602E082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26064082DBC69007A908B = {
fileRef = 8EB26030082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26066082DBC69007A908B = {
fileRef = 8EB26032082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB26068082DBC69007A908B = {
fileRef = 8EB26035082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2606A082DBC69007A908B = {
fileRef = 8EB26037082DBC69007A908B;
isa = PBXBuildFile;
settings = {
};
};
8EB2607A082DBCD0007A908B = {
children = (
8EB2607C082DBCDF007A908B,
);
isa = PBXGroup;
name = Headers;
refType = 4;
sourceTree = "<group>";
};
8EB2607C082DBCDF007A908B = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = decmpa.h;
path = Files/include/decmpa.h;
refType = 4;
sourceTree = "<group>";
};
8EB26083082DBDFD007A908B = {
fileRef = 8EB2607C082DBCDF007A908B;
isa = PBXBuildFile;
settings = {
ATTRIBUTES = (
Public,
);
};
};
};
rootObject = 0867D690FE84028FC02AAC07;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
// !$*UTF8*$!
{
0867D690FE84028FC02AAC07 = {
activeBuildStyle = 4F0BB7ED011F40E904CA0E50;
activeTarget = 8D07F2BC0486CC7A007CD1D0;
addToTargets = (
8D07F2BC0486CC7A007CD1D0,
);
codeSenseManager = 8EB25FF9082DBBEE007A908B;
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
300,
133.2085,
);
PBXFileTableDataSourceColumnsKey = (
PBXErrorsWarningsDataSource_TypeID,
PBXErrorsWarningsDataSource_MessageID,
PBXErrorsWarningsDataSource_LocationID,
);
};
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
243,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
200,
63,
20,
48,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 138940180;
PBXWorkspaceStateSaveDate = 138940180;
};
perUserProjectItems = {
8E5E0CE1082E6B2000A1FEF4 = 8E5E0CE1082E6B2000A1FEF4;
8E6F2A7E08480F330011F126 = 8E6F2A7E08480F330011F126;
};
sourceControlManager = 8EB25FF8082DBBEE007A908B;
userBuildSettings = {
};
};
8D07F2BC0486CC7A007CD1D0 = {
activeExec = 0;
};
8E5E0CE1082E6B2000A1FEF4 = {
fRef = 8EB2607C082DBCDF007A908B;
isa = PBXTextBookmark;
name = "decmpa.h: 7";
rLen = 0;
rLoc = 333;
rType = 0;
vrLen = 0;
vrLoc = 0;
};
8E6F2A7E08480F330011F126 = {
fRef = 8EB2607C082DBCDF007A908B;
isa = PBXTextBookmark;
name = "decmpa.h: 7";
rLen = 0;
rLoc = 333;
rType = 0;
vrLen = 0;
vrLoc = 0;
};
8EB25FF8082DBBEE007A908B = {
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
isa = PBXSourceControlManager;
scmConfiguration = {
};
scmType = "";
};
8EB25FF9082DBBEE007A908B = {
indexTemplatePath = "";
isa = PBXCodeSenseManager;
};
8EB2607C082DBCDF007A908B = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {818, 7798}}";
sepNavSelRange = "{333, 0}";
sepNavVisRect = "{{0, 0}, {0, 0}}";
};
};
}

Binary file not shown.

View File

@ -0,0 +1,125 @@
0.4.1
- improved detection of invalid frames and, therefore, of non-MPEG Audio files
- worked through HIP code:
- removed printfs and exits
- activated layer 1 and 2 support
- changed some interface things to work better with DecMPA
0.4.0
- reorganized API in a way that should allow it to remain downward
compatible in future releases
- the decoder parameters are no longer passed directly to DecMPA_Create
but are now set using a new function, DecMPA_SetParam.
- added API version checking to ensure that the DLL is compatible
- added a new function DecMPA_DecodeNoData to the API. It can be used
to perform a quick scan through a file without actually decoding
any audio data
- added an ease-of-use function (DecMPA_CreateForFile) for creating a
decoder object that reads its input data from a file
- ID3v2 data can now be returned
- more code clean-up
- revamped seek code - seeks are now performed instantly when the
Seek function is called, instead of at the next decode
- more accurate calculation of seek position for VBR streams
- better calculation of decode-time
- improved duration estimation
- corrected some issues on big endian systems
- fixed a few other bugs
0.3.0
- integrated new decoding routines (from Lame/HIP) in addition to the "old"
SPlay decoding
- added a mechanism to choose between HIP and SPlay decoding routines at
compile time
- wrote a new frame finder that adds quite a bit of robustness and also
allows DecMPA to detect if the data is not mpeg audio. The new finder
also greatly reduces the risk to detect frames wrong after seeking.
- threw out more old unnecessary Mpeglib stuff and rewrote/simplified some
other parts.
0.2.2
- disabled "downsampling" again - it only reduced the frequency by half instead
of synthesizing with twice the frequency and THEN reducing it by half.
Thus the quality was definitely NOT improved.
0.2.1
- added workaround for Visual C++ compiler bug that caused occasional
artifacts when decoding some MP3s
0.2
- MP3 synthesis is now performed with downsampling, resulting in improved
quality
- leading ID3v2 tags are now automatically skipped over, fixing some
problems with corrupted tags that contain unescaped "sync" values.
This also improves length detection for files with big ID3 tags.
- removed some more old MPEGLib code that is unnecessary for pure audio
decoding
0.1.8
- added an example application "decodefile"
- added makefile and project file for new example to the "build" directory
- cleaned the code up a bit, removed some unnecessary includes
- the source files in the tar.gz archive now have UNIX-style linebreaks.
this fixes some issues with compilers that weren't able to cope with the
Windows-style linebreaks
- changed some code in the build-tools for potability.
- added makefiles for Digital Unix and Cygwin GCC
0.1.5
- added ability to create documentation with makefiles
- added readme files about makefile usage
- changed the interface of DecMPA_Create - it now accepts a POINTER to
DecMPA_Callbacks rather than an object.
- fixed some portability issues
- fixed a nasty bug in decmpa.h: DecMPA_Create did not have the DECMPA_CC
calling convention (resulting in possible loss of binary interoperability
with dlls created by different compilers)
- fixed gcc commandline when creating a DLL - the DLL is now relocatable
and binary compatible with the VC6 generated DLL
0.1
- initial release

View File

@ -0,0 +1,459 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -0,0 +1,131 @@
*** DecMPA v0.4.1 - Simple MPEG Audio Decoder ***
DecMPA is a small library for decoding MPEG Audio (layer 1,2 and 3). You may
use it under the terms of the GNU Lesser General Public License
(see License.txt).
DecMPA uses some parts of project MPEGLib v0.4.1 by Martin Vogt
(see http://mpeglib.sourceforge.net/) which itself uses modified SPlay
decoding routines (see http://splay.sourceforge.net).
DecMPA v0.3.0 and higher also uses code from Lame's HIP decoding
engine (see http://lame.sourceforge.net/).
Essentially DecMPA is a mixture of "raw" decoding routines from other projects
(with a few bug fixes and extensions), with a new interface coded on top of
it. The goal is to provide a powerful MPEG Audio decoding library that can
be easily integrated into applications.
The project homepage can be found at
http://decmpa.sourceforge.net
************************************************************
** IMPORTANT NOTE for users of versions older than v0.4.0 **
************************************************************
In version 0.4.0 the API has changed a little, in particular the parameters
you pass to the DecMPA_CreateXXX functions. The output type is not passed
directly to Create anymore, but can now be set using DecMPA_SetParam.
Also note that the structure DecMPA_Callbacks now contains an additional
pointer to a "GetPosition" function that HAS to be provided. Be sure to
initialize it!
Please read the documentation for additional information.
These changes allow a greater flexibility when adding new features and will
hopefully enable future releases to be fully downward compatible to earlier
versions.
** Documentation
Documentation is available in the subdirectory 'doc'.
** Compiling
If you want to compile DecMPA yourself, project files and make files for
some target systems and compilers are located in build/SYSTEM, where
SYSTEM is:
vc6: Windows, Visual C++ 6.0
gcc-mingw32: Windows, GCC Mingw32
gcc-cygwin: Windows, GCC Cygwin
gcc-linux: Linux, GCC
gcc-digux: Digital Unix, GCC
For gcc systems, just open a shell/command prompt, got to the appropriate
build/SYSTEM directory and run "make" (or possibly "gmake" if the default
make for your system is not GNU make).
DecMPA can use two different decoding engines: HIP and SPlay. HIP is the
default, but if you want to use SPlay instead you can pass "ENGINE=splay"
as a parameter to you call to make.
More information about the make files can be found in build/MakeGoals.txt
Generated libraries, shared objects and import libraries are placed in
lib/SYSTEM.
Generated DLLs and example executables are placed in bin/SYSTEM.
** Usage
Include include/decmpa.h in your code files and link with the
appropriate library or import library for your target system from lib/SYSTEM.
All library files except those for Windows/Visual C++ have to be compiled
first (see Compiling).
Note that the LGPL might require you to use the dll/shared object instead
of the static library if your application is not released under the GPL
(see License.txt).
** Examples
Example applications are located in the "examples" subdirectory.
The makefiles and project files for the examples are found exactly where
the library make files are (see "Compiling").
For GNU make files, the example make files are integrated into the
normal make files. They can be executed by calling GNU Make with the goal
"example_NAME" where NAME is the directory name of the example. For example
"make example_decodefile" builds the decodefile example application.
More information about the make files can be found in build/MakeGoals.txt
** Portability
DecMPA has been compiled under a few systems, including Windows and Linux
(see "Compiling"). It will probably compile well on other UNIXes with the
Linux or Digital Unix makefiles, but that has not been tested yet.
If you successfully compiled DecMPA on other systems, I would appreciate if
you could drop me a note (and maybe contribute your makefiles or project files
- see below).
** Suggestions, fixes, extensions, feedback
If you have any suggestions, small extension or bug fixes that you would like to
be incorporated into this library, send them to hazard_hd@users.sourceforge.net
If you send me any of your code, you must agree that it will be released under
LGPL.
If you want to continuously help with the development, please send a short resume
describing your qualifications and experience to hazard_hd@users.sourceforge.net.
If I think you will "fit in" I'll add you to the developer list, thus allowing
you direct access to the project CVS.
I would also like to hear from you if you find this library useful and decide
to use it in one of your projects.
Copyright 2002 Hauke Duden
hazard_hd@users.sourceforge.net

View File

@ -0,0 +1,3 @@
- Test on other operating systems
- clean the code up a little more

View File

@ -0,0 +1,556 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _DECMPA_H_
#define _DECMPA_H_
/**\file
Specifies the DecMPA API.*/
#ifndef DECMPA_VERSION
/**DecMPA API version number.*/
#define DECMPA_VERSION 1
#endif
#if defined(_WINDOWS) || defined(_WIN32)
#ifndef CALLBACK
#include <windows.h>
#endif
#define DECMPA_CC CALLBACK
#else
#define DECMPA_CC
#endif
/**\def DECMPA_CC
Macro for the calling convention used by DecMPA functions.*/
/**\defgroup GroupFunctions Functions*/
/**\defgroup GroupResults Result Codes
Description of the result codes that are returned by most DecMPA functions.
Codes of the form DECMPA_ERROR_*** represent errors and are all negative.
The other result codes, all >=0, indicate different degrees of success.*/
/**\defgroup GroupParamIDs Configuations Parameters
Description of the possible parameters that can be defined using
#DecMPA_SetParam.
*/
/**\defgroup GroupParamValues Configuration Parameter Values
Description of the value constants that can be assigned to some configuration
parameters.*/
/**\defgroup GroupStructs Structures*/
/**\addtogroup GroupStructs*/
/*@{*/
/**This structure contains pointers to the functions that are used
to read the MP3 data during DecMPA_Decode.*/
typedef struct
{
/**Pointer to the function that is used to read data. If this pointer
is NULL, DecMPA will read from stdin and ignore the other callback
functions.
@param pContext context pointer that was passed to
#DecMPA_CreateUsingCallbacks
@param pBuffer buffer that the data should be stored into
@param nBytes number of bytes to read
@return the number of bytes read or -1 if an error occurred. If
the returned value is less than nBytes it is assumed that the end
of the data stream was reached.
\note the function that the pointer points to should have the calling
convention DECMPA_CC, i.e. it should be defined as:
\code
long DECMPA_CC MyReadFuncName(void* pContext,void* pBuffer,long nBytes);
\endcode*/
long (DECMPA_CC* Read)(void* pContext,void* pBuffer,long nBytes);
/**Pointer to function that seeks to the specified data stream position.
This function pointer should be set to NULL if seeking is not supported.
@param pContext context pointer that was passed to
#DecMPA_CreateUsingCallbacks
@param DestPos destination position, in bytes.
@return nonzero if successful, 0 otherwise.
\note the function that the pointer points to should have the calling
convention DECMPA_CC, i.e. it should be defined as:
\code
int DECMPA_CC MySeekFuncName(void* pContext,long DestPos);
\endcode*/
int (DECMPA_CC* Seek)(void* pContext,long DestPos);
/**Pointer to a function that returns the length of the data stream.
This function pointer can be set to NULL if the length cannot be
determined. Alternatively the function can return -1,
@param pContext context pointer that was passed to
#DecMPA_CreateUsingCallbacks
@return the length, in bytes. -1 if unknown.
\note the function that the pointer points to should have the calling
convention DECMPA_CC, i.e. it should be defined as:
\code
long DECMPA_CC MyGetLengthFuncName(void* pContext);
\endcode*/
long (DECMPA_CC* GetLength)(void* pContext);
/**Pointer to a function that returns the current position in the data
stream. This function pointer can only be NULL if Read is also NULL.
@param pContext context pointer that was passed to
#DecMPA_CreateUsingCallbacks
@return the current position, in bytes or -1 if an error occurred.
\note the function that the pointer points to should have the calling
convention DECMPA_CC, i.e. it should be defined as:
\code
long DECMPA_CC MyGetPositionFuncName(void* pContext);
\endcode*/
long (DECMPA_CC* GetPosition)(void* pContext);
} DecMPA_Callbacks;
/**This structure provides information extracted from an MPEG Audio header.*/
typedef struct
{
/**The original header data.*/
unsigned char aRawData[4];
/**Protection*/
int bProtection;
/**Layer*/
int nLayer;
/**Version*/
int nVersion;
/**Padding*/
int bPadding;
/**Frequency index*/
int nFrequencyIndex;
/**Frequency in Hz*/
int nFrequency;
/**Bitrate index*/
int nBitRateIndex;
/**Extended mode*/
int nExtendedMode;
/**Mode*/
int nMode;
/**Input stereo*/
int bInputStereo;
/**MPEG 2.5*/
int bMPEG25;
/**Frame size in bytes*/
int nFrameSize;
/**Number of decoded samples per frame. If the data is stereo, a sample
consists of one value for the left channel and one for the right.*/
int nDecodedSamplesPerFrame;
/**Bitrate in Kbps.*/
int nBitRateKbps;
} DecMPA_MPEGHeader;
/**DecMPA_OutputFormat objects are used to specify the format of the decoded
audio data that is returned by DecMPA_Decode.*/
typedef struct
{
/**Specifies the type of the data. Can be either DECMPA_OUTPUT_INT16 or
DECMPA_OUTPUT_FLOAT*/
int nType;
/**Specifies the frequency of the data.*/
int nFrequency;
/**Specifies the number of channels. Can be 1 for mono or 2 for stereo.*/
int nChannels;
} DecMPA_OutputFormat;
/*@}*/
/**\addtogroup GroupResults*/
/*@{*/
/**The operation has been successfully completed.*/
#define DECMPA_OK 0
/**The end of the stream was reached and there is no more data to decode.*/
#define DECMPA_END 1
/**An invalid parameter was passed to a function.*/
#define DECMPA_ERROR_PARAM (-1)
/**The operation is not supported.*/
#define DECMPA_ERROR_UNSUPPORTED (-2)
/**There is not enough free memory.*/
#define DECMPA_ERROR_MEMORY (-3)
/**An internal error occurred in the decoding routines.*/
#define DECMPA_ERROR_INTERNAL (-4)
/**Indicates an error during decoding, which usually means that the input data
is invalid or corrupted.*/
#define DECMPA_ERROR_DECODE (-5)
/**An error occurred during the reading of new data.*/
#define DECMPA_ERROR_READ (-6)
/**An error occurred when it was tried to seek to a different position in
the data stream.*/
#define DECMPA_ERROR_SEEK (-7)
/**An error occurred when opening a file.*/
#define DECMPA_ERROR_OPENFILE (-8)
/**The decoder is in the wrong state to perform the specified
function.*/
#define DECMPA_ERROR_WRONGSTATE (-9)
/**The requested resource is not available*/
#define DECMPA_ERROR_NOTAVAILABLE (-10)
/**The version of the DecMPA library that is used is incompatible:*/
#define DECMPA_ERROR_INCOMPATIBLEVERSION (-11)
/*@}*/
/**\addtogroup GroupParamIDs*/
/*@{*/
/**Specifies the format DecMPA will use to output the decoded audio samples.
Can be either #DECMPA_OUTPUT_INT16 or #DECMPA_OUTPUT_FLOAT.
Default value: #DECMPA_OUTPUT_INT16.*/
#define DECMPA_PARAM_OUTPUT 0
/**Specifies wether the decoder should load a leading ID3v2 tag and
make it available through #DecMPA_GetID3v2Data. Can be either
#DECMPA_YES or #DECMPA_NO.
Default value: #DECMPA_NO.*/
#define DECMPA_PARAM_PROVIDEID3V2 1
/*@}*/
/**Constant indicating the number of definable parameters.*/
#define DECMPA_PARAMCOUNT 2
/**\addtogroup GroupParamValues*/
/*@{*/
/**\defgroup GroupParamGeneric Generic values*/
/*@{*/
/**Indicates that the specified function is activated.*/
#define DECMPA_YES 1
/**Indicates that the specified function is not activated.*/
#define DECMPA_NO 0
/*@}*/
/**\defgroup GroupParamOutput DECMPA_PARAM_OUTPUT values*/
/*@{*/
/**Indicates that the audio samples are signed 16 bit integers (one per
channel). -32768 is the minimum and 32767 is the maximum value.
\note As of version 0.3.0 DecMPA uses integers internally. That means that
#DECMPA_OUTPUT_INT16 is a little faster than #DECMPA_OUTPUT_FLOAT because the
latter requires an additional conversion.*/
#define DECMPA_OUTPUT_INT16 0
/**Indicates that the audio samples are floats (one per channel).
-1.0 is the minimum and 1.0 is the maximum value.
\note As of version 0.3.0 DecMPA uses integers internally. That means that
#DECMPA_OUTPUT_INT16 is a little faster than #DECMPA_OUTPUT_FLOAT because the
latter requires an additional conversion.*/
#define DECMPA_OUTPUT_FLOAT 1
/*@}*/
/*@}*/
/**\addtogroup GroupFunctions*/
/*@{*/
/**Creates a new decoder that obtains its input data from a file.
If you want to provide the input data in some other customized way, use
#DecMPA_CreateUsingCallbacks instead.
After the decoder is created, additional parameters can be configured with
#DecMPA_SetParam.
@param ppDecoder pointer to a void* variable that receives the address of the
decoder object.
@param sFilePath path of the file to open
@param APIVersion version number of the DecMPA API. You should always
pass the constant #DECMPA_VERSION for this parameter.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_CreateUsingFile(void** ppDecoder,const char* sFilePath,int APIVersion);
/**Creates a new decoder that obtains its input data using callback functions.
After the decoder is created, additional parameters can be configured with
#DecMPA_SetParam.
@param ppDecoder pointer to a void* variable that receives the address of the
decoder object.
@param pCallbacks structure containing pointers to the callback functions that
are used to retrieve the MPEG Audio data.
@param pCallbackContext a pointer that is simply passed to the callback
functions. It has no meaning to the decoder and is only meant to be used
to pass arbitrary data to the callback functions.
@param APIVersion version number of the DecMPA API. You should always
pass the constant #DECMPA_VERSION for this parameter.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_CreateUsingCallbacks(void** ppDecoder,const DecMPA_Callbacks* pCallbacks,void* pCallbackContext,int APIVersion);
/**Sets additional DecMPA parameters.
Calling this function is completely optional - if you don't call it
or only call it for some parameters, the remaining parameters will simply keep
their default values.
This function should only be called directly after the decoder was created,
before calling any of the other functions. Otherwise DecMPA_SetParam may return
#DECMPA_ERROR_WRONGSTATE.
@param pDecoder the decoder object
@param ID ID of the parameter to set. See \ref GroupParamIDs.
@param Value the new value for the specified parameter. Which values are possible
depends of the parameter.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_SetParam(void* pDecoder,int ID,long Value);
/**Returns the current value of a DecMPA parameter.
@param pDecoder the decoder object
@param ID ID of the parameter. See \ref GroupParamIDs.
@return the current value of the specified parameter.
@see #DecMPA_SetParam
*/
long DECMPA_CC DecMPA_GetParam(void* pDecoder,int ID);
/**Decodes some data and stores it in the supplied buffer. The buffer is not
necessarily completely filled. Always check the value stored in pBytesDecoded
to find out how much data has been decoded.
The format of the data (frequency and number of channels) can be obtained by
calling #DecMPA_GetOutputFormat <b>after</b> DecMPA_Decode. The format may
change from one call of DecMPA_Decode to the next. Wether the format has
changed can be checked using #DecMPA_OutputFormatChanged.
@param pDecoder the decoder object
@param pBuffer pointer to a buffer that receives the decoded data.
@param nBufferBytes size of the buffer, in bytes
@param pBytesDecoded pointer to a variable that receives the number of bytes
that were stored in the buffer.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_Decode(void* pDecoder,void* pBuffer,long nBufferBytes,long* pBytesDecoded);
/**This is a special version of #DecMPA_Decode that does not actually decode
any MPEG Audio data, but only decodes the header information.
This function is a lot faster than #DecMPA_Decode and can be used
to make a quick run through the file and obtain accurate information about
its properties, like the exact duration or decoded file size.
The function behaves in all ways like #DecMPA_Decode, except that it does not
return any data. In particular, the output format and mpeg audio header
information returned by #DecMPA_GetOutputFormat and #DecMPA_GetMPEGHeader will
be properly updated, just as #DecMPA_Decode does.
@param pDecoder the decoder object
@param pDecodedBytes pointer to a variable that receives the decoded size
(in bytes) of the current MPEG audio frame. If #DecMPA_Decode was called
before and some parts of the current frame have already been read, the
size of the remaining data is returned
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_DecodeNoData(void* pDecoder,long* pDecodedBytes);
/**Changes the decoding position to the specified time, relative to the
beginning of the data stream.
If #DecMPA_CreateUsingCallbacks was used to create the decoder and no
Seek callback function has been specified, seeking is not supported and
#DECMPA_ERROR_UNSUPPORTED is returned.
@param pDecoder the decoder object
@param Millis the target time, in milliseconds
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_SeekToTime(void* pDecoder,long Millis);
/**Retrieves the current decoding time. The decoding time corresponds to
the time that it takes to play the data that has been decoded up to now.
@param pDecoder the decoder object
@param pTime pointer to a variable that receives the time, in milliseconds.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_GetTime(void* pDecoder,long* pTime);
/**Retrieves the time that it takes to play back the whole data stream.
If the duration is not known -1 is returned.
\note The duration is an estimation that can be slightly wrong for some files
but is pretty accurate for the wide majority of files. If you need a
100% accurate duration value, there is really no other way than to read through
the whole file with #DecMPA_Decode or #DecMPA_DecodeNoData and add up the
\c DecodedBytes values that are returned by those functions. Note that
if you only make this pass through the file to get the duration, i.e. you do
not need decoded audio data, you can use #DecMPA_DecodeNoData which is a lot
faster than #DecMPA_Decode.
@param pDecoder the decoder object
@param pDuration pointer to a variable that receives the duration, in
milliseconds.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_GetDuration(void* pDecoder,long* pDuration);
/**Retrieves the format of the data that was returned by the last call to
DecMPA_Decode.
The nType member of DecMPA_OutputFormat never changes and its value is
defined by the #DECMPA_PARAM_OUTPUT parameter that can be set using
#DecMPA_SetParam. If the value has not been explicitly changed using
#DecMPA_SetParam it will be #DECMPA_OUTPUT_INT16, indicating 16 bit signed
samples.
The remaining fields of the structure may change after calls to
#DecMPA_Decode or #DecMPA_DecodeNoData.
@param pDecoder the decoder object
@param pFormat pointer to a DecMPA_OutputFormat object that is filled with
the format data
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_GetOutputFormat(void* pDecoder,DecMPA_OutputFormat* pFormat);
/**Checks wether the output format has changed during the last call to
DecMPA_Decode.
@return nonzero if the format has changed, zero otherwise.*/
int DECMPA_CC DecMPA_OutputFormatChanged(void* pDecoder);
/**Retrieve mpeg header of the data that was returned by the last call to
DecMPA_Decode. This function is only supplied for information purposes.
@param pDecoder the decoder object
@param pHeader pointer to a DecMPA_MPEGHeader object that received the data.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_GetMPEGHeader(void* pDecoder,DecMPA_MPEGHeader* pHeader);
/**Returns the file's ID3v2 tag, if it has one. If the file has no ID3v2
tag, #DECMPA_ERROR_NOTAVAILABLE is returned.
This function will always return #DECMPA_ERROR_NOTAVAILABLE if the decoder parameter
#DECMPA_PARAM_PROVIDEID3V2 has not been set to #DECMPA_YES with #DecMPA_SetParam.
\note There are other libraries that can be used to parse the returned
data, one of them being id3lib. It can be found at
http://id3lib.sourceforge.net/ .
@param pDecoder the decoder object
@param ppData pointer to a pointer variable that will receive the address
of the ID3v2 data. The memory that contains the data will remain valid
until the decoder is destroyed.
@param pDataSize pointer to a variable that will receive the size of the
ID3v2 data, in bytes.
@return a DecMPA result code (see \ref GroupResults).*/
int DECMPA_CC DecMPA_GetID3v2Data(void* pDecoder,unsigned char** ppData,long* pDataSize);
/**Destroys a decoder.
@param pDecoder decoder object.*/
void DECMPA_CC DecMPA_Destroy(void* pDecoder);
/**Returns the version number of the DecMPA API used by the library.*/
int DECMPA_CC DecMPA_GetVersion(void);
/*@}*/
#endif

View File

@ -0,0 +1,262 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include "DefInc.h"
#include "../include/decmpa.h"
#include "MPADecoder.h"
#include <exception>
#include <stdio.h>
#if defined(__GNUC__) && (defined(_WINDOWS) || defined(_WIN32))
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
long DECMPA_CC DecMPA_StdioRead(void* pContext,void* pBuffer,long nBytes)
{
long nBytesRead;
nBytesRead=fread(pBuffer,1,nBytes,(FILE*)pContext);
if(nBytesRead!=nBytes)
{
if(ferror((FILE*)pContext))
return -1;
}
return nBytesRead;
}
int DECMPA_CC DecMPA_StdioSeek(void* pContext,long DestPos)
{
if(fseek((FILE*)pContext,DestPos,SEEK_SET)!=0)
return 0; //error
else
return 1; //no error
}
long DECMPA_CC DecMPA_StdioGetLength(void* pContext)
{
long nOldPos;
long nLength=-1;
nOldPos=ftell((FILE*)pContext);
if(fseek((FILE*)pContext,0,SEEK_END)==0)
{
nLength=ftell((FILE*)pContext);
fseek((FILE*)pContext,nOldPos,SEEK_SET);
}
return nLength;
}
long DECMPA_CC DecMPA_StdioGetPosition(void* pContext)
{
return ftell((FILE*)pContext);
}
void DecMPA_StdioDestroyNotify(void* pContext)
{
fclose((FILE*)pContext);
}
DLLEXPORT int DECMPA_CC DecMPA_CreateUsingFile(void** ppDecoder,const char* sFilePath,int Version)
{
FILE* pFile;
DecMPA_Callbacks Callbacks;
int nResult;
if(Version>DECMPA_VERSION)
return DECMPA_ERROR_INCOMPATIBLEVERSION;
pFile=fopen(sFilePath,"rb");
if(pFile==NULL)
return DECMPA_ERROR_OPENFILE;
Callbacks.Read=DecMPA_StdioRead;
Callbacks.Seek=DecMPA_StdioSeek;
Callbacks.GetLength=DecMPA_StdioGetLength;
Callbacks.GetPosition=DecMPA_StdioGetPosition;
nResult=DecMPA_CreateUsingCallbacks(ppDecoder,&Callbacks,pFile,Version);
if(nResult!=DECMPA_OK)
fclose(pFile);
((CMPADecoder*)(*ppDecoder))->SetDestroyNotify(DecMPA_StdioDestroyNotify,pFile);
return nResult;
}
DLLEXPORT int DECMPA_CC DecMPA_CreateUsingCallbacks(void** ppDecoder,const DecMPA_Callbacks* pCallbacks,void* pContext,int Version)
{
DecMPA_Callbacks Callbacks=*pCallbacks;
if(Callbacks.Read==NULL)
{
Callbacks.Read=DecMPA_StdioRead;
Callbacks.Seek=NULL;
Callbacks.GetLength=NULL;
Callbacks.GetPosition=DecMPA_StdioGetPosition;
pContext=stdin;
}
if(Version>DECMPA_VERSION)
return DECMPA_ERROR_INCOMPATIBLEVERSION;
if(ppDecoder==NULL || Callbacks.GetPosition==NULL)
return DECMPA_ERROR_PARAM;
try
{
*ppDecoder=new CMPADecoder(Callbacks,pContext);
return DECMPA_OK;
}
catch(std::bad_alloc e)
{
return DECMPA_ERROR_MEMORY;
}
catch(std::exception e)
{
return DECMPA_ERROR_INTERNAL;
}
}
DLLEXPORT int DECMPA_CC DecMPA_SetParam(void* pDecoder,int ID,long Value)
{
if(pDecoder==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->SetParam(ID,Value);
}
DLLEXPORT long DECMPA_CC DecMPA_GetParam(void* pDecoder,int ID)
{
if(pDecoder==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->GetParam(ID);
}
DLLEXPORT int DECMPA_CC DecMPA_Decode(void* pDecoder,void* pBuffer,long nBufferBytes,long* pBytesDecoded)
{
if(pDecoder==NULL || pBytesDecoded==NULL || (pBuffer==NULL && nBufferBytes!=0))
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->Decode(pBuffer,nBufferBytes,*pBytesDecoded);
}
DLLEXPORT int DECMPA_CC DecMPA_DecodeNoData(void* pDecoder,long* pDecodedBytes)
{
if(pDecoder==NULL || pDecodedBytes==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->DecodeNoData(*pDecodedBytes);
}
DLLEXPORT int DECMPA_CC DecMPA_SeekToTime(void* pDecoder,long Millis)
{
if(pDecoder==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->SeekToTime(Millis);
}
DLLEXPORT int DECMPA_CC DecMPA_GetTime(void* pDecoder,long* pTime)
{
if(pDecoder==NULL || pTime==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->GetTime(*pTime);
}
DLLEXPORT int DECMPA_CC DecMPA_GetDuration(void* pDecoder,long* pDuration)
{
if(pDecoder==NULL || pDuration==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->GetDuration(*pDuration);
}
DLLEXPORT int DECMPA_CC DecMPA_GetOutputFormat(void* pDecoder,DecMPA_OutputFormat* pFormat)
{
if(pDecoder==NULL || pFormat==NULL)
return DECMPA_ERROR_PARAM;
((CMPADecoder*)pDecoder)->GetOutputFormat(*pFormat);
return DECMPA_OK;
}
DLLEXPORT int DECMPA_CC DecMPA_OutputFormatChanged(void* pDecoder)
{
if(pDecoder==NULL)
return 0;
return ((CMPADecoder*)pDecoder)->OutputFormatChanged() ? 1 : 0;
}
DLLEXPORT int DECMPA_CC DecMPA_GetMPEGHeader(void* pDecoder,DecMPA_MPEGHeader* pHeader)
{
if(pDecoder==NULL || pHeader==NULL)
return DECMPA_ERROR_PARAM;
((CMPADecoder*)pDecoder)->GetMPEGHeader(*pHeader);
return DECMPA_OK;
}
DLLEXPORT int DECMPA_CC DecMPA_GetID3v2Data(void* pDecoder,unsigned char** ppData,long* pDataSize)
{
if(pDecoder==NULL || ppData==NULL || pDataSize==NULL)
return DECMPA_ERROR_PARAM;
return ((CMPADecoder*)pDecoder)->GetID3v2Data(*ppData,*pDataSize);
}
DLLEXPORT void DECMPA_CC DecMPA_Destroy(void* pDecoder)
{
if(pDecoder!=NULL)
{
try
{
delete (CMPADecoder*)pDecoder;
}
catch(std::exception)
{
}
}
}
DLLEXPORT int DECMPA_CC DecMPA_GetVersion(void)
{
return DECMPA_VERSION;
}

View File

@ -0,0 +1,326 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include "DefInc.h"
#include "DecMPAFileAccess.h"
#include <memory.h>
CDecMPAFileAccess::CDecMPAFileAccess(const DecMPA_Callbacks& Callbacks,void* pContext)
{
m_Callbacks=Callbacks;
m_pCallbackContext=pContext;
m_nPosition=Callbacks.GetPosition(pContext);
if(m_nPosition<0)
m_nPosition=0;
m_bEOF=false;
m_pUndoBuffer=NULL;
m_nUndoBufferSize=0;
m_nUndoBufferFilled=0;
m_nUndoBufferPos=0;
m_nUndoRecordingCount=0;
m_LastError=DECMPA_OK;
m_pSkipBuffer=NULL;
m_nSkipBufferSize=0;
}
CDecMPAFileAccess::~CDecMPAFileAccess()
{
if(m_pUndoBuffer!=NULL)
delete[] m_pUndoBuffer;
if(m_pSkipBuffer!=NULL)
delete[] m_pSkipBuffer;
}
int CDecMPAFileAccess::Read(void* pDest,int nBytes)
{
long nResult=0;
long nRedoBytes=0;
nRedoBytes=m_nUndoBufferFilled-m_nUndoBufferPos;
if(nRedoBytes>0)
{
if(nRedoBytes>nBytes)
nRedoBytes=nBytes;
memcpy(pDest,m_pUndoBuffer+m_nUndoBufferPos,nRedoBytes);
m_nUndoBufferPos+=nRedoBytes;
nBytes-=nRedoBytes;
pDest=((char*)pDest)+nRedoBytes;
m_nPosition+=nRedoBytes;
if(m_nUndoBufferPos==m_nUndoBufferFilled && m_nUndoRecordingCount==0)
{
m_nUndoBufferFilled=0;
m_nUndoBufferPos=0;
}
nResult+=nRedoBytes;
}
if(nBytes>0)
{
long nRead;
nRead=m_Callbacks.Read(m_pCallbackContext,pDest,nBytes);
if(nRead>=0)
{
if(nRead!=nBytes)
m_bEOF=true;
m_nPosition+=nRead;
if(m_nUndoRecordingCount>0)
{
EnsureUndoBufferFree(nRead);
memcpy(m_pUndoBuffer+m_nUndoBufferPos,pDest,nRead);
m_nUndoBufferFilled+=nRead;
m_nUndoBufferPos+=nRead;
}
nResult+=nRead;
}
else
{
m_LastError=DECMPA_ERROR_READ;
nResult=-1;
}
}
return nResult;
}
long CDecMPAFileAccess::Skip(long nBytes)
{
long nResult=0;
long nRedoBytes=0;
bool bSeekFailed=false;
nRedoBytes=m_nUndoBufferFilled-m_nUndoBufferPos;
if(nRedoBytes>0)
{
if(nRedoBytes>nBytes)
nRedoBytes=nBytes;
m_nUndoBufferPos+=nRedoBytes;
nBytes-=nRedoBytes;
m_nPosition+=nRedoBytes;
if(m_nUndoBufferPos==m_nUndoBufferFilled && m_nUndoRecordingCount==0)
{
m_nUndoBufferFilled=0;
m_nUndoBufferPos=0;
}
nResult+=nRedoBytes;
}
if(nBytes>0)
{
//first try to skip using seek
if(nBytes>1024 && m_Callbacks.Seek!=NULL && m_nUndoRecordingCount==0)
{
long nLength=GetLength();
if(nLength!=-1)
{
long nToSkip=nBytes;
if(m_nPosition+nToSkip>nLength)
nToSkip=nLength-m_nPosition;
if(m_Callbacks.Seek(m_pCallbackContext,m_nPosition+nToSkip)!=0)
{
m_nPosition+=nToSkip;
nResult+=nToSkip;
nBytes-=nToSkip;
}
else
{
//seek failed - not critical, we can still try to skip
//using read.
bSeekFailed=true;
}
}
}
}
if(nBytes>0)
{
int nToRead;
int nRead;
if(m_pSkipBuffer==NULL)
{
m_nSkipBufferSize=8192;
m_pSkipBuffer=new unsigned char[m_nSkipBufferSize];
}
while(nBytes>0 && !m_bEOF)
{
nToRead=(nBytes<=m_nSkipBufferSize) ? nBytes : m_nSkipBufferSize;
nRead=m_Callbacks.Read(m_pCallbackContext,m_pSkipBuffer,nToRead);
if(nRead>=0)
{
if(nRead!=nToRead)
m_bEOF=true;
m_nPosition+=nRead;
if(m_nUndoRecordingCount>0)
{
EnsureUndoBufferFree(nRead);
memcpy(m_pUndoBuffer+m_nUndoBufferPos,m_pSkipBuffer,nRead);
m_nUndoBufferFilled+=nRead;
m_nUndoBufferPos+=nRead;
}
nResult+=nRead;
nBytes-=nRead;
}
else
{
if(bSeekFailed)
{
//if seek also failed before we report a seek error
m_LastError=DECMPA_ERROR_SEEK;
}
else
m_LastError=DECMPA_ERROR_READ;
nResult=-1;
break;
}
}
}
return nResult;
}
bool CDecMPAFileAccess::IsEndOfFile()
{
return m_bEOF;
}
bool CDecMPAFileAccess::Seek(long pos)
{
bool bResult=false;
if(pos==m_nPosition)
bResult=true;
else
{
if(m_nUndoRecordingCount==0)
{
if(m_Callbacks.Seek!=NULL)
{
if(m_Callbacks.Seek(m_pCallbackContext,pos)!=0)
{
m_nPosition=pos;
bResult=true;
}
else
m_LastError=DECMPA_ERROR_SEEK;
}
}
}
return bResult;
}
long CDecMPAFileAccess::GetPosition()
{
return m_nPosition;
}
long CDecMPAFileAccess::GetLength()
{
long nLength=-1;
if(m_Callbacks.GetLength!=NULL)
nLength=m_Callbacks.GetLength(m_pCallbackContext);
return nLength;
}
long CDecMPAFileAccess::StartUndoRecording()
{
m_nUndoRecordingCount++;
return m_nUndoBufferPos;
}
void CDecMPAFileAccess::EndUndoRecording(long ID,bool bUndo)
{
if(m_nUndoRecordingCount>0)
{
if(bUndo)
{
m_nPosition-=m_nUndoBufferPos-ID;
if(m_nUndoBufferPos!=ID)
m_bEOF=false;
m_nUndoBufferPos=ID;
}
m_nUndoRecordingCount--;
}
}
void CDecMPAFileAccess::EnsureUndoBufferFree(long nBytes)
{
if(m_nUndoBufferPos+nBytes>m_nUndoBufferSize)
{
unsigned char* pNew;
long nAdd=m_nUndoBufferPos+nBytes-m_nUndoBufferSize;
if((nAdd & 8191)!=0)
nAdd+=8192-(nAdd & 8191);
pNew=new unsigned char[m_nUndoBufferSize+nAdd];
memcpy(pNew,m_pUndoBuffer,m_nUndoBufferFilled);
m_nUndoBufferSize+=nAdd;
if(m_pUndoBuffer!=NULL)
delete[] m_pUndoBuffer;
m_pUndoBuffer=pNew;
}
}
int CDecMPAFileAccess::GetLastError()
{
return m_LastError;
}
bool CDecMPAFileAccess::CanSeek()
{
return (m_Callbacks.Seek!=NULL);
}

View File

@ -0,0 +1,75 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _DECMPAFILEACCESS_H_
#define _DECMPAFILEACCESS_H_
#include "../include/decmpa.h"
#include "IFileAccess.h"
class CDecMPAFileAccess : public IFileAccess
{
public:
CDecMPAFileAccess(const DecMPA_Callbacks& Callbacks,void* pContext);
~CDecMPAFileAccess();
int Read(void* pDest,int nBytes);
long Skip(long nBytes);
bool IsEndOfFile();
bool CanSeek();
bool Seek(long pos);
long GetPosition();
long GetLength();
long StartUndoRecording();
void EndUndoRecording(long ID,bool bUndo);
int GetLastError();
protected:
void EnsureUndoBufferFree(long nBytes);
DecMPA_Callbacks m_Callbacks;
void* m_pCallbackContext;
long m_nPosition;
bool m_bEOF;
unsigned char* m_pUndoBuffer;
long m_nUndoBufferSize;
long m_nUndoBufferFilled;
long m_nUndoBufferPos;
int m_nUndoRecordingCount;
unsigned char* m_pSkipBuffer;
long m_nSkipBufferSize;
int m_LastError;
};
#endif

View File

@ -0,0 +1,36 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _DECODEENGINE_H_
#define _DECODEENGINE_H_
#include "frame/audioFrame.h"
void* DecodeEngine_Create();
bool DecodeEngine_Decode(void* pEngine,AudioFrame* pDest,void* pData,long nDataLength);
void DecodeEngine_Flush(void* pEngine);
void DecodeEngine_Destroy(void* pEngine);
#endif

View File

@ -0,0 +1,25 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include <new>

View File

@ -0,0 +1,40 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _IFILEACCESS_H_
#define _IFILEACCESS_H_
class IFileAccess
{
public:
virtual int Read(void* pDest,int nBytes)=0;
virtual long Skip(long nBytes)=0;
virtual bool IsEndOfFile()=0;
virtual bool CanSeek()=0;
virtual bool Seek(long nPosition)=0;
virtual long GetPosition()=0;
virtual long GetLength()=0;
};
#endif

View File

@ -0,0 +1,638 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
//This file is a heavily modified version of SPlayPlugin.cpp from the original
//mpeglib. See Readme.txt for details.
#include "DefInc.h"
#include "MPADecoder.h"
#include "DecodeEngine.h"
#include <exception>
#include <memory>
#include <math.h>
CMPADecoder::CMPADecoder(const DecMPA_Callbacks& Callbacks,void* pCallbackContext)
{
pow(6.0,3.0); // fixes bug in __math.h
m_Callbacks=Callbacks;
m_pCallbackContext=pCallbackContext;
m_pFileAccess=new CDecMPAFileAccess(Callbacks,pCallbackContext);
m_nResyncCounter=0;
m_nBufferBytes=0;
m_nUsedBufferBytes=0;
m_pBuffer=NULL;
m_OutputFormat.nType=0;
m_OutputFormat.nFrequency=0;
m_OutputFormat.nChannels=0;
m_bOutputFormatChanged=false;
memset(&m_MPEGHeader,0,sizeof(m_MPEGHeader));
m_bDoFloat=false;
m_pPCMFrame=new PCMFrame(MP3FRAMESIZE);
m_pFloatFrame=new FloatFrame(MP3FRAMESIZE);
m_pAudioFrame=NULL;
m_pFormatFrame=new AudioFrame;
m_nReadTime=0;
m_nBufferStartTime=0;
m_nDecodeTime=0;
m_bPrepared=false;
m_bHasFrame=false;
m_bFirstDecode=true;
m_pDecodeEngine=DecodeEngine_Create();
m_bStoreID3v2=false;
m_pID3v2Data=(unsigned char*)0;
m_nID3v2DataSize=0;
m_pDestroyNotify=(void (*)(void*))0;
m_pDestroyNotifyContext=(void*)0;
m_aParams[DECMPA_PARAM_OUTPUT]=DECMPA_OUTPUT_INT16;
m_aParams[DECMPA_PARAM_PROVIDEID3V2]=DECMPA_NO;
m_bNotMPEG=false;
m_bDecoderNeedsFlush=false;
}
CMPADecoder::~CMPADecoder()
{
if(m_pDestroyNotify!=(void (*)(void*))0)
m_pDestroyNotify(m_pDestroyNotifyContext);
delete m_pPCMFrame;
delete m_pFloatFrame;
delete m_pFileAccess;
delete m_pFormatFrame;
DecodeEngine_Destroy(m_pDecodeEngine);
}
int CMPADecoder::DecodeNoData(long& nDecodedBytes)
{
return Decode(NULL,-1,nDecodedBytes);
}
int CMPADecoder::Decode(void* pBuffer,long nBufferBytes,long& nBytesDecoded)
{
int Result=DECMPA_OK;
if(pBuffer==NULL)
nBufferBytes=-1;
nBytesDecoded=0;
m_bOutputFormatChanged=false;
if((Result=EnsurePrepared())!=DECMPA_OK)
return Result;
try
{
while(!ReadDecodedData(pBuffer,nBufferBytes,nBytesDecoded))
{
Result=DecodeNextFrame(pBuffer==NULL);
if(Result!=DECMPA_OK)
break;
}
}
catch(std::bad_alloc)
{
return DECMPA_ERROR_MEMORY;
}
catch(std::exception)
{
return DECMPA_ERROR_INTERNAL;
}
return Result;
}
int CMPADecoder::DecodeNextFrame(bool bNoData)
{
int Result=DECMPA_OK;
//find and read the next frame
//we may still have one frame buffered that was read to find out
//the file information. In that case don't read another one
if(!m_bHasFrame)
m_bHasFrame=ReadNextFrame();
if(m_bHasFrame)
{
bool bDecodeOK;
//don't use this frame again
m_bHasFrame=false;
//if bNoData==true we don't decode any audio data but only
//parse the frame headers
//this allows the user to do a quick pass over the file and
//get an accurate estimate of the files properties
//(actual duration, decoded size, etc...).
if(!bNoData)
{
if(m_bDecoderNeedsFlush)
{
DecodeEngine_Flush(m_pDecodeEngine);
m_bDecoderNeedsFlush=false;
}
bDecodeOK=DecodeEngine_Decode(m_pDecodeEngine,m_pAudioFrame,m_FrameFinder.GetFrameData(),m_FrameFinder.GetFrameSize());
}
else
{
MpegAudioHeader* pHeader=m_FrameFinder.GetFrameHeader();
long nDecodedFrameSize;
m_bDecoderNeedsFlush=true;
nDecodedFrameSize=pHeader->getpcmperframe();
if(pHeader->getInputstereo()==1)
nDecodedFrameSize*=2;
//pretend that we have decoded something
m_pAudioFrame->setLen(nDecodedFrameSize);
m_pAudioFrame->setFrameFormat(pHeader->getInputstereo(),pHeader->getFrequencyHz());
//note that this "ghost data" will never be retrieved because the call
//to ReadDecodedData that follows will always remove all of it
//(see Decode)
bDecodeOK=true;
}
if(bDecodeOK)
{
//make the decoded data available to the "user"
HandleDecodedData(m_pAudioFrame);
}
//ignore if the decoding of the frame failed. Just continue with
//the next frame
}
else
{
if(m_FrameFinder.IsStreamInvalid())
Result=DECMPA_ERROR_DECODE;
else
{
if(m_pFileAccess->IsEndOfFile())
{
//end of file reached
if(!m_FrameFinder.KnowsCharacteristics())
{
//the end was reached without being able to find out
//essential stream characteristics
//=> not an MPEG Audio file (or one that has less than 4 frames)
Result=DECMPA_ERROR_DECODE;
}
else
Result=DECMPA_END;
}
else
{
if(m_pFileAccess->GetLastError()!=DECMPA_OK)
Result=m_pFileAccess->GetLastError();
else
{
//should never happen - an invalid stream, end of file
//or a read error are the only things that could cause
//ReadNextFrame to fail
Result=DECMPA_ERROR_INTERNAL;
}
}
}
}
return Result;
}
void CMPADecoder::Flush()
{
m_FrameFinder.Flush();
DecodeEngine_Flush(m_pDecodeEngine);
m_nBufferBytes=0;
m_nUsedBufferBytes=0;
}
bool CMPADecoder::ReadDecodedData(void* pDest,long nBytes,long& nRead)
{
long nAvailBytes=m_nBufferBytes-m_nUsedBufferBytes;
if(nAvailBytes>0)
{
if(nBytes>nAvailBytes || nBytes==-1)
nBytes=nAvailBytes;
nBytes&=~m_nOutputBlockSize; //only full samples
if(pDest!=NULL)
memcpy(pDest,m_pBuffer+m_nUsedBufferBytes,nBytes);
m_nUsedBufferBytes+=nBytes;
nRead=nBytes;
m_nReadTime=m_nBufferStartTime+(((double)(m_nUsedBufferBytes/m_nOutputBlockSize))*1000)/m_pFormatFrame->getFrequenceHZ();
return true;
}
else
return false;
}
long CMPADecoder::GetFilePositionFromTime(long Millis)
{
int nResult;
if((nResult=EnsurePrepared())!=DECMPA_OK)
return nResult;
return m_Info.GetFilePositionFromTime(Millis);
}
int CMPADecoder::SeekToTime(long Millis)
{
int Result=DECMPA_OK;
if(!m_pFileAccess->CanSeek())
Result=DECMPA_ERROR_UNSUPPORTED;
else
{
long nFilePos;
if((Result=EnsurePrepared())==DECMPA_OK)
{
nFilePos=m_Info.GetFilePositionFromTime(Millis);
if(nFilePos==-1)
Result=DECMPA_ERROR_UNSUPPORTED;
else
{
if(!m_pFileAccess->Seek(nFilePos))
Result=DECMPA_ERROR_SEEK;
else
{
//throw away buffered data
Flush();
if(Millis!=0)
{
//initiate resync (skip next 5 frames until back
//references are ok again)
m_nResyncCounter=5;
}
m_nDecodeTime=Millis;
m_nBufferStartTime=Millis;
m_nReadTime=Millis;
}
}
}
}
return Result;
}
int CMPADecoder::GetTime(long& Time)
{
Time=(long)m_nReadTime;
return DECMPA_OK;
}
int CMPADecoder::GetDuration(long& Duration)
{
int nResult;
try
{
if((nResult=EnsurePrepared())!=DECMPA_OK)
return nResult;
Duration=m_Info.GetDuration();
return DECMPA_OK;
}
catch(std::bad_alloc)
{
return DECMPA_ERROR_MEMORY;
}
catch(std::exception)
{
return DECMPA_ERROR_INTERNAL;
}
}
bool CMPADecoder::ReadNextFrame()
{
while(!m_FrameFinder.ReadNextFrame())
{
if(m_FrameFinder.IsStreamInvalid())
return false;
if(!m_FrameFinder.ReadInput(m_pFileAccess))
return false;
}
return true;
}
void CMPADecoder::SetOutputFormat(AudioFrame* pNewFormatFrame)
{
pNewFormatFrame->copyFormat(m_pFormatFrame);
m_OutputFormat.nFrequency=m_pFormatFrame->getFrequenceHZ();
m_OutputFormat.nChannels=m_pFormatFrame->getStereo() ? 2 : 1;
m_bOutputFormatChanged=true;
m_nOutputBlockSize=m_pFormatFrame->getSampleSize()/8;
m_nOutputBlockSize*=m_OutputFormat.nChannels;
}
void CMPADecoder::UpdateMPEGHeader(MpegAudioHeader* pHeader)
{
memcpy(m_MPEGHeader.aRawData,pHeader->getHeader(),4);
m_MPEGHeader.bProtection=pHeader->getProtection()!=0;
m_MPEGHeader.nLayer=pHeader->getLayer();
m_MPEGHeader.nVersion=pHeader->getVersion();
m_MPEGHeader.bPadding=pHeader->getPadding()!=0;
m_MPEGHeader.nFrequencyIndex=pHeader->getFrequency();
m_MPEGHeader.nFrequency=pHeader->getFrequencyHz();
m_MPEGHeader.nBitRateIndex=pHeader->getBitrateindex();
m_MPEGHeader.nExtendedMode=pHeader->getExtendedmode();
m_MPEGHeader.nMode=pHeader->getMode();
m_MPEGHeader.bInputStereo=pHeader->getInputstereo()!=0;
m_MPEGHeader.bMPEG25=pHeader->getLayer25()!=0;
m_MPEGHeader.nFrameSize=pHeader->getFramesize();
m_MPEGHeader.nDecodedSamplesPerFrame=pHeader->getpcmperframe();
m_MPEGHeader.nBitRateKbps=pHeader->GetBitRateKbps();
}
bool CMPADecoder::OutputFormatChanged()
{
return m_bOutputFormatChanged;
}
void CMPADecoder::GetOutputFormat(DecMPA_OutputFormat& Format)
{
Format=m_OutputFormat;
}
void CMPADecoder::GetMPEGHeader(DecMPA_MPEGHeader& Header)
{
Header=m_MPEGHeader;
}
void CMPADecoder::HandleDecodedData(AudioFrame* pDecodedFrame)
{
int nDecodedSamples;
if(m_bFirstDecode)
{
SetOutputFormat(pDecodedFrame);
m_bFirstDecode=false;
}
nDecodedSamples=pDecodedFrame->getLen();
if(pDecodedFrame->getStereo()==1)
nDecodedSamples/=2;
m_nBufferStartTime=m_nDecodeTime;
m_nDecodeTime+=(((double)nDecodedSamples)*1000)/pDecodedFrame->getFrequenceHZ();
if(m_nResyncCounter>0)
{
//we need to resync = read a few frames to make sure
//that the back references are ok again
//do not output any of the decoded data
m_nResyncCounter--;
}
else
{
if(!m_pFormatFrame->isFormatEqual(pDecodedFrame))
SetOutputFormat(pDecodedFrame);
UpdateMPEGHeader(m_FrameFinder.GetFrameHeader());
if(m_bDoFloat)
{
m_nBufferBytes=m_pFloatFrame->getLen()*sizeof(float);
m_pBuffer=(unsigned char*)m_pFloatFrame->getData();
}
else
{
m_nBufferBytes=m_pPCMFrame->getLen()*sizeof(short);
m_pBuffer=(unsigned char*)m_pPCMFrame->getData();
}
m_nUsedBufferBytes=0;
}
}
int CMPADecoder::EnsurePrepared()
{
int Result=DECMPA_OK;
if(!m_bPrepared)
{
if(m_bNotMPEG)
Result=DECMPA_ERROR_DECODE;
else
{
m_bStoreID3v2=(m_aParams[DECMPA_PARAM_PROVIDEID3V2]==DECMPA_YES);
m_bDoFloat=(m_aParams[DECMPA_PARAM_OUTPUT]==DECMPA_OUTPUT_FLOAT);
m_nOutputBlockSize=1;
if(m_bDoFloat)
m_pAudioFrame=m_pFloatFrame;
else
m_pAudioFrame=m_pPCMFrame;
m_OutputFormat.nType=m_aParams[DECMPA_PARAM_OUTPUT];
//Skip or store any leading ID3 tags - some tags are not
//correctly escaped and contain "sync" codes that can confuse
//the decoder
HandleID3Tag();
if(!m_Info.InitInfo(&m_FrameFinder,m_pFileAccess))
{
m_bNotMPEG=true;
Result=DECMPA_ERROR_DECODE;
}
else
{
//info reads up to one frame.
//we can use this in decoding, we only have to remember not
//to read a fresh one in the first iteration of Decode
m_bHasFrame=m_FrameFinder.HasFrame();
m_bPrepared=true;
}
}
}
return Result;
}
void CMPADecoder::HandleID3Tag()
{
unsigned char aHeaderData[10];
struct ID3v2Header
{
char sID[3];
unsigned char Version;
unsigned char Revision;
unsigned char Flags;
unsigned long Size;
} Header;
int nBytesRead;
long UndoID;
UndoID=m_pFileAccess->StartUndoRecording();
if((nBytesRead=m_pFileAccess->Read((char*)&aHeaderData,10))==10)
{
//we do not read directly into the header because the fields may
//have been padded by the compiler
memcpy(Header.sID,aHeaderData,3);
Header.Version=aHeaderData[3];
Header.Revision=aHeaderData[4];
Header.Flags=aHeaderData[5];
Header.Size=aHeaderData[6];
Header.Size<<=8;
Header.Size|=aHeaderData[7];
Header.Size<<=8;
Header.Size|=aHeaderData[8];
Header.Size<<=8;
Header.Size|=aHeaderData[9];
//make sure its an ID3 header
if(strncmp(Header.sID,"ID3",3)==0 && Header.Version!=0xff && Header.Revision!=0xff
&& (Header.Size & 0x80808080)==0)
{
unsigned long TagSize=Header.Size;
//ok, we have an ID3 tag - no need for undo
m_pFileAccess->EndUndoRecording(UndoID,false);
UndoID=-1;
//correct "unsyncing" of tag size
TagSize=(TagSize & 0x7f) | ((TagSize & 0x7f00)>>1)
| ((TagSize & 0x7f0000)>>2) | ((TagSize & 0x7f000000)>>3);
if(m_bStoreID3v2)
{
//read ID3 tag
m_pID3v2Data=new unsigned char[10+TagSize];
memcpy(m_pID3v2Data,aHeaderData,10);
if(m_pFileAccess->Read(m_pID3v2Data+10,TagSize)==(long)TagSize)
m_nID3v2DataSize=TagSize+10;
else
{
delete[] m_pID3v2Data;
m_pID3v2Data=(unsigned char*)0;
}
}
else
{
//skip the ID3 tag
m_pFileAccess->Skip(TagSize);
}
}
}
if(UndoID!=-1)
{
//no ID3 tag found
//=> undo read operations
m_pFileAccess->EndUndoRecording(UndoID,true);
}
}
int CMPADecoder::GetID3v2Data(unsigned char*& pData,long& nDataSize)
{
int nResult;
if((nResult=EnsurePrepared())!=DECMPA_OK)
return nResult;
if(m_pID3v2Data==(unsigned char*)0)
return DECMPA_ERROR_NOTAVAILABLE;
pData=m_pID3v2Data;
nDataSize=m_nID3v2DataSize;
return DECMPA_OK;
}
int CMPADecoder::SetParam(int ID,long Value)
{
bool bOK=false;
if(m_bPrepared)
return DECMPA_ERROR_WRONGSTATE;
switch(ID)
{
case DECMPA_PARAM_OUTPUT: bOK=(Value==DECMPA_OUTPUT_INT16 || Value==DECMPA_OUTPUT_FLOAT);
break;
case DECMPA_PARAM_PROVIDEID3V2: bOK=(Value==DECMPA_YES || Value==DECMPA_NO);
break;
}
if(!bOK)
return DECMPA_ERROR_PARAM;
m_aParams[ID]=Value;
return DECMPA_OK;
}
long CMPADecoder::GetParam(int ID)
{
if(ID<0 || ID>=DECMPA_PARAMCOUNT)
return 0;
return m_aParams[ID];
}

View File

@ -0,0 +1,143 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
//This file is a heavily modified version of SPlayPlugin.h from the original
//mpeglib. See Readme.txt for details.
#ifndef _MPADECODER_H_
#define _MPADECODER_H_
#include "../include/decmpa.h"
#include "DecMPAFileAccess.h"
#include "frame/pcmFrame.h"
#include "frame/floatFrame.h"
#include "MPAFrameFinder.h"
#include "MPAInfo.h"
class CMPADecoder
{
public:
CMPADecoder(const DecMPA_Callbacks& Callbacks,void* pCallbackContext);
~CMPADecoder();
int Decode(void* pBuffer,long nBufferBytes,long& nBytesDecoded);
int DecodeNoData(long& nDecodedBytes);
int SeekToTime(long Millis);
int GetTime(long& Time);
int GetDuration(long& Duration);
bool OutputFormatChanged();
void GetOutputFormat(DecMPA_OutputFormat& Format);
void GetMPEGHeader(DecMPA_MPEGHeader& Header);
int GetID3v2Data(unsigned char*& pData,long& nDataSize);
inline void SetDestroyNotify(void (*pNotify)(void*),void* pContext);
long GetFilePositionFromTime(long Millis);
int SetParam(int ID,long Value);
long GetParam(int ID);
protected:
int DecodeNextFrame(bool bNoData);
bool ReadNextFrame();
void HandleDecodedData(AudioFrame* playFrame);
void SetOutputFormat(AudioFrame* pNewFormatFrame);
bool ReadDecodedData(void* pDest,long nBytes,long& nRead);
void Flush();
int EnsurePrepared();
void HandleID3Tag();
void UpdateMPEGHeader(MpegAudioHeader* pHeader);
DecMPA_Callbacks m_Callbacks;
void* m_pCallbackContext;
bool m_bDoFloat;
AudioFrame* m_pAudioFrame;
FloatFrame* m_pFloatFrame;
PCMFrame* m_pPCMFrame;
AudioFrame* m_pFormatFrame;
int m_nOutputBlockSize;
CDecMPAFileAccess* m_pFileAccess;
long m_nBufferBytes;
long m_nUsedBufferBytes;
unsigned char* m_pBuffer;
double m_nReadTime;
double m_nBufferStartTime;
double m_nDecodeTime;
DecMPA_OutputFormat m_OutputFormat;
bool m_bOutputFormatChanged;
DecMPA_MPEGHeader m_MPEGHeader;
bool m_bFirstDecode;
bool m_bPrepared;
bool m_bHasFrame;
int m_nResyncCounter;
void* m_pDecodeEngine;
CMPAFrameFinder m_FrameFinder;
CMPAInfo m_Info;
bool m_bStoreID3v2;
unsigned char* m_pID3v2Data;
long m_nID3v2DataSize;
void (*m_pDestroyNotify)(void*);
void* m_pDestroyNotifyContext;
long m_aParams[DECMPA_PARAMCOUNT];
bool m_bNotMPEG;
bool m_bDecoderNeedsFlush;
};
inline void CMPADecoder::SetDestroyNotify(void (*pNotify)(void*),void* pContext)
{
m_pDestroyNotify=pNotify;
m_pDestroyNotifyContext=pContext;
}
#endif

View File

@ -0,0 +1,550 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include "MPAFrameFinder.h"
#include <memory.h>
CMPAFrameFinder::CMPAFrameFinder()
{
// max size of buffer is:
// header: 4
// max bitrate: 448
// min freq: 22050
// padding: 1
// ------------------
// maxsize: 4+144000*max(bitrate)/min(freq)+1 ca: 2931 byte
// then we add a "sentinel" at the end these are 4 byte.
// so we should be ok, with a 4KB buffer.
m_OutBuffer.Alloc(4096);
m_OutBuffer.SetSize(4096);
m_MyInBuffer.Alloc(65536);
m_pFirstHeader=(HeaderRecord*)0;
m_pLastHeader=(HeaderRecord*)0;
m_pNewHeaderRecord=(HeaderRecord*)0;
m_bStreamInvalid=false;
m_nLayer=-1;
m_bAllowFrequencyChanges=false;
m_nLookAheadFrames=3; //try to find 4 consistent frames by default
m_nReadStartPosition=0;
Restart();
}
CMPAFrameFinder::~CMPAFrameFinder()
{
DeleteHeaderRecords();
}
bool CMPAFrameFinder::ReadNextFrame()
{
bool bNeedMoreThanAvailable;
if(m_State==STATE_HAVEFRAME)
ResetState();
while(true)
{
bNeedMoreThanAvailable=false;
while(m_State!=STATE_HAVEFRAME && m_pInBuffer->HasMoreData() && !bNeedMoreThanAvailable)
{
switch(m_State)
{
case STATE_FINDCHARACTERISTICS: if(!FindCharacteristics())
{
//need more data, but we may still have
//up to 3 bytes buffered
//so, break manually here
bNeedMoreThanAvailable=true;
}
break;
case STATE_FINDSYNC: FindNextSync();
break;
case STATE_READHEADER: ReadHeader();
break;
case STATE_CHECKHEADER: CheckHeader();
break;
case STATE_READFRAME: ReadFrame();
break;
}
}
if(m_State!=STATE_HAVEFRAME && m_State>=STATE_FINDSYNC && m_pInBuffer==&m_MyInBuffer)
{
//we need more data, but were still reading
//from our own preread data that was used to find out the
//stream characteristics
//switch to user buffer (it may already contain some data)
m_pInBuffer=&m_UserInBuffer;
}
else
break;
}
if(m_State==STATE_FINDCHARACTERISTICS && m_MyInBuffer.GetSize()==m_MyInBuffer.GetCapacity())
{
//we have read the maximum of data and not found m_nLookAheadFrames+1 consistent
//frames
//the stream does probably not contain valid MPEG Audio data
m_bStreamInvalid=true;
}
return (m_State==STATE_HAVEFRAME); //otherwise we need more data
}
bool CMPAFrameFinder::FindCharacteristics()
{
unsigned char* pData;
//we read up to 64k data and try to find at least
//m_nLookAheadFrames+1 frame headers that are consistent with one
//another
while(m_MyInBuffer.GetBytesLeft()>=4)
{
pData=m_MyInBuffer.GetPosPtr();
if(pData[0]==0xff && (pData[1] & 0xe0)==0xe0)
{
//found sync
//parse the header
if(m_pNewHeaderRecord==(HeaderRecord*)0)
m_pNewHeaderRecord=new HeaderRecord;
if(m_pNewHeaderRecord->Header.parseHeader(pData))
{
if(IsValidHeader(&m_pNewHeaderRecord->Header))
{
//seems to be a valid header.
//add the a header record to the list
m_pNewHeaderRecord->nPosition=m_MyInBuffer.GetPos();
m_pNewHeaderRecord->pNext=(HeaderRecord*)0;
if(m_pLastHeader==(HeaderRecord*)0)
m_pFirstHeader=m_pLastHeader=m_pNewHeaderRecord;
else
{
m_pLastHeader->pNext=m_pNewHeaderRecord;
m_pLastHeader=m_pNewHeaderRecord;
}
m_pNewHeaderRecord=(HeaderRecord*)0;
//check wether we have found m_nLookAheadFrames+1 consistent headers yet
if(FindConsistentHeaders())
break;
}
}
}
m_MyInBuffer.AddToPos(1);
}
return (m_State>=STATE_FINDSYNC);
}
bool CMPAFrameFinder::FindConsistentHeaders()
{
HeaderRecord* pRecord;
//ok, we have found some headers in the data stream
//now we try to find m_nLookAheadFrames+1 that are consistent
//and assume that they correspond to valid frames in the stream
pRecord=m_pFirstHeader;
while(pRecord!=(HeaderRecord*)0)
{
//be prejudiced for early headers
if(!CanHaveConsistentHeaders(pRecord,m_nLookAheadFrames))
{
//if we haven't yet read enough data to find
//consistent headers for the first headers, stop
//here
pRecord=(HeaderRecord*)0;
break;
}
//find two headers that are consistent with this one
if(HasConsistentHeaders(pRecord,pRecord->pNext,m_nLookAheadFrames))
break;
pRecord=pRecord->pNext;
}
if(pRecord!=(HeaderRecord*)0)
{
//yay! we found m_nLookAheadFrames+1 consistent headers.
//The first of them is pRecord
//store stream characteristics
m_nLayer=pRecord->Header.getLayer();
m_nInputStereo=pRecord->Header.getInputstereo();
m_nFrequency=pRecord->Header.getFrequencyHz();
m_nLayer25=pRecord->Header.getLayer25();
m_nVersion=pRecord->Header.getVersion();
//set input buffer to start of first frame
m_MyInBuffer.SetPos(pRecord->nPosition);
m_nFirstFramePosition=pRecord->nPosition+m_nReadStartPosition;
//throw away the header records
DeleteHeaderRecords();
//got to next state (start extracting frame data)
m_State++;
return true;
}
return false;
}
bool CMPAFrameFinder::CanHaveConsistentHeaders(CMPAFrameFinder::HeaderRecord* pRecord,int nHeaderCount)
{
long nFirstFrameBegin;
int nFrameSize;
long nLastFrameHeaderEnd;
nFirstFrameBegin=pRecord->nPosition;
nFrameSize=pRecord->Header.getFramesize();
//assume that the frames have a size difference of at most 512 bytes
//(or at most 512 bytes of data in between)
nLastFrameHeaderEnd=nFirstFrameBegin+((nFrameSize+512)*nHeaderCount)+4;
if(m_MyInBuffer.GetPos()<nLastFrameHeaderEnd)
{
//abort because we have not yet read parsed enough data
return false;
}
return true;
}
bool CMPAFrameFinder::HasConsistentHeaders(CMPAFrameFinder::HeaderRecord* pCheckRecord,HeaderRecord* pRecord,int nHeadersNeeded)
{
while(pRecord!=(HeaderRecord*)0)
{
if(AreHeadersConsistent(pCheckRecord,pRecord))
{
nHeadersNeeded--;
if(nHeadersNeeded==0)
return true;
pCheckRecord=pRecord;
}
pRecord=pRecord->pNext;
}
return false;
}
bool CMPAFrameFinder::AreHeadersConsistent(HeaderRecord* pFirst,HeaderRecord* pSecond)
{
//do the corresponding frames overlap?
if(pFirst->nPosition+pFirst->Header.getFramesize()>pSecond->nPosition)
return false;
//different layers?
if(pFirst->Header.getLayer()!=pSecond->Header.getLayer())
return false;
//one stereo, the other not?
if(pFirst->Header.getInputstereo()!=pSecond->Header.getInputstereo())
return false;
//mpeg 2.5?
if(pFirst->Header.getLayer25()!=pSecond->Header.getLayer25())
return false;
//version?
if(pFirst->Header.getVersion()!=pSecond->Header.getVersion())
return false;
if(!m_bAllowFrequencyChanges)
{
if(pFirst->Header.getFrequencyHz()!=pSecond->Header.getFrequencyHz())
return false;
}
return true;
}
bool CMPAFrameFinder::IsConformingHeader(MpegAudioHeader* pHeader)
{
//check wether the header conforms with the detected stream characteristics
if(pHeader->getInputstereo()==m_nInputStereo
&& pHeader->getLayer()==m_nLayer
&& pHeader->getLayer25()==m_nLayer25
&& pHeader->getVersion()==m_nVersion
&& (pHeader->getFrequencyHz()==m_nFrequency || m_bAllowFrequencyChanges))
{
return true;
}
return false;
}
void CMPAFrameFinder::FindNextSync()
{
unsigned char* pOut=m_OutBuffer.GetPosPtr();
while(m_pInBuffer->HasMoreData())
{
// shift
pOut[0]=pOut[1];
pOut[1]=m_pInBuffer->ReadByte();
if (pOut[0] == 0xff)
{
// upper 4 bit are syncword, except bit one
// which is layer 2.5 indicator.
if ( (pOut[1] & 0xe0) == 0xe0)
{
m_OutBuffer.SetPos(2);
m_State++;
break;
}
}
}
}
void CMPAFrameFinder::ReadHeader()
{
while(m_pInBuffer->HasMoreData())
{
if(m_OutBuffer.GetPos()>=4)
{
m_State++;
break;
}
m_OutBuffer.WriteByte(m_pInBuffer->ReadByte());
}
}
void CMPAFrameFinder::CheckHeader()
{
bool bHeaderOK=false;
if(m_Header.parseHeader(m_OutBuffer.GetPtr()))
{
if(IsValidHeader(&m_Header))
{
//make sure the header conforms to the established stream
//characteristics
if(IsConformingHeader(&m_Header))
{
m_nFrameSize=m_Header.getFramesize();
bHeaderOK=true;
}
}
}
if(bHeaderOK)
m_State++;
else
ResetState();
}
void CMPAFrameFinder::ReadFrame()
{
int nBytesNeeded;
int nBytesAvailable;
int nCopyBytes;
do
{
nBytesNeeded=m_nFrameSize-m_OutBuffer.GetPos();
nBytesAvailable=m_pInBuffer->GetSize()-m_pInBuffer->GetPos();
nCopyBytes=(nBytesAvailable<nBytesNeeded) ? nBytesAvailable : nBytesNeeded;
memcpy(m_OutBuffer.GetPosPtr(),m_pInBuffer->GetPosPtr(),nCopyBytes);
m_OutBuffer.AddToPos(nCopyBytes);
m_pInBuffer->AddToPos(nCopyBytes);
if(nBytesNeeded==nCopyBytes)
{
m_State++;
break;
}
}
while(m_pInBuffer->HasMoreData());
}
void CMPAFrameFinder::SetInput(void* pBuffer,int nBufferBytes,long nStreamPosition)
{
if(m_State==STATE_FINDCHARACTERISTICS)
{
int nCopyBytes=m_MyInBuffer.GetCapacity()-m_MyInBuffer.GetSize();
//copy it in into our own buffer
if(nCopyBytes>nBufferBytes)
nCopyBytes=nBufferBytes;
if(m_MyInBuffer.GetSize()==0)
m_nReadStartPosition=nStreamPosition;
memcpy(m_MyInBuffer.GetPtr()+m_MyInBuffer.GetSize(),pBuffer,nCopyBytes);
m_MyInBuffer.SetSize(m_MyInBuffer.GetSize()+nCopyBytes);
pBuffer=((unsigned char*)pBuffer)+nCopyBytes;
nBufferBytes-=nCopyBytes;
//attach the rest to the user buffer
}
m_UserInBuffer.Attach(pBuffer,nBufferBytes);
}
bool CMPAFrameFinder::ReadInput(IFileAccess* pFileAccess)
{
int nResult;
if(m_State==STATE_FINDCHARACTERISTICS)
{
int nFree=m_MyInBuffer.GetCapacity()-m_MyInBuffer.GetSize();
//read data into our own buffer
if(nFree>0)
{
//read in small chunks
if(nFree>4096)
nFree=4096;
if(m_MyInBuffer.GetSize()==0) //first input
m_nReadStartPosition=pFileAccess->GetPosition();
nResult=pFileAccess->Read((char*)m_MyInBuffer.GetPtr()+m_MyInBuffer.GetSize(),nFree);
if(nResult<=0)
return false;
m_MyInBuffer.SetSize(m_MyInBuffer.GetSize()+nResult);
}
}
else
{
if(m_UserInBuffer.IsAttached())
m_UserInBuffer.Alloc(4096);
nResult=pFileAccess->Read((char*)m_UserInBuffer.GetPtr(),m_UserInBuffer.GetCapacity());
if(nResult<=0)
return false;
m_UserInBuffer.SetSize(nResult);
m_UserInBuffer.SetPos(0);
}
return true;
}
void CMPAFrameFinder::Flush()
{
ResetState();
m_UserInBuffer.SetSize(0);
m_MyInBuffer.SetSize(0);
DeleteHeaderRecords();
}
void CMPAFrameFinder::ResetState()
{
m_OutBuffer.SetPos(0);
//make sure that we do not accidentally treat
//"leftover" data in the buffer as a sync mark
m_OutBuffer.GetPtr()[0]=0;
m_OutBuffer.GetPtr()[1]=0;
if(m_State>=STATE_FINDSYNC)
m_State=STATE_FINDSYNC;
}
void CMPAFrameFinder::Restart()
{
Flush();
m_State=STATE_FINDCHARACTERISTICS;
m_pInBuffer=&m_MyInBuffer;
m_bStreamInvalid=false;
m_nFirstFramePosition=0;
}
void CMPAFrameFinder::DeleteHeaderRecords()
{
HeaderRecord* pRecord;
while(m_pFirstHeader!=(HeaderRecord*)0)
{
pRecord=m_pFirstHeader;
m_pFirstHeader=m_pFirstHeader->pNext;
delete pRecord;
}
m_pLastHeader=(HeaderRecord*)0;
if(m_pNewHeaderRecord!=(HeaderRecord*)0)
{
delete m_pNewHeaderRecord;
m_pNewHeaderRecord=(HeaderRecord*)0;
}
}
bool CMPAFrameFinder::IsValidHeader(MpegAudioHeader* pHeader)
{
int nFrameSize;
nFrameSize=pHeader->getFramesize();
// don't allow stupid framesizes:
// if framesize <4 or > max mepg framsize its an error
if(nFrameSize<4 || nFrameSize+4>4096)
return false;
if(pHeader->GetBitRateKbps()==0)
{
//skip frames with bitrate 0 (empty)
return false;
}
return true;
}

View File

@ -0,0 +1,201 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _MPAFRAMEFINDER_H_
#define _MPAFRAMEFINDER_H_
#include "IFileAccess.h"
#include "mpegAudioFrame/mpegAudioHeader.h"
#include "MemBuffer.h"
class CMPAFrameFinder
{
public:
CMPAFrameFinder();
~CMPAFrameFinder();
inline void SetLookAheadFrames(int nFrames);
inline void SetAllowFrequencyChanges(bool bAllow);
inline int GetLookAheadFrames();
inline bool GetAllowFrequencyChanges();
//if false, the finder needs more input data or the stream
//invalid
bool ReadNextFrame();
inline bool IsStreamInvalid();
inline bool KnowsCharacteristics();
inline bool HasFrame();
inline void* GetFrameData();
inline int GetFrameSize();
inline double GetAvgFrameSize();
inline MpegAudioHeader* GetFrameHeader();
void SetInput(void* pBuffer,int nBytes,long nStreamPosition);
bool ReadInput(IFileAccess* pAccess);
//throw away buffered data and find next frame
void Flush();
//start with a completely blank slate for a new data stream
void Restart();
inline long GetFirstFramePosition();
protected:
struct HeaderRecord
{
MpegAudioHeader Header;
long nPosition;
HeaderRecord* pNext;
};
bool FindCharacteristics();
bool FindConsistentHeaders();
bool CanHaveConsistentHeaders(HeaderRecord* pRecord,int nHeaderCount);
bool HasConsistentHeaders(HeaderRecord* pCheckRecord,HeaderRecord* pRecord,int nHeadersNeeded);
bool AreHeadersConsistent(HeaderRecord* pFirst,HeaderRecord* pSecond);
bool IsConformingHeader(MpegAudioHeader* pHeader);
void FindNextSync();
void ReadHeader();
void CheckHeader();
void ReadFrame();
void ResetState();
void DeleteHeaderRecords();
static bool IsValidHeader(MpegAudioHeader* pHeader);
CMemBuffer m_OutBuffer;
CMemBuffer* m_pInBuffer;
CMemBuffer m_MyInBuffer;
CMemBuffer m_UserInBuffer;
int m_State;
int m_nLookAheadFrames;
bool m_bAllowFrequencyChanges;
int m_nLayer;
int m_nInputStereo;
int m_nFrequency;
int m_nLayer25;
int m_nVersion;
MpegAudioHeader m_Header;
int m_nFrameSize;
long m_nReadStartPosition;
long m_nFirstFramePosition;
enum
{
STATE_FINDCHARACTERISTICS=0,
STATE_FINDSYNC,
STATE_READHEADER,
STATE_CHECKHEADER,
STATE_READFRAME,
STATE_HAVEFRAME
};
HeaderRecord* m_pFirstHeader;
HeaderRecord* m_pLastHeader;
HeaderRecord* m_pNewHeaderRecord;
bool m_bStreamInvalid;
};
inline void CMPAFrameFinder::SetLookAheadFrames(int nFrames)
{
if(nFrames<0)
nFrames=0;
m_nLookAheadFrames=nFrames;
}
inline void CMPAFrameFinder::SetAllowFrequencyChanges(bool bAllow)
{
m_bAllowFrequencyChanges=bAllow;
}
inline int CMPAFrameFinder::GetLookAheadFrames()
{
return m_nLookAheadFrames;
}
inline bool CMPAFrameFinder::GetAllowFrequencyChanges()
{
return m_bAllowFrequencyChanges;
}
inline bool CMPAFrameFinder::HasFrame()
{
return (m_State==STATE_HAVEFRAME);
}
inline void* CMPAFrameFinder::GetFrameData()
{
return m_OutBuffer.GetPtr();
}
inline int CMPAFrameFinder::GetFrameSize()
{
return m_OutBuffer.GetPos();
}
inline double CMPAFrameFinder::GetAvgFrameSize()
{
return m_Header.GetAvgFrameSize();
}
inline MpegAudioHeader* CMPAFrameFinder::GetFrameHeader()
{
return &m_Header;
}
inline bool CMPAFrameFinder::IsStreamInvalid()
{
return m_bStreamInvalid;
}
inline bool CMPAFrameFinder::KnowsCharacteristics()
{
return (m_State>STATE_FINDCHARACTERISTICS);
}
inline long CMPAFrameFinder::GetFirstFramePosition()
{
return m_nFirstFramePosition;
}
#endif

View File

@ -0,0 +1,200 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include "MPAInfo.h"
CMPAInfo::CMPAInfo()
{
m_nEncodedDataSize=-1;
m_nEncodedDataOffset=0;
m_nDuration=-1;
m_bXingVBR=false;
m_XingHeader.toc=m_aXingTOC;
}
CMPAInfo::~CMPAInfo()
{
}
bool CMPAInfo::InitInfo(CMPAFrameFinder* pFrameFinder,IFileAccess* pFileAccess)
{
m_nEncodedDataSize=-1;
m_nEncodedDataOffset=0;
m_nDuration=-1;
m_bXingVBR=false;
while(!pFrameFinder->ReadNextFrame())
{
if(pFrameFinder->IsStreamInvalid())
return false;
if(!pFrameFinder->ReadInput(pFileAccess))
return false;
}
m_nEncodedDataOffset=pFrameFinder->GetFirstFramePosition();
m_nEncodedDataSize=pFileAccess->GetLength();
if(m_nEncodedDataSize!=-1)
{
//ignore any leading non-MPEG-Audio data
m_nEncodedDataSize-=m_nEncodedDataOffset;
}
Init(pFrameFinder);
return true;
}
void CMPAInfo::Init(CMPAFrameFinder* pFrameFinder)
{
double nAvgFrameSize;
int nFrameSize;
long nFrameCount=-1;
nAvgFrameSize=pFrameFinder->GetAvgFrameSize();
nFrameSize=pFrameFinder->GetFrameSize();
if(nAvgFrameSize>0)
{
if(ReadXingHeader(pFrameFinder->GetFrameData(),nFrameSize))
{
m_bXingVBR=true;
nFrameCount=m_XingHeader.frames;
}
else
{
if(m_nEncodedDataSize>=0)
nFrameCount=(long)(m_nEncodedDataSize/nAvgFrameSize);
}
}
if(nFrameCount!=-1)
{
MpegAudioHeader* pHeader=pFrameFinder->GetFrameHeader();
int nDecodedSamplesPerFrame;
int nFrequency;
double nDecodedSamples;
nDecodedSamplesPerFrame=pHeader->getpcmperframe();
nFrequency=pHeader->getFrequencyHz();
nDecodedSamples=((double)nFrameCount)*nDecodedSamplesPerFrame;
if(nFrequency!=0)
m_nDuration=(long)((nDecodedSamples*1000)/nFrequency);
}
}
bool CMPAInfo::ReadXingHeader(void* pFrameData,int nFrameSize)
{
if(nFrameSize<152) //cannot have xing header
return false;
if(::GetXingHeader(&m_XingHeader,(unsigned char*)pFrameData)==0)
return false;
//we use floats so that we won't loose precision
//with the un-compensation stuff below
for(int i=0;i<100;i++)
m_aTOC[i]=((float)m_XingHeader.toc[i])/256.0f;
m_aTOC[100]=1.0f;
if(m_aTOC[0]!=0)
{
//the Xing table of contents compensates for some
//leading non-MP3 data (maybe an ID3 tag or something)
//Since that data may never have been passed to the library
//(or if it has been passed, it should have been skipped)
//we undo this compensation
float FullSizeValue;
FullSizeValue=1.0f-m_aTOC[0];
for(int i=100;i>=0;i--)
m_aTOC[i]=(m_aTOC[i]-m_aTOC[0])/FullSizeValue;
}
return true;
}
long CMPAInfo::GetFilePositionFromTime(long Millis)
{
long nPos=-1;
double nTimeFraction;
if(m_nDuration>0 && m_nEncodedDataSize>=0)
{
nTimeFraction=((double)Millis)/m_nDuration;
if(m_bXingVBR)
{
nPos=GetEncodedDataPositionFromTOC((float)nTimeFraction);
if(nPos>=m_nEncodedDataSize)
nPos=m_nEncodedDataSize;
}
else
nPos=(long)(nTimeFraction*m_nEncodedDataSize);
}
if(nPos==-1)
{
//ok, we couldn't find the correct position because
//we don't know enough about the stream
//however, ONE position we know: the beginning
if(Millis==0)
nPos=0;
}
nPos+=m_nEncodedDataOffset;
return nPos;
}
long CMPAInfo::GetEncodedDataPositionFromTOC(float TimeFract)
{
// interpolate in TOC to get file seek point in bytes
int nTOCIndex;
float LowerPosFract;
float UpperPosFract;
float PosFract;
float Percent=TimeFract*100.0f;
if(Percent<0.0f)
Percent=0.0f;
if(Percent>100.0f)
Percent=100.0f;
nTOCIndex=(int)Percent;
if(nTOCIndex>99)
nTOCIndex=99;
LowerPosFract=m_aTOC[nTOCIndex];
UpperPosFract=m_aTOC[nTOCIndex+1];
PosFract=LowerPosFract + ((UpperPosFract-LowerPosFract)*(Percent-nTOCIndex));
return (long)(PosFract*m_nEncodedDataSize);
}

View File

@ -0,0 +1,81 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _MPAINFO_H_
#define _MPAINFO_H_
#include "IFileAccess.h"
#include "MPAFrameFinder.h"
#include "mpegAudioFrame/dxHead.h"
class CMPAInfo
{
public:
CMPAInfo();
~CMPAInfo();
bool InitInfo(CMPAFrameFinder* pFrameFinder,IFileAccess* pFileAccess);
//-1 if unknown
inline long GetDuration();
//-1 if unknown
long GetFilePositionFromTime(long Millis);
inline bool IsXingVBR();
inline XHEADDATA* GetXingHeader();
protected:
void Init(CMPAFrameFinder* pFrameFinder);
bool ReadXingHeader(void* pFrameData,int nFrameSize);
long GetEncodedDataPositionFromTOC(float TimeFract);
long m_nEncodedDataSize;
long m_nEncodedDataOffset;
long m_nDuration;
bool m_bXingVBR;
XHEADDATA m_XingHeader;
unsigned char m_aXingTOC[100];
float m_aTOC[101];
};
inline long CMPAInfo::GetDuration()
{
return m_nDuration;
}
inline bool CMPAInfo::IsXingVBR()
{
return m_bXingVBR;
}
inline XHEADDATA* CMPAInfo::GetXingHeader()
{
return &m_XingHeader;
}
#endif

View File

@ -0,0 +1,157 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _MEMBUFFER_H_
#define _MEMBUFFER_H_
class CMemBuffer
{
public:
inline CMemBuffer()
{
m_pBuffer=(unsigned char*)0;
m_nSize=0;
m_nCapacity=0;
m_bAllocated=false;
m_nPos=0;
}
inline ~CMemBuffer()
{
Free();
}
inline void Alloc(int nBytes)
{
Free();
if(nBytes>0)
{
m_pBuffer=new unsigned char[nBytes];
m_bAllocated=true;
}
m_nCapacity=nBytes;
}
inline void Free()
{
if(m_bAllocated)
delete[] m_pBuffer;
Detach();
}
inline void Attach(void* pMem,int nBytes)
{
Free();
m_pBuffer=(unsigned char*)pMem;
m_nSize=nBytes;
m_nCapacity=nBytes;
}
inline void Detach()
{
m_pBuffer=(unsigned char*)0;
m_nSize=0;
m_nCapacity=0;
m_bAllocated=false;
m_nPos=0;
}
inline int GetPos()
{
return m_nPos;
}
inline void SetPos(int Pos)
{
m_nPos=Pos;
}
inline void AddToPos(int Add)
{
m_nPos+=Add;
}
inline unsigned char ReadByte()
{
return m_pBuffer[m_nPos++];
}
inline void WriteByte(unsigned char Value)
{
m_pBuffer[m_nPos++]=Value;
}
inline int GetSize()
{
return m_nSize;
}
inline int GetCapacity()
{
return m_nCapacity;
}
inline int GetBytesLeft()
{
return m_nSize-m_nPos;
}
inline void SetSize(int nSize)
{
if(nSize>m_nCapacity)
nSize=m_nCapacity;
m_nSize=nSize;
if(m_nPos>m_nSize)
m_nPos=m_nSize;
}
inline unsigned char* GetPosPtr()
{
return &m_pBuffer[m_nPos];
}
inline unsigned char* GetPtr()
{
return m_pBuffer;
}
inline bool IsAttached()
{
return !m_bAllocated;
}
inline bool HasMoreData()
{
return m_nPos<m_nSize;
}
protected:
unsigned char* m_pBuffer;
int m_nSize;
int m_nCapacity;
bool m_bAllocated;
int m_nPos;
};
#endif

View File

@ -0,0 +1,119 @@
/*
abstract definition of an audio frame
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
//changes 8/4/2002 (by Hauke Duden):
// - removed cout and exit stuff
#include "audioFrame.h"
AudioFrame::AudioFrame() {
stereo=-1;
frequencyHZ=-1;
sampleSize=-1;
lBigEndian=-1;
lSigned=-1;
setFrameType(_FRAME_AUDIO_BASE);
}
AudioFrame::~AudioFrame() {
}
int AudioFrame::getLen() {
//cout << "direct virtual call AudioFrame::getLen"<<endl;
return 0;
}
void AudioFrame::setLen(int ) {
//cout << "direct virtual call AudioFrame::setLen"<<endl;
}
int AudioFrame::getSize() {
//cout << "direct virtual call AudioFrame::getSize"<<endl;
return 0;
}
void AudioFrame::putFloatData(float* ,int ) {
//cout << "direct virtual call AudioFrame::putFloatData"<<endl;
}
void AudioFrame::putFloatData(float* ,float* ,int ) {
//cout << "direct virtual call AudioFrame::putFloatData L/R version"<<endl;
}
void AudioFrame::putInt16Data(short* pdata,int nLength)
{
}
void AudioFrame::putSilence(int nLength)
{
}
void AudioFrame::clearrawdata() {
//cout << "direct virtual call AudioFrame::clearrawdata"<<endl;
}
void AudioFrame::setFrameFormat(int stereo,int freq) {
this->stereo=stereo;
this->frequencyHZ=freq;
}
int AudioFrame::isFormatEqual(AudioFrame* compare) {
if(compare->getStereo() != stereo) {
return false;
}
if(compare->getSampleSize() != sampleSize) {
return false;
}
if(compare->getBigEndian() != lBigEndian) {
return false;
}
if(compare->getFrequenceHZ() != frequencyHZ) {
return false;
}
if(compare->getSigned() != lSigned) {
return false;
}
return true;
}
void AudioFrame::print(const char* msg) {
/*cout << "PCMFrame::print:"<<msg<<endl;
cout << "stereo:"<<stereo<<endl;
cout << "sampleSize:"<<sampleSize<<endl;
cout << "lBigEndian:"<<lBigEndian<<endl;
cout << "frequencyHZ:"<<frequencyHZ<<endl;
cout << "lSigned:"<<lSigned<<endl;*/
}
void AudioFrame::copyFormat(AudioFrame* dest) {
//if (dest->getFrameType() != _FRAME_AUDIO_BASE) {
// cout << "cannot copy frameFormat into frametype!= _FRAME_AUDIO_BASE"<<endl;
// exit(0);
//}
dest->setFrameFormat(getStereo(),getFrequenceHZ());
dest->sampleSize=getSampleSize();
dest->lBigEndian=getBigEndian();
dest->lSigned=getSigned();
}

View File

@ -0,0 +1,85 @@
/*
abstract definition of an audio frame
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#ifndef __AUDIOFRAME_H
#define __AUDIOFRAME_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef WORDS_BIGENDIAN
#define AUDIOFRAME_BIGENDIAN 1
#else
#define AUDIOFRAME_BIGENDIAN 0
#endif
#include "frame.h"
#define SCALFACTOR SHRT_MAX
#define MP3FRAMESIZE (2*2*2*32*18)
class AudioFrame : public Frame {
int stereo;
int frequencyHZ;
public:
AudioFrame();
virtual ~AudioFrame();
// info about "import" data
void setFrameFormat(int stereo,int freq);
inline int getStereo() { return stereo; }
inline int getFrequenceHZ() { return frequencyHZ; }
// these return values depend on the implementation
// how the data is stored internally after "import"
inline int getSampleSize() { return sampleSize; }
inline int getBigEndian() { return lBigEndian; }
inline int getSigned() { return lSigned; }
// info about output
virtual int getLen();
virtual void setLen(int len);
virtual int getSize();
virtual void clearrawdata();
// data import
virtual void putFloatData(float* data,int len);
virtual void putFloatData(float* left,float* right,int len);
virtual void putInt16Data(short* pdata,int nLength);
virtual void putSilence(int nLength);
int isFormatEqual(AudioFrame* compare);
// Note: this can only be called with _real_ AudioFrame's as dest
void copyFormat(AudioFrame* dest);
void print(const char* msg);
protected:
int sampleSize;
int lBigEndian;
int lSigned;
};
#endif

View File

@ -0,0 +1,71 @@
/*
stores frames as floats.
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
//changes 8/4/2002 (by Hauke Duden):
// - removed cout and exit stuff
// - added #include <new> to ensure that bad_alloc will be thrown on mem error
#include "floatFrame.h"
#include <new>
#include <memory.h>
FloatFrame::FloatFrame(int size) {
data=new float[size];
len=0;
this->size=size;
this->sampleSize=sizeof(float)*8;
this->lSigned=true;
this->lBigEndian=AUDIOFRAME_BIGENDIAN;
setFrameType(_FRAME_AUDIO_FLOAT);
}
FloatFrame::~FloatFrame() {
delete data;
}
void FloatFrame::putFloatData(float* in,int lenCopy) {
//if ((len+lenCopy) > size) {
// cout << "cannot copy putFloatData. Does not fit"<<endl;
// exit(0);
//}
memcpy(data+len,in,lenCopy*sizeof(float));
len+=lenCopy;
}
void FloatFrame::putFloatData(float* left,float* right,int len) {
//cout << "not yet implemented"<<endl;
}
void FloatFrame::putInt16Data(short* pData,int nLength)
{
for(int i=0;i<nLength;i++)
data[i]=((float)pData[i])/32768.0f;
len=nLength;
}
void FloatFrame::putSilence(int nLength)
{
for(int i=0;i<nLength;i++)
data[i]=0.0f;
len=nLength;
}

View File

@ -0,0 +1,49 @@
/*
stores frames as floats.
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#ifndef __FLOATFRAME_H
#define __FLOATFRAME_H
#include "audioFrame.h"
// this format has a sampleSize of sizeof(float), signed, endian==machine
class FloatFrame : public AudioFrame {
float* data;
int len;
int size;
public:
FloatFrame(int size);
~FloatFrame();
int getLen() { return len; }
void setLen(int len) { this->len=len; }
int getSize() { return size; }
float* getData() { return data; }
void putFloatData(float* data,int len);
void putFloatData(float* left,float* right,int len);
void putInt16Data(short* pdata,int nLength);
void putSilence(int nLength);
void clearrawdata() { len=0; }
};
#endif

View File

@ -0,0 +1,73 @@
/*
base class for frames
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#include "frame.h"
Frame::Frame() {
type=_FRAME_UNK;
}
Frame::~Frame() {
}
const char* Frame::getMajorFrameName(int type) {
int majorID=type >> 12;
switch(majorID) {
case _FRAME_UNK:
return "_FRAME_UNK";
case _FRAME_RAW:
return "_FRAME_RAW";
case _FRAME_AUDIO:
return "_FRAME_AUDIO";
case _FRAME_VIDEO:
return "_FRAME_VIDEO";
case _FRAME_PAKET:
return "_FRAME_PAKET";
default:
return "unknown major frameType";
}
return "never happens Frame::getMajorFrameName";
}
const char* Frame::getFrameName(int type) {
switch(type) {
// Raw
case _FRAME_RAW_BASE:
return "_FRAME_RAW_BASE";
case _FRAME_RAW_OGG:
return "_FRAME_RAW_OGG";
// Audio
case _FRAME_AUDIO_BASE:
return "_FRAME_AUDIO_BASE";
case _FRAME_AUDIO_PCM:
return "_FRAME_AUDIO_PCM";
case _FRAME_AUDIO_FLOAT:
return "_FRAME_AUDIO_FLOAT";
// Rest
default:
return "cannot find name";
}
return "never happens Frame::getFrameName";
}

View File

@ -0,0 +1,103 @@
/*
base class for frames
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
//changes 8/11/2002 (by Hauke Duden):
// - removed unnecessary includes
#ifndef __FRAME_H
#define __FRAME_H
//#include <iostream.h>
//#include <stdio.h>
//#include <limits.h>
//#include <stdlib.h>
//#include <string.h>
/**
The base class for frames. Every derived class from this class
must belong to some "major" class type and it must have an unique
id for itsself. Even if it is a base class it must have a unique id.
How does this work. We have an int for the Frame id. In the int
itsself we but the majorid as well.
The Start codes are all multiple of 2 so for example
0..127 belongs to FRAME UNK
128..255 belongs to FRAME RAW
So we can with a simple shift operation find out the major class
*/
#define _FRAME_SHIFT 7
#define _FRAME_ID_MAX 128 //(2^_FRAME_SHIFT)
// Major Frame classes
#define _FRAME_UNK 0
#define _FRAME_RAW 1
#define _FRAME_AUDIO 2
#define _FRAME_VIDEO 3
#define _FRAME_PAKET 4
// start ids of minor classes
#define _FRAME_UNK_START (0)
#define _FRAME_RAW_START (_FRAME_ID_MAX)
#define _FRAME_AUDIO_START (_FRAME_ID_MAX*2)
#define _FRAME_VIDEO_START (_FRAME_ID_MAX*2*2)
#define _FRAME_PAKET_START (_FRAME_ID_MAX*2*2*2)
// Minor Frame type IDs
// Raw
#define _FRAME_RAW_BASE (_FRAME_RAW_START+1)
#define _FRAME_RAW_OGG (_FRAME_RAW_START+2)
#define _FRAME_RAW_MPEG_I_VIDEO (_FRAME_RAW_START+3)
#define _FRAME_RAW_MPEG_SYSTEM (_FRAME_RAW_START+4)
// Audio:
#define _FRAME_AUDIO_BASE (_FRAME_AUDIO_START+1)
#define _FRAME_AUDIO_PCM (_FRAME_AUDIO_START+2)
#define _FRAME_AUDIO_FLOAT (_FRAME_AUDIO_START+3)
// Video:
#define _FRAME_VIDEO_BASE (_FRAME_VIDEO_START+1)
#define _FRAME_VIDEO_YUV (_FRAME_VIDEO_START+2)
#define _FRAME_VIDEO_RGB_8 (_FRAME_VIDEO_START+3)
#define _FRAME_VIDEO_RGB_16 (_FRAME_VIDEO_START+4)
#define _FRAME_VIDEO_RGB_32 (_FRAME_VIDEO_START+5)
// Packet:
#define _FRAME_PACKET_SYNC (_FRAME_PAKET_START+1)
#define _FRAME_PACKET_PACKET_CONTAINER (_FRAME_PAKET_START+2)
class Frame {
int type;
public:
Frame();
~Frame();
inline int getMajorFrameType() { return (type>>_FRAME_SHIFT);}
inline int getFrameType() { return type; }
inline void setFrameType(int type) { this->type=type; }
static const char* getMajorFrameName(int type);
static const char* getFrameName(int type);
};
#endif

View File

@ -0,0 +1,143 @@
/*
pcm frame description.
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
//changes 8/4/2002 (by Hauke Duden):
// - removed cout and exit stuff
// - added #include <new> to ensure that bad_alloc will be thrown on mem error
#include "pcmFrame.h"
#include <stdlib.h>
#include <new>
#include <limits.h>
#include <string.h>
//anscheinend ist die range der Werte -1,1
/*#define convMacro(in,dtemp,tmp) \
tmp=(int)(in[0]*32768*0.9f); \
in++; \
if(tmp>32767) \
tmp=32767; \
else if(tmp<-32768) \
tmp=-32768;*/
#define convMacro(in,dtemp,tmp) \
in[0]*=SCALFACTOR; \
dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))+(in[0]); \
tmp = ((*(int *)&dtemp) - 0x80000000); \
in++; \
if(tmp>32767) { \
tmp=32767; \
} else if (tmp<-32768) { \
tmp =-0x8000; \
}
PCMFrame::PCMFrame(int size) {
data=new short int[size];
len=0;
this->size=size;
// this format has a sampleSize of 16, signed, endian==machine
this->sampleSize=sizeof(short int)*8;
this->lSigned=true;
this->lBigEndian=AUDIOFRAME_BIGENDIAN;
setFrameType(_FRAME_AUDIO_PCM);
}
PCMFrame::~PCMFrame() {
delete data;
}
void PCMFrame::putFloatData(float* left,float* right,int copyLen) {
int destSize=0;
if (left != NULL) destSize++;
if (right != NULL) destSize++;
destSize*=copyLen;
/*if ((len+destSize) > size) {
cout << "cannot copy putFloatData L/R version . Does not fit"<<endl;
exit(0);
}*/
double dtemp;
int tmp;
int i=copyLen;
switch(getStereo()) {
case 1:
while(i > 0) {
convMacro(left,dtemp,tmp);
data[len++]=(short int)tmp;
convMacro(right,dtemp,tmp);
data[len++]=(short int)tmp;
i--;
}
break;
case 0:
if (left != NULL) {
int i=copyLen;
while(i > 0) {
convMacro(left,dtemp,tmp);
data[len++]=(short int)tmp;
i--;
// right channel empty
len++;
}
}
if (right != NULL) {
int i=copyLen;
len=len-destSize;
while(i > 0) {
// select right channel
len++;
convMacro(right,dtemp,tmp);
data[len++]=(short int)tmp;
i--;
// left channel already copied
}
}
default:
/*cout << "unknown stereo value in pcmFrame"<<endl;
exit(0);*/
break;
}
}
void PCMFrame::putFloatData(float* in,int lenCopy) {
/*if ((len+lenCopy) > size) {
cout << "cannot copy putFloatData. Does not fit"<<endl;
exit(0);
}*/
double dtemp;
int tmp;
while(lenCopy > 0) {
convMacro(in,dtemp,tmp);
data[len++]=(short int)tmp;
lenCopy--;
}
}
void PCMFrame::putInt16Data(short* pData,int nLength)
{
memcpy(data,pData,nLength*sizeof(short));
len=nLength;
}
void PCMFrame::putSilence(int nLength)
{
memset(data,0,nLength*sizeof(short));
len=nLength;
}

View File

@ -0,0 +1,50 @@
/*
pcm frame description.
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#ifndef __PCMFRAME_H
#define __PCMFRAME_H
#include "audioFrame.h"
// this format has a sampleSize of 16, signed, endian==machine
class PCMFrame : public AudioFrame {
short int* data;
int len;
int size;
public:
PCMFrame(int size);
~PCMFrame();
int getLen() { return len; }
void setLen(int len) { this->len=len; }
int getSize() { return size; }
short int* getData() { return data; }
void putFloatData(float* data,int len);
void putFloatData(float* left,float* right,int len);
void putInt16Data(short* pdata,int nLength);
void putSilence(int nLength);
void clearrawdata() { len=0; }
};
#endif

View File

@ -0,0 +1,21 @@
/*
stores simple buffer information. does not allocate anything
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#include "rawDataBuffer.h"
// hm
RawDataBuffer::~RawDataBuffer() {
}

View File

@ -0,0 +1,48 @@
/*
stores simple buffer information. does not allocate anything
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file License.txt in this package
*/
#ifndef __RAWDATABUFFER_H
#define __RAWDATABUFFER_H
class RawDataBuffer {
int _size;
unsigned char* _ptr;
int _pos;
public:
RawDataBuffer(unsigned char* ptr,int size) { set(ptr,size,0); }
~RawDataBuffer();
unsigned char* ptr() { return _ptr; }
unsigned char* current() { return _ptr+_pos; }
int size() { return _size; }
int pos() { return _pos; }
int untilend() { return _size-_pos; }
int eof() { return _pos>=_size; }
void inc() { this->_pos++; }
void inc(int val) { this->_pos+=val; }
void setpos(int val) { this->_pos=val; }
void setptr(unsigned char* ptr) { this->_ptr=ptr; }
void setsize(int size) { this->_size=size; }
void set(unsigned char* ptr,
int size,int pos) { setpos(pos);setptr(ptr);setsize(size);}
};
#endif

View File

@ -0,0 +1,135 @@
/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include <math.h>
#include "interface.h"
#include "../DecodeEngine.h"
#include "../frame/pcmFrame.h"
#include <new>
extern const long freqs[9];
struct DecodeEngine
{
MPSTR Decoder;
short aTempBuffer[MP3FRAMESIZE*2];
};
void* DecodeEngine_Create()
{
DecodeEngine* pEngine=new DecodeEngine;
if(!InitMP3(&pEngine->Decoder))
{
delete pEngine;
pEngine=(DecodeEngine*)0;
}
return pEngine;
}
void DecodeEngine_Destroy(void* pEng)
{
DecodeEngine* pEngine=(DecodeEngine*)pEng;
ExitMP3(&pEngine->Decoder);
delete pEngine;
}
bool DecodeEngine_Decode(void* pEng,AudioFrame* pDest,void* pData,long nDataLength)
{
DecodeEngine* pEngine=(DecodeEngine*)pEng;
int nDone;
int nResult;
char* pOut;
int nOutSize;
int nChannels;
if(pDest->getFrameType()==_FRAME_AUDIO_PCM)
{
pOut=(char*)((PCMFrame*)pDest)->getData();
nOutSize=pDest->getSize();
}
else
{
pOut=(char*)pEngine->aTempBuffer;
nOutSize=sizeof(pEngine->aTempBuffer)/sizeof(short);
}
nResult=decodeMP3(&pEngine->Decoder,(unsigned char*)pData,nDataLength,pOut,nOutSize,&nDone);
if(nResult==MP3_OK)
{
nDone/=sizeof(short);
nChannels=pEngine->Decoder.fr.stereo;
if(pDest->getFrameType()!=_FRAME_AUDIO_PCM)
pDest->putInt16Data((short*)pOut,nDone);
else
pDest->setLen(nDone);
pDest->setFrameFormat((nChannels==2) ? 1 : 0,freqs[pEngine->Decoder.fr.sampling_frequency]);
return true;
}
else if(nResult==MP3_NEED_MORE)
{
//should never happen otherwise because only whole frames
//are passed to HIP and the modified version of HIP we use
//here does not buffer data from the beginning for later use
//not critical, though
pDest->setLen(0);
pDest->setFrameFormat(1,44100);
return true;
}
else
{
//error
return false;
}
}
void DecodeEngine_Flush(void* pEng)
{
DecodeEngine* pEngine=(DecodeEngine*)pEng;
//complete reinit
ExitMP3(&pEngine->Decoder);
InitMP3(&pEngine->Decoder);
/*while(pEngine->Decoder.tail!=NULL)
remove_buf(&pEngine->Decoder);
pEngine->Decoder.bsize=0;
pEngine->Decoder.header_parsed=0;
pEngine->Decoder.side_parsed=0;
pEngine->Decoder.data_parsed=0;
pEngine->Decoder.sync_bitstream=1;*/
}

View File

@ -0,0 +1,10 @@
#ifndef _HIPDEFINES_H_
#define _HIPDEFINES_H_
#define NOANALYSIS
#define USE_LAYER_1
#define USE_LAYER_2
#define MPEG1
#endif

View File

@ -0,0 +1,176 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#include "VbrTag.h"
#include <stdio.h>
/* stuff from lame's tables.c */
const int bitrate_table [3] [16] = {
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 },
{ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 },
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 },
};
const int samplerate_table [3] [4] = {
{ 22050, 24000, 16000, -1 }, /* MPEG 2 */
{ 44100, 48000, 32000, -1 }, /* MPEG 1 */
{ 11025, 12000, 8000, -1 }, /* MPEG 2.5 */
};
/* end stuff from lame's tables.c */
/* stuff from VbrTag.c/.h */
const static char VBRTag[]={"Xing"};
const static char VBRTag2[]={"Info"};
/* from lame's VbrTag.c */
static int
ExtractI4(unsigned char *buf)
{
int x;
/* big endian extract */
x = buf[0];
x <<= 8;
x |= buf[1];
x <<= 8;
x |= buf[2];
x <<= 8;
x |= buf[3];
return x;
}
/* from lame's VbrTag.c */
int
GetVbrTag(VBRTAGDATA *pTagData, unsigned char *buf)
{
int i, head_flags;
int h_bitrate,h_id, h_mode, h_sr_index;
int enc_delay,enc_padding;
/* get Vbr header data */
pTagData->flags = 0;
/* get selected MPEG header data */
h_id = (buf[1] >> 3) & 1;
h_sr_index = (buf[2] >> 2) & 3;
h_mode = (buf[3] >> 6) & 3;
h_bitrate = ((buf[2]>>4)&0xf);
h_bitrate = bitrate_table[h_id][h_bitrate];
/* check for FFE syncword */
if ((buf[1]>>4)==0xE)
pTagData->samprate = samplerate_table[2][h_sr_index];
else
pTagData->samprate = samplerate_table[h_id][h_sr_index];
// if( h_id == 0 )
// pTagData->samprate >>= 1;
/* determine offset of header */
if( h_id )
{
/* mpeg1 */
if( h_mode != 3 ) buf+=(32+4);
else buf+=(17+4);
}
else
{
/* mpeg2 */
if( h_mode != 3 ) buf+=(17+4);
else buf+=(9+4);
}
if( buf[0] != VBRTag[0] && buf[0] != VBRTag2[0] ) return 0; /* fail */
if( buf[1] != VBRTag[1] && buf[1] != VBRTag2[1]) return 0; /* header not found*/
if( buf[2] != VBRTag[2] && buf[2] != VBRTag2[2]) return 0;
if( buf[3] != VBRTag[3] && buf[3] != VBRTag2[3]) return 0;
buf+=4;
pTagData->h_id = h_id;
head_flags = pTagData->flags = ExtractI4(buf); buf+=4; /* get flags */
if( head_flags & FRAMES_FLAG )
{
pTagData->frames = ExtractI4(buf); buf+=4;
}
if( head_flags & BYTES_FLAG )
{
pTagData->bytes = ExtractI4(buf); buf+=4;
}
if( head_flags & TOC_FLAG )
{
if( pTagData->toc != NULL )
{
for(i=0;i<NUMTOCENTRIES;i++)
pTagData->toc[i] = buf[i];
}
buf+=NUMTOCENTRIES;
}
pTagData->vbr_scale = -1;
if( head_flags & VBR_SCALE_FLAG )
{
pTagData->vbr_scale = ExtractI4(buf); buf+=4;
}
pTagData->headersize =
((h_id+1)*72000*h_bitrate) / pTagData->samprate;
buf+=21;
enc_delay = buf[0] << 4;
enc_delay += buf[1] >> 4;
enc_padding= (buf[1] & 0x0F)<<8;
enc_padding += buf[2];
// check for reasonable values (this may be an old Xing header,
// not a INFO tag)
if (enc_delay<0 || enc_delay > 3000) enc_delay=-1;
if (enc_padding<0 || enc_padding > 3000) enc_padding=-1;
pTagData->enc_delay=enc_delay;
pTagData->enc_padding=enc_padding;
#ifdef HIP_DEBUG
fprintf(stderr,"exit GetVbrTag:\n");
fprintf(stderr," tag = %s\n",VBRTag);
fprintf(stderr," head_flags = %d\n",head_flags);
fprintf(stderr," bytes = %d\n",pTagData->bytes);
fprintf(stderr," frames = %d\n",pTagData->frames);
fprintf(stderr," VBR Scale = %d\n",pTagData->vbr_scale);
fprintf(stderr," enc_delay = %i \n",enc_delay);
fprintf(stderr," enc_padding = %i \n",enc_padding);
fprintf(stderr," toc =\n");
if( pTagData->toc != NULL )
{
for(i=0;i<NUMTOCENTRIES;i++)
{
if( (i%10) == 0 ) fprintf(stderr,"\n");
fprintf(stderr," %3d", (int)(pTagData->toc[i]));
}
}
fprintf(stderr,"\n");
#endif
return 1; /* success */
}

View File

@ -0,0 +1,82 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
*
* Xing VBR tagging for LAME.
*
* Copyright (c) 1999 A.L. Faber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef LAME_VRBTAG_H
#define LAME_VRBTAG_H
/* -----------------------------------------------------------
* A Vbr header may be present in the ancillary
* data field of the first frame of an mp3 bitstream
* The Vbr header (optionally) contains
* frames total number of audio frames in the bitstream
* bytes total number of bytes in the bitstream
* toc table of contents
* toc (table of contents) gives seek points
* for random access
* the ith entry determines the seek point for
* i-percent duration
* seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
* e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes
*/
#define FRAMES_FLAG 0x0001
#define BYTES_FLAG 0x0002
#define TOC_FLAG 0x0004
#define VBR_SCALE_FLAG 0x0008
#define NUMTOCENTRIES 100
#define FRAMES_AND_BYTES (FRAMES_FLAG | BYTES_FLAG)
/*structure to receive extracted header */
/* toc may be NULL*/
typedef struct
{
int h_id; /* from MPEG header, 0=MPEG2, 1=MPEG1 */
int samprate; /* determined from MPEG header */
int flags; /* from Vbr header data */
int frames; /* total bit stream frames from Vbr header data */
int bytes; /* total bit stream bytes from Vbr header data*/
int vbr_scale; /* encoded vbr scale from Vbr header data*/
unsigned char toc[NUMTOCENTRIES]; /* may be NULL if toc not desired*/
int headersize; /* size of VBR header, in bytes */
int enc_delay; /* encoder delay */
int enc_padding; /* encoder paddign added at end of stream */
} VBRTAGDATA;
int CheckVbrTag(unsigned char *buf);
int GetVbrTag(VBRTAGDATA *pTagData, unsigned char *buf);
/*
int SeekPoint(unsigned char TOC[NUMTOCENTRIES], int file_bytes, float percent);
int InitVbrTag(lame_global_flags *gfp);
int PutVbrTag(lame_global_flags *gfp,FILE *fid,int nVbrScale);
int PutLameVBR(lame_global_flags *gfp, FILE *fpStream, uint8_t *pbtStreamBuffer, uint32_t id3v2size, uint16_t crc);
void AddVbrFrame(lame_global_flags *gfp);
void ReportLameTagProgress(lame_global_flags *gfp,int nStart);
void UpdateMusicCRC(uint16_t *crc,unsigned char *buffer, int size);
*/
#endif

View File

@ -0,0 +1,320 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef macintosh
#include <types.h>
#include <stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "common.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
// In C++ the array first must be prototyped, why ?
extern const int tabsel_123 [2] [3] [16];
const int tabsel_123 [2] [3] [16] = {
{ {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
{0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
{0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
{ {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
};
const long freqs[9] = { 44100, 48000, 32000,
22050, 24000, 16000,
11025, 12000, 8000 };
int bitindex;
unsigned char *wordpointer;
unsigned char *pcm_sample;
int pcm_point = 0;
#if defined( USE_LAYER_1 ) || defined ( USE_LAYER_2 )
real muls[27][64];
#endif
#define HDRCMPMASK 0xfffffd00
int head_check(unsigned long head,int check_layer)
{
/*
look for a valid header.
if check_layer > 0, then require that
nLayer = check_layer.
*/
/* bits 13-14 = layer 3 */
int nLayer=4-((head>>17)&3);
if( (head & 0xffe00000) != 0xffe00000) {
/* syncword */
return FALSE;
}
#if 0
if(!((head>>17)&3)) {
/* bits 13-14 = layer 3 */
return FALSE;
}
#endif
if (3 != nLayer)
{
#if defined (USE_LAYER_1) || defined (USE_LAYER_2)
if (4==nLayer)
return FALSE;
#else
return FALSE;
#endif
}
if (check_layer>0) {
if (nLayer != check_layer) return FALSE;
}
if( ((head>>12)&0xf) == 0xf) {
/* bits 16,17,18,19 = 1111 invalid bitrate */
return FALSE;
}
if( ((head>>10)&0x3) == 0x3 ) {
/* bits 20,21 = 11 invalid sampling freq */
return FALSE;
}
return TRUE;
}
/*
* the code a header and write the information
* into the frame structure
*/
int decode_header(struct frame *fr,unsigned long newhead)
{
if( newhead & (1<<20) ) {
fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
fr->mpeg25 = 0;
}
else {
fr->lsf = 1;
fr->mpeg25 = 1;
}
fr->lay = 4-((newhead>>17)&3);
if( ((newhead>>10)&0x3) == 0x3)
{
//fprintf(stderr,"Stream error\n");
//exit(1);
return 0;
}
if(fr->mpeg25) {
fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
}
else
fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
fr->error_protection = ((newhead>>16)&0x1)^0x1;
if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */
fr->bitrate_index = ((newhead>>12)&0xf);
fr->bitrate_index = ((newhead>>12)&0xf);
fr->padding = ((newhead>>9)&0x1);
fr->extension = ((newhead>>8)&0x1);
fr->mode = ((newhead>>6)&0x3);
fr->mode_ext = ((newhead>>4)&0x3);
fr->copyright = ((newhead>>3)&0x1);
fr->original = ((newhead>>2)&0x1);
fr->emphasis = newhead & 0x3;
fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
switch(fr->lay)
{
#ifdef USE_LAYER_1
case 1:
fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
fr->framesize /= freqs[fr->sampling_frequency];
fr->framesize = ((fr->framesize+fr->padding)<<2)-4;
fr->down_sample=0;
fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
break;
#endif
#ifdef USE_LAYER_2
case 2:
fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
fr->framesize /= freqs[fr->sampling_frequency];
fr->framesize += fr->padding - 4;
fr->down_sample=0;
fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
break;
#endif
case 3:
#if 0
fr->do_layer = do_layer3;
if(fr->lsf)
ssize = (fr->stereo == 1) ? 9 : 17;
else
ssize = (fr->stereo == 1) ? 17 : 32;
#endif
#if 0
if(fr->error_protection)
ssize += 2;
#endif
if (fr->bitrate_index==0)
fr->framesize=0;
else{
fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
fr->framesize = fr->framesize + fr->padding - 4;
}
break;
default:
//fprintf(stderr,"Sorry, layer %d not supported\n",fr->lay);
return (0);
}
/* print_header(fr); */
return 1;
}
/*#if 1
void print_header(struct frame *fr)
{
static const char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
static const char *layers[4] = { "Unknown" , "I", "II", "III" };
fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n",
fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
layers[fr->lay],freqs[fr->sampling_frequency],
modes[fr->mode],fr->mode_ext,fr->framesize+4);
fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n",
fr->stereo,fr->copyright?"Yes":"No",
fr->original?"Yes":"No",fr->error_protection?"Yes":"No",
fr->emphasis);
fprintf(stderr,"Bitrate: %d Kbits/s, Extension value: %d\n",
tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension);
}
void print_header_compact(struct frame *fr)
{
static const char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" };
static const char *layers[4] = { "Unknown" , "I", "II", "III" };
fprintf(stderr,"MPEG %s layer %s, %d kbit/s, %ld Hz %s\n",
fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
layers[fr->lay],
tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
freqs[fr->sampling_frequency], modes[fr->mode]);
}
#endif*/
unsigned int getbits(int number_of_bits)
{
unsigned long rval;
if(!number_of_bits)
return 0;
{
rval = wordpointer[0];
rval <<= 8;
rval |= wordpointer[1];
rval <<= 8;
rval |= wordpointer[2];
rval <<= bitindex;
rval &= 0xffffff;
bitindex += number_of_bits;
rval >>= (24-number_of_bits);
wordpointer += (bitindex>>3);
bitindex &= 7;
}
return rval;
}
unsigned int getbits_fast(int number_of_bits)
{
unsigned long rval;
{
rval = wordpointer[0];
rval <<= 8;
rval |= wordpointer[1];
rval <<= bitindex;
rval &= 0xffff;
bitindex += number_of_bits;
rval >>= (16-number_of_bits);
wordpointer += (bitindex>>3);
bitindex &= 7;
}
return rval;
}
int set_pointer( PMPSTR mp, long backstep)
{
unsigned char *bsbufold;
if(mp->fsizeold < 0 && backstep > 0) {
//fprintf(stderr,"Can't step back %ld!\n",backstep);
return MP3_ERR;
}
bsbufold = mp->bsspace[1-mp->bsnum] + 512;
wordpointer -= backstep;
if (backstep)
memcpy(wordpointer,bsbufold+mp->fsizeold-backstep,(size_t)backstep);
bitindex = 0;
return MP3_OK;
}

View File

@ -0,0 +1,54 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifndef COMMON_H_INCLUDED
#define COMMON_H_INCLUDED
#include "HIPDefines.h"
#include "mpg123.h"
#include "mpglib.h"
extern const int tabsel_123[2][3][16];
extern const long freqs[9];
extern unsigned char *wordpointer;
extern int bitindex;
#if defined( USE_LAYER_1 ) || defined ( USE_LAYER_2 )
extern real muls[27][64];
#endif
int head_check(unsigned long head,int check_layer);
int decode_header(struct frame *fr,unsigned long newhead);
void print_header(struct frame *fr);
void print_header_compact(struct frame *fr);
unsigned int getbits(int number_of_bits);
unsigned int getbits_fast(int number_of_bits);
int set_pointer( PMPSTR mp, long backstep);
#endif

View File

@ -0,0 +1,348 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* Discrete Cosine Tansform (DCT) for subband synthesis
* optimized for machines with no auto-increment.
* The performance is highly compiler dependend. Maybe
* the dct64.c version for 'normal' processor may be faster
* even for Intel processors.
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "dct64_i386.h"
#include "tabinit.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples)
{
{
register real *costab = pnts[0];
b1[0x00] = samples[0x00] + samples[0x1F];
b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
b1[0x01] = samples[0x01] + samples[0x1E];
b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
b1[0x02] = samples[0x02] + samples[0x1D];
b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
b1[0x03] = samples[0x03] + samples[0x1C];
b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
b1[0x04] = samples[0x04] + samples[0x1B];
b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
b1[0x05] = samples[0x05] + samples[0x1A];
b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
b1[0x06] = samples[0x06] + samples[0x19];
b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
b1[0x07] = samples[0x07] + samples[0x18];
b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
b1[0x08] = samples[0x08] + samples[0x17];
b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
b1[0x09] = samples[0x09] + samples[0x16];
b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
b1[0x0A] = samples[0x0A] + samples[0x15];
b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
b1[0x0B] = samples[0x0B] + samples[0x14];
b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
b1[0x0C] = samples[0x0C] + samples[0x13];
b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
b1[0x0D] = samples[0x0D] + samples[0x12];
b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
b1[0x0E] = samples[0x0E] + samples[0x11];
b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
b1[0x0F] = samples[0x0F] + samples[0x10];
b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
}
{
register real *costab = pnts[1];
b2[0x00] = b1[0x00] + b1[0x0F];
b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
b2[0x01] = b1[0x01] + b1[0x0E];
b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
b2[0x02] = b1[0x02] + b1[0x0D];
b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
b2[0x03] = b1[0x03] + b1[0x0C];
b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
b2[0x04] = b1[0x04] + b1[0x0B];
b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
b2[0x05] = b1[0x05] + b1[0x0A];
b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
b2[0x06] = b1[0x06] + b1[0x09];
b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
b2[0x07] = b1[0x07] + b1[0x08];
b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
b2[0x10] = b1[0x10] + b1[0x1F];
b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
b2[0x11] = b1[0x11] + b1[0x1E];
b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
b2[0x12] = b1[0x12] + b1[0x1D];
b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
b2[0x13] = b1[0x13] + b1[0x1C];
b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
b2[0x14] = b1[0x14] + b1[0x1B];
b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
b2[0x15] = b1[0x15] + b1[0x1A];
b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
b2[0x16] = b1[0x16] + b1[0x19];
b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
b2[0x17] = b1[0x17] + b1[0x18];
b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
}
{
register real *costab = pnts[2];
b1[0x00] = b2[0x00] + b2[0x07];
b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
b1[0x01] = b2[0x01] + b2[0x06];
b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
b1[0x02] = b2[0x02] + b2[0x05];
b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
b1[0x03] = b2[0x03] + b2[0x04];
b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
b1[0x08] = b2[0x08] + b2[0x0F];
b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
b1[0x09] = b2[0x09] + b2[0x0E];
b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
b1[0x0A] = b2[0x0A] + b2[0x0D];
b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
b1[0x0B] = b2[0x0B] + b2[0x0C];
b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
b1[0x10] = b2[0x10] + b2[0x17];
b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
b1[0x11] = b2[0x11] + b2[0x16];
b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
b1[0x12] = b2[0x12] + b2[0x15];
b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
b1[0x13] = b2[0x13] + b2[0x14];
b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
b1[0x18] = b2[0x18] + b2[0x1F];
b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
b1[0x19] = b2[0x19] + b2[0x1E];
b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
b1[0x1A] = b2[0x1A] + b2[0x1D];
b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
b1[0x1B] = b2[0x1B] + b2[0x1C];
b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
}
{
register real const cos0 = pnts[3][0];
register real const cos1 = pnts[3][1];
b2[0x00] = b1[0x00] + b1[0x03];
b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
b2[0x01] = b1[0x01] + b1[0x02];
b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
b2[0x04] = b1[0x04] + b1[0x07];
b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
b2[0x05] = b1[0x05] + b1[0x06];
b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
b2[0x08] = b1[0x08] + b1[0x0B];
b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
b2[0x09] = b1[0x09] + b1[0x0A];
b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
b2[0x0C] = b1[0x0C] + b1[0x0F];
b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
b2[0x0D] = b1[0x0D] + b1[0x0E];
b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
b2[0x10] = b1[0x10] + b1[0x13];
b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
b2[0x11] = b1[0x11] + b1[0x12];
b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
b2[0x14] = b1[0x14] + b1[0x17];
b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
b2[0x15] = b1[0x15] + b1[0x16];
b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
b2[0x18] = b1[0x18] + b1[0x1B];
b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
b2[0x19] = b1[0x19] + b1[0x1A];
b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
b2[0x1C] = b1[0x1C] + b1[0x1F];
b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
b2[0x1D] = b1[0x1D] + b1[0x1E];
b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
}
{
register real const cos0 = pnts[4][0];
b1[0x00] = b2[0x00] + b2[0x01];
b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
b1[0x02] = b2[0x02] + b2[0x03];
b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
b1[0x02] += b1[0x03];
b1[0x04] = b2[0x04] + b2[0x05];
b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
b1[0x06] = b2[0x06] + b2[0x07];
b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
b1[0x06] += b1[0x07];
b1[0x04] += b1[0x06];
b1[0x06] += b1[0x05];
b1[0x05] += b1[0x07];
b1[0x08] = b2[0x08] + b2[0x09];
b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
b1[0x0A] = b2[0x0A] + b2[0x0B];
b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
b1[0x0A] += b1[0x0B];
b1[0x0C] = b2[0x0C] + b2[0x0D];
b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
b1[0x0E] = b2[0x0E] + b2[0x0F];
b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
b1[0x0E] += b1[0x0F];
b1[0x0C] += b1[0x0E];
b1[0x0E] += b1[0x0D];
b1[0x0D] += b1[0x0F];
b1[0x10] = b2[0x10] + b2[0x11];
b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
b1[0x12] = b2[0x12] + b2[0x13];
b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
b1[0x12] += b1[0x13];
b1[0x14] = b2[0x14] + b2[0x15];
b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
b1[0x16] = b2[0x16] + b2[0x17];
b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
b1[0x16] += b1[0x17];
b1[0x14] += b1[0x16];
b1[0x16] += b1[0x15];
b1[0x15] += b1[0x17];
b1[0x18] = b2[0x18] + b2[0x19];
b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
b1[0x1A] = b2[0x1A] + b2[0x1B];
b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
b1[0x1A] += b1[0x1B];
b1[0x1C] = b2[0x1C] + b2[0x1D];
b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
b1[0x1E] = b2[0x1E] + b2[0x1F];
b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
b1[0x1E] += b1[0x1F];
b1[0x1C] += b1[0x1E];
b1[0x1E] += b1[0x1D];
b1[0x1D] += b1[0x1F];
}
out0[0x10*16] = b1[0x00];
out0[0x10*12] = b1[0x04];
out0[0x10* 8] = b1[0x02];
out0[0x10* 4] = b1[0x06];
out0[0x10* 0] = b1[0x01];
out1[0x10* 0] = b1[0x01];
out1[0x10* 4] = b1[0x05];
out1[0x10* 8] = b1[0x03];
out1[0x10*12] = b1[0x07];
b1[0x08] += b1[0x0C];
out0[0x10*14] = b1[0x08];
b1[0x0C] += b1[0x0a];
out0[0x10*10] = b1[0x0C];
b1[0x0A] += b1[0x0E];
out0[0x10* 6] = b1[0x0A];
b1[0x0E] += b1[0x09];
out0[0x10* 2] = b1[0x0E];
b1[0x09] += b1[0x0D];
out1[0x10* 2] = b1[0x09];
b1[0x0D] += b1[0x0B];
out1[0x10* 6] = b1[0x0D];
b1[0x0B] += b1[0x0F];
out1[0x10*10] = b1[0x0B];
out1[0x10*14] = b1[0x0F];
b1[0x18] += b1[0x1C];
out0[0x10*15] = b1[0x10] + b1[0x18];
out0[0x10*13] = b1[0x18] + b1[0x14];
b1[0x1C] += b1[0x1a];
out0[0x10*11] = b1[0x14] + b1[0x1C];
out0[0x10* 9] = b1[0x1C] + b1[0x12];
b1[0x1A] += b1[0x1E];
out0[0x10* 7] = b1[0x12] + b1[0x1A];
out0[0x10* 5] = b1[0x1A] + b1[0x16];
b1[0x1E] += b1[0x19];
out0[0x10* 3] = b1[0x16] + b1[0x1E];
out0[0x10* 1] = b1[0x1E] + b1[0x11];
b1[0x19] += b1[0x1D];
out1[0x10* 1] = b1[0x11] + b1[0x19];
out1[0x10* 3] = b1[0x19] + b1[0x15];
b1[0x1D] += b1[0x1B];
out1[0x10* 5] = b1[0x15] + b1[0x1D];
out1[0x10* 7] = b1[0x1D] + b1[0x13];
b1[0x1B] += b1[0x1F];
out1[0x10* 9] = b1[0x13] + b1[0x1B];
out1[0x10*11] = b1[0x1B] + b1[0x17];
out1[0x10*13] = b1[0x17] + b1[0x1F];
out1[0x10*15] = b1[0x1F];
}
/*
* the call via dct64 is a trick to force GCC to use
* (new) registers for the b1,b2 pointer to the bufs[xx] field
*/
void dct64( real *a,real *b,real *c)
{
real bufs[0x40];
dct64_1(a,b,bufs,bufs+0x20,c);
}

View File

@ -0,0 +1,36 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifndef MPGLIB_DCT64_I386_H_INCLUDED
#define MPGLIB_DCT64_I386_H_INCLUDED
#include "common.h"
void dct64( real *a,real *b,real *c);
#endif

View File

@ -0,0 +1,202 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* Mpeg Layer-1,2,3 audio decoder
* ------------------------------
* copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
* See also 'README'
*
* slighlty optimized for machines without autoincrement/decrement.
* The performance is highly compiler dependend. Maybe
* the decode.c version for 'normal' processor may be faster
* even for Intel processors.
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
//#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
//#else
/*# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
/*# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif*/
#if defined(__riscos__) && defined(FPA10)
#include "ymath.h"
#else
#include <math.h>
#endif
#include "decode_i386.h"
#include "dct64_i386.h"
#include "tabinit.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
/* old WRITE_SAMPLE */
#define WRITE_SAMPLE(samples,sum,clip) \
if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = (short)( ((sum)>0 ? (sum)+0.5 : (sum)-0.5) ); }
int synth_1to1_mono(PMPSTR mp, real *bandPtr,unsigned char *samples,int *pnt)
{
short samples_tmp[64];
short *tmp1 = samples_tmp;
int i,ret;
int pnt1 = 0;
ret = synth_1to1(mp,bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
samples += *pnt;
for(i=0;i<32;i++) {
*( (short *) samples) = *tmp1;
samples += 2;
tmp1 += 2;
}
*pnt += 64;
return ret;
}
int synth_1to1(PMPSTR mp, real *bandPtr,int channel,unsigned char *out,int *pnt)
{
static const int step = 2;
int bo;
short *samples = (short *) (out + *pnt);
real *b0,(*buf)[0x110];
int clip = 0;
int bo1;
bo = mp->synth_bo;
if(!channel) {
bo--;
bo &= 0xf;
buf = mp->synth_buffs[0];
}
else {
samples++;
buf = mp->synth_buffs[1];
}
if(bo & 0x1) {
b0 = buf[0];
bo1 = bo;
dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
}
else {
b0 = buf[1];
bo1 = bo+1;
dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
}
mp->synth_bo = bo;
{
register int j;
real *window = decwin + 16 - bo1;
for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
{
real sum;
sum = window[0x0] * b0[0x0];
sum -= window[0x1] * b0[0x1];
sum += window[0x2] * b0[0x2];
sum -= window[0x3] * b0[0x3];
sum += window[0x4] * b0[0x4];
sum -= window[0x5] * b0[0x5];
sum += window[0x6] * b0[0x6];
sum -= window[0x7] * b0[0x7];
sum += window[0x8] * b0[0x8];
sum -= window[0x9] * b0[0x9];
sum += window[0xA] * b0[0xA];
sum -= window[0xB] * b0[0xB];
sum += window[0xC] * b0[0xC];
sum -= window[0xD] * b0[0xD];
sum += window[0xE] * b0[0xE];
sum -= window[0xF] * b0[0xF];
WRITE_SAMPLE(samples,sum,clip);
}
{
real sum;
sum = window[0x0] * b0[0x0];
sum += window[0x2] * b0[0x2];
sum += window[0x4] * b0[0x4];
sum += window[0x6] * b0[0x6];
sum += window[0x8] * b0[0x8];
sum += window[0xA] * b0[0xA];
sum += window[0xC] * b0[0xC];
sum += window[0xE] * b0[0xE];
WRITE_SAMPLE(samples,sum,clip);
b0-=0x10,window-=0x20,samples+=step;
}
window += bo1<<1;
for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
{
real sum;
sum = -window[-0x1] * b0[0x0];
sum -= window[-0x2] * b0[0x1];
sum -= window[-0x3] * b0[0x2];
sum -= window[-0x4] * b0[0x3];
sum -= window[-0x5] * b0[0x4];
sum -= window[-0x6] * b0[0x5];
sum -= window[-0x7] * b0[0x6];
sum -= window[-0x8] * b0[0x7];
sum -= window[-0x9] * b0[0x8];
sum -= window[-0xA] * b0[0x9];
sum -= window[-0xB] * b0[0xA];
sum -= window[-0xC] * b0[0xB];
sum -= window[-0xD] * b0[0xC];
sum -= window[-0xE] * b0[0xD];
sum -= window[-0xF] * b0[0xE];
sum -= window[-0x0] * b0[0xF];
WRITE_SAMPLE(samples,sum,clip);
}
}
*pnt += 128;
return clip;
}

View File

@ -0,0 +1,36 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifndef DECODE_I386_H_INCLUDED
#define DECODE_I386_H_INCLUDED
#include "common.h"
int synth_1to1_mono(PMPSTR mp, real *bandPtr,unsigned char *samples,int *pnt);
int synth_1to1(PMPSTR mp, real *bandPtr,int channel,unsigned char *out,int *pnt);
#endif

View File

@ -0,0 +1,354 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* huffman tables ... recalcualted to work with my optimzed
* decoder scheme (MH)
*
* probably we could save a few bytes of memory, because the
* smaller tables are often the part of a bigger table
*/
struct newhuff
{
const unsigned int linbits;
const short * const table;
};
static const short tab0[] =
{
0
};
static const short tab1[] =
{
-5, -3, -1, 17, 1, 16, 0
};
static const short tab2[] =
{
-15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
16, 0
};
static const short tab3[] =
{
-13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
1, 0
};
static const short tab5[] =
{
-29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
0
};
static const short tab6[] =
{
-25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
0
};
static const short tab7[] =
{
-69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
-1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
-3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
-5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
};
static const short tab8[] =
{
-65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
-3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
};
static const short tab9[] =
{
-63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
-1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
-3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
};
static const short tab10[] =
{
-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
-1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
-17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
-1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
-3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
2, 32, 17, -1, 1, 16, 0
};
static const short tab11[] =
{
-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
-3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
-1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
-1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
-1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
-1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
32, 17, -3, -1, 1, 16, 0
};
static const short tab12[] =
{
-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
-1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
-1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
2, 32, 0, 17, -1, 1, 16
};
static const short tab13[] =
{
-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
-7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
-5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
-5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
-1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
-1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
-5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
-1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
-11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
-3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
-1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
-1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
-1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
-7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
-5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
-1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
0
};
static const short tab15[] =
{
-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
-1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
-1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
-3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
-3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
-3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
-3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
-1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
-1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
-5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
-1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
-7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
-5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
-1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
-1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
-13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
-3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
-3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
-3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
-1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
-5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
0
};
static const short tab16[] =
{
-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
-1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
-3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
-13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
-1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
-5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
-1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
-1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
-5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
-3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
-1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
-1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
-1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
-19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
-1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
-1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
-1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
-1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
-5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
-23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
-5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
0
};
static const short tab24[] =
{
-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
-5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
-1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
-1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
-1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
-5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
-1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
-1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
-3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
-1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
-1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
-1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
-1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
-3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
-7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
-7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
-1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
0
};
static const short tab_c0[] =
{
-29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
0
};
static const short tab_c1[] =
{
-15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
0
};
static const struct newhuff ht[] =
{
{ /* 0 */ 0 , tab0 } ,
{ /* 2 */ 0 , tab1 } ,
{ /* 3 */ 0 , tab2 } ,
{ /* 3 */ 0 , tab3 } ,
{ /* 0 */ 0 , tab0 } ,
{ /* 4 */ 0 , tab5 } ,
{ /* 4 */ 0 , tab6 } ,
{ /* 6 */ 0 , tab7 } ,
{ /* 6 */ 0 , tab8 } ,
{ /* 6 */ 0 , tab9 } ,
{ /* 8 */ 0 , tab10 } ,
{ /* 8 */ 0 , tab11 } ,
{ /* 8 */ 0 , tab12 } ,
{ /* 16 */ 0 , tab13 } ,
{ /* 0 */ 0 , tab0 } ,
{ /* 16 */ 0 , tab15 } ,
{ /* 16 */ 1 , tab16 } ,
{ /* 16 */ 2 , tab16 } ,
{ /* 16 */ 3 , tab16 } ,
{ /* 16 */ 4 , tab16 } ,
{ /* 16 */ 6 , tab16 } ,
{ /* 16 */ 8 , tab16 } ,
{ /* 16 */ 10, tab16 } ,
{ /* 16 */ 13, tab16 } ,
{ /* 16 */ 4 , tab24 } ,
{ /* 16 */ 5 , tab24 } ,
{ /* 16 */ 6 , tab24 } ,
{ /* 16 */ 7 , tab24 } ,
{ /* 16 */ 8 , tab24 } ,
{ /* 16 */ 9 , tab24 } ,
{ /* 16 */ 11, tab24 } ,
{ /* 16 */ 13, tab24 }
};
static const struct newhuff htc[] =
{
{ /* 1 , 1 , */ 0 , tab_c0 } ,
{ /* 1 , 1 , */ 0 , tab_c1 }
};

View File

@ -0,0 +1,666 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
//changes: 8/20/2002, Hauke Duden
// - fixed potential access violation in check_vbr_header and sync_buffer
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#include "interface.h"
#include "tabinit.h"
#include "layer3.h"
#include "VbrTag.h"
#ifdef USE_LAYER_1
#include "layer1.h"
#endif
#ifdef USE_LAYER_2
#include "layer2.h"
#endif
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
BOOL InitMP3( PMPSTR mp)
{
memset(mp,0,sizeof(MPSTR));
mp->framesize = 0;
mp->num_frames = 0;
mp->enc_delay = -1;
mp->enc_padding = -1;
mp->vbr_header=0;
mp->header_parsed=0;
mp->side_parsed=0;
mp->data_parsed=0;
mp->free_format=0;
mp->old_free_format=0;
mp->ssize = 0;
mp->dsize=0;
mp->fsizeold = -1;
mp->bsize = 0;
mp->head = mp->tail = NULL;
mp->fr.single = -1;
mp->bsnum = 0;
wordpointer = mp->bsspace[mp->bsnum] + 512;
mp->synth_bo = 1;
mp->sync_bitstream = 1;
make_decode_tables(32767);
init_layer3(SBLIMIT);
#ifdef USE_LAYER_2
init_layer2();
#endif
return !0;
}
void ExitMP3( PMPSTR mp)
{
struct buf *b,*bn;
b = mp->tail;
while(b) {
free(b->pnt);
bn = b->next;
free(b);
b = bn;
}
}
static struct buf *addbuf( PMPSTR mp, unsigned char *buf,int size)
{
struct buf *nbuf;
nbuf = (struct buf*) malloc( sizeof(struct buf) );
if(!nbuf) {
//fprintf(stderr,"Out of memory!\n");
return NULL;
}
nbuf->pnt = (unsigned char*) malloc((size_t)size);
if(!nbuf->pnt) {
free(nbuf);
return NULL;
}
nbuf->size = size;
memcpy(nbuf->pnt,buf,(size_t)size);
nbuf->next = NULL;
nbuf->prev = mp->head;
nbuf->pos = 0;
if(!mp->tail) {
mp->tail = nbuf;
}
else {
mp->head->next = nbuf;
}
mp->head = nbuf;
mp->bsize += size;
return nbuf;
}
void remove_buf(PMPSTR mp)
{
struct buf *buf = mp->tail;
mp->tail = buf->next;
if(mp->tail)
mp->tail->prev = NULL;
else {
mp->tail = mp->head = NULL;
}
free(buf->pnt);
free(buf);
}
static int read_buf_byte(PMPSTR mp)
{
unsigned int b;
int pos;
pos = mp->tail->pos;
while(pos >= mp->tail->size) {
remove_buf(mp);
//if(!mp->tail) {
//fprintf(stderr,"Fatal error! tried to read past mp buffer\n");
//exit(1);
//}
pos = mp->tail->pos;
}
b = mp->tail->pnt[pos];
mp->bsize--;
mp->tail->pos++;
return b;
}
static void read_head(PMPSTR mp)
{
unsigned long head;
head = read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
head <<= 8;
head |= read_buf_byte(mp);
mp->header = head;
}
void copy_mp(PMPSTR mp,int size,unsigned char *ptr)
{
int len = 0;
while(len < size) {
int nlen;
int blen = mp->tail->size - mp->tail->pos;
if( (size - len) <= blen) {
nlen = size-len;
}
else {
nlen = blen;
}
memcpy(ptr+len,mp->tail->pnt+mp->tail->pos,(size_t)nlen);
len += nlen;
mp->tail->pos += nlen;
mp->bsize -= nlen;
if(mp->tail->pos == mp->tail->size) {
remove_buf(mp);
}
}
}
// number of bytes needed by GetVbrTag to parse header
#define XING_HEADER_SIZE 194
// traverse mp data structure without changing it
// (just like sync_buffer)
// pull out Xing bytes
// call vbr header check code from LAME
// if we find a header, parse it and also compute the VBR header size
// if no header, do nothing.
//
// bytes = number of bytes before MPEG header. skip this many bytes
// before starting to read
// return value: number of bytes in VBR header, including syncword
int check_vbr_header(PMPSTR mp,int bytes)
{
int i,pos;
struct buf *buf=mp->tail;
unsigned char xing[XING_HEADER_SIZE];
VBRTAGDATA pTagData;
pos = buf->pos;
// skip to valid header
for (i=0; i<bytes; ++i) {
while(pos >= buf->size) {
buf = buf->next;
//fixed by Hauke Duden
//this has to be checked BEFORE accessing buf->pos
if(!buf) return -1; /* fatal error */
pos = buf->pos;
}
++pos;
}
// now read header
for (i=0; i<XING_HEADER_SIZE; ++i) {
while(pos >= buf->size)
{
buf = buf->next;
//fixed by Hauke Duden
//this has to be checked BEFORE accessing buf->pos
if(!buf) return -1; /* fatal error */
pos = buf->pos;
}
xing[i] = buf->pnt[pos];
++pos;
}
/* check first bytes for Xing header */
mp->vbr_header = GetVbrTag(&pTagData,xing);
if (mp->vbr_header) {
mp->num_frames=pTagData.frames;
mp->enc_delay=pTagData.enc_delay;
mp->enc_padding=pTagData.enc_padding;
//fprintf(stderr,"\rmpglib: delays: %i %i \n",mp->enc_delay,mp->enc_padding);
// fprintf(stderr,"\rmpglib: Xing VBR header dectected. MP3 file has %i frames\n", pTagData.frames);
return pTagData.headersize;
}
return 0;
}
int sync_buffer(PMPSTR mp,int free_match)
{
/* traverse mp structure without modifing pointers, looking
* for a frame valid header.
* if free_format, valid header must also have the same
* samplerate.
* return number of bytes in mp, before the header
* return -1 if header is not found
*/
unsigned int b[4]={0,0,0,0};
int i,h,pos;
struct buf *buf=mp->tail;
pos = buf->pos;
for (i=0; i<mp->bsize; i++)
{
/* get 4 bytes */
b[0]=b[1]; b[1]=b[2]; b[2]=b[3];
while(pos >= buf->size)
{
buf = buf->next;
//fixed by Hauke Duden
//this has to be checked BEFORE accessing buf->pos
if(!buf)
{
return -1;
/* not enough data to read 4 bytes */
}
pos = buf->pos;
}
b[3] = buf->pnt[pos];
++pos;
if (i>=3)
{
struct frame *fr = &mp->fr;
unsigned long head;
head = b[0];
head <<= 8;
head |= b[1];
head <<= 8;
head |= b[2];
head <<= 8;
head |= b[3];
h = head_check(head,fr->lay);
if (h && free_match)
{
/* just to be even more thorough, match the sample rate */
int mode,stereo,sampling_frequency,mpeg25,lsf;
if( head & (1<<20) )
{
lsf = (head & (1<<19)) ? 0x0 : 0x1;
mpeg25 = 0;
}
else
{
lsf = 1;
mpeg25 = 1;
}
mode = ((head>>6)&0x3);
stereo = (mode == MPG_MD_MONO) ? 1 : 2;
if(mpeg25)
sampling_frequency = 6 + ((head>>10)&0x3);
else
sampling_frequency = ((head>>10)&0x3) + (lsf*3);
h = ((stereo==fr->stereo) && (lsf==fr->lsf) && (mpeg25==fr->mpeg25) &&
(sampling_frequency == fr->sampling_frequency));
}
if (h)
return i-3;
}
}
return -1;
}
int decodeMP3( PMPSTR mp,unsigned char *in,int isize,char *out,
int osize,int *done)
{
int i,iret,bits,bytes;
if(osize < 4608)
{
//fprintf(stderr,"To less out space\n");
return MP3_ERR;
}
if(in!=NULL)
{
if(addbuf(mp,in,isize) == NULL)
return MP3_ERR;
}
/* First decode header */
if(!mp->header_parsed)
{
if (mp->fsizeold==-1 || mp->sync_bitstream)
{
int vbrbytes;
mp->sync_bitstream=0;
/* This is the very first call. sync with anything */
/* bytes= number of bytes before header */
bytes=sync_buffer(mp,0);
/* now look for Xing VBR header */
if (mp->bsize >= bytes+XING_HEADER_SIZE )
{
/* vbrbytes = number of bytes in entire vbr header */
vbrbytes=check_vbr_header(mp,bytes);
}
else
{
/* not enough data to look for Xing header */
//changed for DecMPA
//since DecMPA only passes in full frames and there is
//not enough data for a xing header, there is no Xing header.
if(mp->bsize==0)
return MP3_NEED_MORE; //no data at all, need next frame
else
{
//frame too small for xing header => no xing header
mp->vbr_header=0;
vbrbytes=0;
}
//return MP3_NEED_MORE;
}
if (mp->vbr_header)
{
/* do we have enough data to parse entire Xing header? */
if (bytes+vbrbytes > mp->bsize)
return MP3_NEED_MORE;
/* read in Xing header. Buffer data in case it
* is used by a non zero main_data_begin for the next
* frame, but otherwise dont decode Xing header */
/*fprintf(stderr,"found xing header, skipping %i bytes\n",vbrbytes+bytes);*/
for (i=0; i<vbrbytes+bytes; ++i)
read_buf_byte(mp);
/* now we need to find another syncword */
/* just return and make user send in more data */
return MP3_NEED_MORE;
}
}
else
{
/* match channels, samplerate, etc, when syncing */
bytes=sync_buffer(mp,1);
}
if (bytes<0)
return MP3_NEED_MORE;
if (bytes>0)
{
/* there were some extra bytes in front of header.
* bitstream problem, but we are now resynced
* should try to buffer previous data in case new
* frame has nonzero main_data_begin, but we need
* to make sure we do not overflow buffer
*/
int size;
//fprintf(stderr,"bitstream problem: resyncing...\n");
mp->old_free_format=0;
mp->sync_bitstream=1;
/* skip some bytes, buffer the rest */
size = (int) (wordpointer - (mp->bsspace[mp->bsnum]+512));
if (size > MAXFRAMESIZE)
{
/* wordpointer buffer is trashed. probably cant recover, but try anyway */
//fprintf(stderr,"mpglib: wordpointer trashed. size=%i (%i) bytes=%i \n",
//size,MAXFRAMESIZE,bytes);
size=0;
wordpointer = mp->bsspace[mp->bsnum]+512;
}
/* buffer contains 'size' data right now
we want to add 'bytes' worth of data, but do not
exceed MAXFRAMESIZE, so we through away 'i' bytes */
i = (size+bytes)-MAXFRAMESIZE;
for (; i>0; --i)
{
--bytes;
read_buf_byte(mp);
}
copy_mp(mp,bytes,wordpointer);
mp->fsizeold += bytes;
}
read_head(mp);
decode_header(&mp->fr,mp->header);
mp->header_parsed=1;
mp->framesize = mp->fr.framesize;
mp->free_format = (mp->framesize==0);
if(mp->fr.lsf)
mp->ssize = (mp->fr.stereo == 1) ? 9 : 17;
else
mp->ssize = (mp->fr.stereo == 1) ? 17 : 32;
if (mp->fr.error_protection)
mp->ssize += 2;
mp->bsnum = 1-mp->bsnum; /* toggle buffer */
wordpointer = mp->bsspace[mp->bsnum] + 512;
bitindex = 0;
/* for very first header, never parse rest of data */
//Hauke Duden: why? header_parsed is 1 so continuing here is the same
//as returning and then being called again with no new data (or not
//enough new data)
//=> removed
//if (mp->fsizeold==-1)
//return MP3_NEED_MORE;
}
/* now decode side information */
if (!mp->side_parsed)
{
/* Layer 3 only */
if (mp->fr.lay==3)
{
if (mp->bsize < mp->ssize)
return MP3_NEED_MORE;
copy_mp(mp,mp->ssize,wordpointer);
if(mp->fr.error_protection)
getbits(16);
bits=do_layer3_sideinfo(&mp->fr);
/* bits = actual number of bits needed to parse this frame */
/* can be negative, if all bits needed are in the reservoir */
if (bits<0)
bits=0;
/* read just as many bytes as necessary before decoding */
mp->dsize = (bits+7)/8;
/* this will force mpglib to read entire frame before decoding */
/* mp->dsize= mp->framesize - mp->ssize;*/
}
else
{
/* Layers 1 and 2 */
/* check if there is enough input data */
if(mp->fr.framesize > mp->bsize)
return MP3_NEED_MORE;
/* takes care that the right amount of data is copied into wordpointer */
mp->dsize=mp->fr.framesize;
mp->ssize=0;
}
mp->side_parsed=1;
}
/* now decode main data */
iret=MP3_NEED_MORE;
if (!mp->data_parsed )
{
if(mp->dsize > mp->bsize)
return MP3_NEED_MORE;
copy_mp(mp,mp->dsize,wordpointer);
*done = 0;
//do_layer3(&mp->fr,(unsigned char *) out,done);
switch (mp->fr.lay)
{
#ifdef USE_LAYER_1
case 1:
if(mp->fr.error_protection)
getbits(16);
do_layer1(mp,(unsigned char *) out,done);
break;
#endif
#ifdef USE_LAYER_2
case 2:
if(mp->fr.error_protection)
getbits(16);
do_layer2(mp,(unsigned char *) out,done);
break;
#endif
case 3:
do_layer3(mp,(unsigned char *) out,done);
break;
default:
//fprintf(stderr,"invalid layer %d\n",mp->fr.lay);
break;
}
wordpointer = mp->bsspace[mp->bsnum] + 512 + mp->ssize + mp->dsize;
mp->data_parsed=1;
iret=MP3_OK;
}
/* remaining bits are ancillary data, or reservoir for next frame
* If free format, scan stream looking for next frame to determine
* mp->framesize */
if (mp->free_format)
{
if (mp->old_free_format)
{
/* free format. bitrate must not vary */
mp->framesize=mp->fsizeold_nopadding + (mp->fr.padding);
}
else
{
bytes=sync_buffer(mp,1);
if (bytes<0)
return iret;
mp->framesize = bytes + mp->ssize+mp->dsize;
mp->fsizeold_nopadding= mp->framesize - mp->fr.padding;
/*
fprintf(stderr,"freeformat bitstream: estimated bitrate=%ikbs \n",
8*(4+mp->framesize)*freqs[mp->fr.sampling_frequency]/
(1000*576*(2-mp->fr.lsf)));
*/
}
}
/* buffer the ancillary data and reservoir for next frame */
bytes = mp->framesize-(mp->ssize+mp->dsize);
if (bytes > mp->bsize)
return iret;
if (bytes>0)
{
int size;
copy_mp(mp,bytes,wordpointer);
wordpointer += bytes;
size = (int) (wordpointer - (mp->bsspace[mp->bsnum]+512));
if (size > MAXFRAMESIZE)
{
//fprintf(stderr,"fatal error. MAXFRAMESIZE not large enough.\n");
}
}
/* the above frame is completey parsed. start looking for next frame */
mp->fsizeold = mp->framesize;
mp->old_free_format = mp->free_format;
mp->framesize =0;
mp->header_parsed=0;
mp->side_parsed=0;
mp->data_parsed=0;
return iret;
}

View File

@ -0,0 +1,47 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifndef INTERFACE_H_INCLUDED
#define INTERFACE_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "common.h"
BOOL InitMP3(PMPSTR mp);
int decodeMP3(PMPSTR mp,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done);
void ExitMP3(PMPSTR mp);
/* added remove_buf to support mpglib seeking */
void remove_buf(PMPSTR mp);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,177 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* Layer 2 Alloc tables ..
* most other tables are calculated on program start (which is (of course)
* not ISO-conform) ..
* Layer-3 huffman table is in huffman.h
*/
const struct al_table2 alloc_0[] = {
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767} };
const struct al_table2 alloc_1[] = {
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767} };
const struct al_table2 alloc_2[] = {
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
const struct al_table2 alloc_3[] = {
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
const struct al_table2 alloc_4[] = {
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9},
{2,0},{5,3},{7,5},{10,9} };

View File

@ -0,0 +1,194 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* Mpeg Layer-1 audio decoder
* --------------------------
* copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
* near unoptimzed ...
*
* may have a few bugs after last optimization ...
*
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "HIPDefines.h"
#ifdef USE_LAYER_1
#include <assert.h>
#include "common.h"
#include "decode_i386.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
{
unsigned int *ba=balloc;
unsigned int *sca = (unsigned int *) scale_index;
assert ( fr->stereo == 0 || fr->stereo == 1 );
if(fr->stereo) {
int i;
int jsbound = fr->jsbound;
for (i=0;i<jsbound;i++) {
*ba++ = getbits(4);
*ba++ = getbits(4);
}
for (i=jsbound;i<SBLIMIT;i++)
*ba++ = getbits(4);
ba = balloc;
for (i=0;i<jsbound;i++) {
if ((*ba++))
*sca++ = getbits(6);
if ((*ba++))
*sca++ = getbits(6);
}
for (i=jsbound;i<SBLIMIT;i++)
if ((*ba++)) {
*sca++ = getbits(6);
*sca++ = getbits(6);
}
}
else {
int i;
for (i=0;i<SBLIMIT;i++)
*ba++ = getbits(4);
ba = balloc;
for (i=0;i<SBLIMIT;i++)
if ((*ba++))
*sca++ = getbits(6);
}
}
void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
unsigned int scale_index[2][SBLIMIT],struct frame *fr)
{
int i,n;
int smpb[2*SBLIMIT]; /* values: 0-65535 */
int *sample;
register unsigned int *ba;
register unsigned int *sca = (unsigned int *) scale_index;
assert ( fr->stereo == 0 || fr->stereo == 1 );
if(fr->stereo) {
int jsbound = fr->jsbound;
register real *f0 = fraction[0];
register real *f1 = fraction[1];
ba = balloc;
for (sample=smpb,i=0;i<jsbound;i++) {
if ((n = *ba++))
*sample++ = getbits(n+1);
if ((n = *ba++))
*sample++ = getbits(n+1);
}
for (i=jsbound;i<SBLIMIT;i++)
if ((n = *ba++))
*sample++ = getbits(n+1);
ba = balloc;
for (sample=smpb,i=0;i<jsbound;i++) {
if((n=*ba++))
*f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
else
*f0++ = 0.0;
if((n=*ba++))
*f1++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
else
*f1++ = 0.0;
}
for (i=jsbound;i<SBLIMIT;i++) {
if ((n=*ba++)) {
real samp = (real)( ((-1)<<n) + (*sample++) + 1);
*f0++ = samp * muls[n+1][*sca++];
*f1++ = samp * muls[n+1][*sca++];
}
else
*f0++ = *f1++ = 0.0;
}
for(i=fr->down_sample_sblimit;i<32;i++)
fraction[0][i] = fraction[1][i] = 0.0;
}
else {
register real *f0 = fraction[0];
ba = balloc;
for (sample=smpb,i=0;i<SBLIMIT;i++)
if ((n = *ba++))
*sample++ = getbits(n+1);
ba = balloc;
for (sample=smpb,i=0;i<SBLIMIT;i++) {
if((n=*ba++))
*f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
else
*f0++ = 0.0;
}
for(i=fr->down_sample_sblimit;i<32;i++)
fraction[0][i] = 0.0;
}
}
//int do_layer1(struct frame *fr,int outmode,struct audio_info_struct *ai)
int do_layer1(PMPSTR mp, unsigned char *pcm_sample,int *pcm_point)
{
int clip=0;
unsigned int balloc[2*SBLIMIT];
unsigned int scale_index[2][SBLIMIT];
real fraction[2][SBLIMIT];
struct frame *fr=&(mp->fr);
int i,stereo = fr->stereo;
int single = fr->single;
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
if(stereo == 1 || single == 3)
single = 0;
I_step_one(balloc,scale_index,fr);
for (i=0;i<SCALE_BLOCK;i++)
{
I_step_two(fraction,balloc,scale_index,fr);
if(single >= 0)
{
clip += synth_1to1_mono( mp, (real *) fraction[single],pcm_sample,pcm_point);
}
else {
int p1 = *pcm_point;
clip += synth_1to1( mp, (real *) fraction[0],0,pcm_sample,&p1);
clip += synth_1to1( mp, (real *) fraction[1],1,pcm_sample,pcm_point);
}
}
return clip;
}
#endif

View File

@ -0,0 +1,33 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifndef LAYER1_H_INCLUDED
#define LAYER1_H_INCLUDED
int do_layer1(PMPSTR mp, unsigned char *pcm_sample,int *pcm_point);
#endif

View File

@ -0,0 +1,333 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
* Mpeg Layer-2 audio decoder
* --------------------------
* copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
*
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "HIPDefines.h"
#ifdef USE_LAYER_2
#include "common.h"
#include "layer2.h"
#include "l2tables.h"
#include "decode_i386.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */
static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */
static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
void init_layer2(void)
{
static const double mulmul[27] = {
0.0 , -2.0/3.0 , 2.0/3.0 ,
2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 ,
2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 ,
2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 ,
-4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 ,
-8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 };
static const int base[3][9] = {
{ 1 , 0, 2 , } ,
{ 17, 18, 0 , 19, 20 , } ,
{ 21, 1, 22, 23, 0, 24, 25, 2, 26 } };
int i,j,k,l,len;
real *table;
static const int tablen[3] = { 3 , 5 , 9 };
static int *itable,*tables[3] = { grp_3tab , grp_5tab , grp_9tab };
for(i=0;i<3;i++)
{
itable = tables[i];
len = tablen[i];
for(j=0;j<len;j++)
for(k=0;k<len;k++)
for(l=0;l<len;l++)
{
*itable++ = base[i][l];
*itable++ = base[i][k];
*itable++ = base[i][j];
}
}
for(k=0;k<27;k++)
{
double m=mulmul[k];
table = muls[k];
for(j=3,i=0;i<63;i++,j--)
*table++ = (real)(m * pow(2.0,(double) j / 3.0));
*table++ = 0.0;
}
}
void II_step_one(unsigned int *bit_alloc,int *scale,struct frame *fr)
{
int stereo = fr->stereo-1;
int sblimit = fr->II_sblimit;
int jsbound = fr->jsbound;
int sblimit2 = fr->II_sblimit<<stereo;
struct al_table2 *alloc1 = fr->alloc;
int i;
static unsigned int scfsi_buf[64];
unsigned int *scfsi,*bita;
int sc,step;
bita = bit_alloc;
if(stereo)
{
for (i=jsbound;i;i--,alloc1+=(1<<step))
{
*bita++ = (char) getbits(step=alloc1->bits);
*bita++ = (char) getbits(step);
}
for (i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
{
bita[0] = (char) getbits(step=alloc1->bits);
bita[1] = bita[0];
bita+=2;
}
bita = bit_alloc;
scfsi=scfsi_buf;
for (i=sblimit2;i;i--)
if (*bita++)
*scfsi++ = (char) getbits_fast(2);
}
else /* mono */
{
for (i=sblimit;i;i--,alloc1+=(1<<step))
*bita++ = (char) getbits(step=alloc1->bits);
bita = bit_alloc;
scfsi=scfsi_buf;
for (i=sblimit;i;i--)
if (*bita++)
*scfsi++ = (char) getbits_fast(2);
}
bita = bit_alloc;
scfsi=scfsi_buf;
for (i=sblimit2;i;i--)
if (*bita++)
switch (*scfsi++)
{
case 0:
*scale++ = getbits_fast(6);
*scale++ = getbits_fast(6);
*scale++ = getbits_fast(6);
break;
case 1 :
*scale++ = sc = getbits_fast(6);
*scale++ = sc;
*scale++ = getbits_fast(6);
break;
case 2:
*scale++ = sc = getbits_fast(6);
*scale++ = sc;
*scale++ = sc;
break;
default: /* case 3 */
*scale++ = getbits_fast(6);
*scale++ = sc = getbits_fast(6);
*scale++ = sc;
break;
}
}
void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1)
{
int i,j,k,ba;
int stereo = fr->stereo;
int sblimit = fr->II_sblimit;
int jsbound = fr->jsbound;
struct al_table2 *alloc2,*alloc1 = fr->alloc;
unsigned int *bita=bit_alloc;
int d1,step;
for (i=0;i<jsbound;i++,alloc1+=(1<<step))
{
step = alloc1->bits;
for (j=0;j<stereo;j++)
{
if ( (ba=*bita++) )
{
k=(alloc2 = alloc1+ba)->bits;
if( (d1=alloc2->d) < 0)
{
real cm=muls[k][scale[x1]];
fraction[j][0][i] = ((real) ((int)getbits(k) + d1)) * cm;
fraction[j][1][i] = ((real) ((int)getbits(k) + d1)) * cm;
fraction[j][2][i] = ((real) ((int)getbits(k) + d1)) * cm;
}
else
{
static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
unsigned int idx,*tab,m=scale[x1];
idx = (unsigned int) getbits(k);
tab = (unsigned int *) (table[d1] + idx + idx + idx);
fraction[j][0][i] = muls[*tab++][m];
fraction[j][1][i] = muls[*tab++][m];
fraction[j][2][i] = muls[*tab][m];
}
scale+=3;
}
else
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
}
}
for (i=jsbound;i<sblimit;i++,alloc1+=(1<<step))
{
step = alloc1->bits;
bita++; /* channel 1 and channel 2 bitalloc are the same */
if ( (ba=*bita++) )
{
k=(alloc2 = alloc1+ba)->bits;
if( (d1=alloc2->d) < 0)
{
real cm;
cm=muls[k][scale[x1+3]];
fraction[1][0][i] = (fraction[0][0][i] = (real) ((int)getbits(k) + d1) ) * cm;
fraction[1][1][i] = (fraction[0][1][i] = (real) ((int)getbits(k) + d1) ) * cm;
fraction[1][2][i] = (fraction[0][2][i] = (real) ((int)getbits(k) + d1) ) * cm;
cm=muls[k][scale[x1]];
fraction[0][0][i] *= cm; fraction[0][1][i] *= cm; fraction[0][2][i] *= cm;
}
else
{
static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
unsigned int idx,*tab,m1,m2;
m1 = scale[x1]; m2 = scale[x1+3];
idx = (unsigned int) getbits(k);
tab = (unsigned int *) (table[d1] + idx + idx + idx);
fraction[0][0][i] = muls[*tab][m1]; fraction[1][0][i] = muls[*tab++][m2];
fraction[0][1][i] = muls[*tab][m1]; fraction[1][1][i] = muls[*tab++][m2];
fraction[0][2][i] = muls[*tab][m1]; fraction[1][2][i] = muls[*tab][m2];
}
scale+=6;
}
else {
fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] =
fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0;
}
/*
should we use individual scalefac for channel 2 or
is the current way the right one , where we just copy channel 1 to
channel 2 ??
The current 'strange' thing is, that we throw away the scalefac
values for the second channel ...!!
-> changed .. now we use the scalefac values of channel one !!
*/
}
// if(sblimit > (fr->down_sample_sblimit) )
// sblimit = fr->down_sample_sblimit;
for(i=sblimit;i<SBLIMIT;i++)
for (j=0;j<stereo;j++)
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
}
static void II_select_table(struct frame *fr)
{
static const int translate[3][2][16] =
{ { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,
{ 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,
{ { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,
{ 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,
{ { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,
{ 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } };
int table,sblim;
static const struct al_table2 *tables[5] =
{ alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
static const int sblims[5] = { 27 , 30 , 8, 12 , 30 };
if(fr->lsf)
table = 4;
else
table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
sblim = sblims[table];
fr->alloc = (struct al_table2*)tables[table];
fr->II_sblimit = sblim;
}
int do_layer2( PMPSTR mp,unsigned char *pcm_sample,int *pcm_point)
//int do_layer2(struct frame *fr,int outmode,struct audio_info_struct *ai)
{
int clip=0;
int i,j;
real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
unsigned int bit_alloc[64];
int scale[192];
struct frame *fr=&(mp->fr);
int stereo = fr->stereo;
int single = fr->single;
II_select_table(fr);
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
(fr->mode_ext<<2)+4 : fr->II_sblimit;
if(stereo == 1 || single == 3)
single = 0;
II_step_one(bit_alloc, scale, fr);
for (i=0;i<SCALE_BLOCK;i++)
{
II_step_two(bit_alloc,fraction,scale,fr,i>>2);
for (j=0;j<3;j++)
{
if(single >= 0)
{
clip += synth_1to1_mono(mp, fraction[single][j],pcm_sample,pcm_point);
}
else {
int p1 = *pcm_point;
clip += synth_1to1(mp, fraction[0][j],0,pcm_sample,&p1);
clip += synth_1to1(mp, fraction[1][j],1,pcm_sample,pcm_point);
}
}
}
return clip;
}
#endif

View File

@ -0,0 +1,49 @@
/* DecMPA decoding routines from Lame/HIP (Myers W. Carpenter)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
/*
** Copyright (C) 2000 Albert L. Faber
**/
#ifdef USE_LAYER_2
#ifndef LAYER2_H_INCLUDED
#define LAYER2_H_INCLUDED
struct al_table2
{
short bits;
short d;
};
void init_layer2(void);
void II_step_one(unsigned int *bit_alloc,int *scale,struct frame *fr);
void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1);
int do_layer2( PMPSTR mp,unsigned char *pcm_sample,int *pcm_point);
#endif
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More