Initial revision
commit
655c5d7093
|
@ -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
|
|
@ -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
|
|
@ -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.
|
|
@ -0,0 +1,3 @@
|
|||
Awesomized id3v2 and tagging support courtesy of TagLib.
|
||||
Dramatically improved performance of monkeys audio codec.
|
||||
minor bug fixes.
|
|
@ -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<Double></string>
|
||||
</dict>
|
||||
<key>bitRate</key>
|
||||
<dict>
|
||||
<key>AppleEventCode</key>
|
||||
<string>CoBi</string>
|
||||
<key>ReadOnly</key>
|
||||
<string>YES</string>
|
||||
<key>Type</key>
|
||||
<string>NSNumber<Int></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>
|
|
@ -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>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
}
|
|
@ -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.
|
@ -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;
|
||||
}
|
|
@ -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.
|
@ -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;
|
||||
}
|
|
@ -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.
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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>
|
Binary file not shown.
|
@ -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
|
@ -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.
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
- Test on other operating systems
|
||||
|
||||
- clean the code up a little more
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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>
|
||||
|
|
@ -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
|
|
@ -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];
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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;*/
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _HIPDEFINES_H_
|
||||
#define _HIPDEFINES_H_
|
||||
|
||||
#define NOANALYSIS
|
||||
#define USE_LAYER_1
|
||||
#define USE_LAYER_2
|
||||
|
||||
#define MPEG1
|
||||
|
||||
#endif
|
|
@ -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 */
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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} };
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue