From 1a251073489775190b45c21ca53a6a28954458e9 Mon Sep 17 00:00:00 2001 From: chudov Date: Thu, 15 Jan 2009 23:15:04 +0000 Subject: [PATCH] can be of use later --- ttalib-1.1/BitReader.h | 199 ++++++++++++++ ttalib-1.1/BitWriter.h | 204 ++++++++++++++ ttalib-1.1/COPYING | 281 +++++++++++++++++++ ttalib-1.1/ReadMe.txt | 276 +++++++++++++++++++ ttalib-1.1/Stdafx.cpp | 5 + ttalib-1.1/Stdafx.h | 8 + ttalib-1.1/TTAError.h | 67 +++++ ttalib-1.1/TTALib.cpp | 564 +++++++++++++++++++++++++++++++++++++++ ttalib-1.1/TTALib.h | 125 +++++++++ ttalib-1.1/TTALib.vcproj | 406 ++++++++++++++++++++++++++++ ttalib-1.1/TTAReader.cpp | 175 ++++++++++++ ttalib-1.1/TTAReader.h | 63 +++++ ttalib-1.1/TTATester.h | 69 +++++ ttalib-1.1/TTAWriter.cpp | 203 ++++++++++++++ ttalib-1.1/TTAWriter.h | 62 +++++ ttalib-1.1/WavFile.cpp | 266 ++++++++++++++++++ ttalib-1.1/WavFile.h | 86 ++++++ ttalib-1.1/crc32.h | 114 ++++++++ ttalib-1.1/filters3.h | 115 ++++++++ ttalib-1.1/ttacommon.h | 147 ++++++++++ 20 files changed, 3435 insertions(+) create mode 100644 ttalib-1.1/BitReader.h create mode 100644 ttalib-1.1/BitWriter.h create mode 100644 ttalib-1.1/COPYING create mode 100644 ttalib-1.1/ReadMe.txt create mode 100644 ttalib-1.1/Stdafx.cpp create mode 100644 ttalib-1.1/Stdafx.h create mode 100644 ttalib-1.1/TTAError.h create mode 100644 ttalib-1.1/TTALib.cpp create mode 100644 ttalib-1.1/TTALib.h create mode 100644 ttalib-1.1/TTALib.vcproj create mode 100644 ttalib-1.1/TTAReader.cpp create mode 100644 ttalib-1.1/TTAReader.h create mode 100644 ttalib-1.1/TTATester.h create mode 100644 ttalib-1.1/TTAWriter.cpp create mode 100644 ttalib-1.1/TTAWriter.h create mode 100644 ttalib-1.1/WavFile.cpp create mode 100644 ttalib-1.1/WavFile.h create mode 100644 ttalib-1.1/crc32.h create mode 100644 ttalib-1.1/filters3.h create mode 100644 ttalib-1.1/ttacommon.h diff --git a/ttalib-1.1/BitReader.h b/ttalib-1.1/BitReader.h new file mode 100644 index 0000000..1125b85 --- /dev/null +++ b/ttalib-1.1/BitReader.h @@ -0,0 +1,199 @@ +/* + * BitReader.h + * + * Description: Bit reader internal interface + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once +#include +#include "TTACommon.h" +#include "TTAError.h" +#include "crc32.h" + +namespace TTALib +{ + class BitReader + { + protected: + HANDLE hInFile; + + unsigned char bit_buffer[BIT_BUFFER_SIZE + 8]; + unsigned char *bit_buffer_end; + + unsigned long frame_crc32; + unsigned long bit_count; + unsigned long bit_cache; + unsigned char *bitpos; + + unsigned long *st; + unsigned long next_frame_pos; + + public: + BitReader(HANDLE fd) : + frame_crc32(0xFFFFFFFFUL), hInFile (fd), + bit_count(0), bit_cache(0), bit_buffer_end(bit_buffer + BIT_BUFFER_SIZE), + bitpos(bit_buffer_end), input_byte_count (0) + { + } + + virtual ~BitReader(void) {} + + virtual void GetHeader (TTAHeader *ttahdr) + { + unsigned long result, checksum; + + if (!ReadFile(hInFile, ttahdr, sizeof(TTAHeader), &result, NULL) || + result != sizeof (TTAHeader)) + { + throw TTAException (READ_ERROR); + } else input_byte_count += sizeof(*ttahdr); + + // check for supported formats + if (ENDSWAP_INT32(ttahdr->TTAid) != TTA1_SIGN) + throw TTAException (FORMAT_ERROR); + + checksum = crc32((unsigned char *) ttahdr, sizeof(TTAHeader) - sizeof(long)); + if (checksum != ttahdr->CRC32) + throw TTAException (FILE_ERROR); + + ttahdr->AudioFormat = ENDSWAP_INT16(ttahdr->AudioFormat); + ttahdr->NumChannels = ENDSWAP_INT16(ttahdr->NumChannels); + ttahdr->BitsPerSample = ENDSWAP_INT16(ttahdr->BitsPerSample); + ttahdr->SampleRate = ENDSWAP_INT32(ttahdr->SampleRate); + ttahdr->DataLength = ENDSWAP_INT32(ttahdr->DataLength); + } + + virtual bool GetSeekTable (unsigned long *seek_table, long st_size) + { + unsigned long result, checksum; + bool st_state = false; + + if (!ReadFile(hInFile, seek_table, st_size * sizeof(long), &result, NULL) || + result != st_size * sizeof(long)) + throw TTAException (READ_ERROR); + else input_byte_count += st_size * sizeof(long); + + checksum = crc32((unsigned char *) seek_table, (st_size - 1) * sizeof(long)); + if (checksum == ENDSWAP_INT32(seek_table[st_size - 1])) + st_state = true; + + for (st = seek_table; st < (seek_table + st_size); st++) + *st = ENDSWAP_INT32(*st); + + next_frame_pos = SetFilePointer (hInFile, 0, NULL, FILE_CURRENT); + st = seek_table; + + return st_state; + } + + virtual void GetBinary(unsigned long *value, unsigned long bits) { + while (bit_count < bits) { + if (bitpos == bit_buffer_end) { + unsigned long result; + if (!ReadFile (hInFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL)) + throw TTAException (READ_ERROR); + input_byte_count += result; + bitpos = bit_buffer; + } + + UPDATE_CRC32(*bitpos, frame_crc32); + bit_cache |= *bitpos << bit_count; + bit_count += 8; + bitpos++; + } + + *value = bit_cache & bit_mask[bits]; + bit_cache >>= bits; + bit_count -= bits; + bit_cache &= bit_mask[bit_count]; + } + + virtual void GetUnary(unsigned long *value) + { + *value = 0; + + while (!(bit_cache ^ bit_mask[bit_count])) { + if (bitpos == bit_buffer_end) { + unsigned long result; + if (!ReadFile (hInFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL)) + throw TTAException (READ_ERROR); + input_byte_count += result; + bitpos = bit_buffer; + } + + *value += bit_count; + bit_cache = *bitpos++; + UPDATE_CRC32(bit_cache, frame_crc32); + bit_count = 8; + } + + while (bit_cache & 1) { + (*value)++; + bit_cache >>= 1; + bit_count--; + } + + bit_cache >>= 1; + bit_count--; + } + + virtual int Done () + { + unsigned long crc32, rbytes, result; + frame_crc32 ^= 0xFFFFFFFFUL; + + next_frame_pos += *st++; + + rbytes = bit_buffer_end - bitpos; + if (rbytes < sizeof(long)) { + CopyMemory(bit_buffer, bitpos, 4); + if (!ReadFile(hInFile, bit_buffer + rbytes, + BIT_BUFFER_SIZE - rbytes, &result, NULL)) + throw TTAException (READ_ERROR); + input_byte_count += result; + bitpos = bit_buffer; + } + + CopyMemory(&crc32, bitpos, 4); + crc32 = ENDSWAP_INT32(crc32); + bitpos += sizeof(long); + result = (crc32 != frame_crc32); + + bit_cache = bit_count = 0; + frame_crc32 = 0xFFFFFFFFUL; + + return result; + } + + virtual void SkipFrame () + { + SetFilePointer(hInFile, next_frame_pos, NULL, FILE_BEGIN); + bitpos = bit_buffer_end; + } + + unsigned long input_byte_count; + }; +}; diff --git a/ttalib-1.1/BitWriter.h b/ttalib-1.1/BitWriter.h new file mode 100644 index 0000000..a62ed4f --- /dev/null +++ b/ttalib-1.1/BitWriter.h @@ -0,0 +1,204 @@ +/* + * BitWriter.h + * + * Description: Bit writer internal interface + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once +#include +#include "TTACommon.h" +#include "TTAError.h" +#include "crc32.h" + +namespace TTALib +{ + class BitWriter + { + protected: + HANDLE hOutFile; + unsigned long start_offset; + + unsigned char bit_buffer[BIT_BUFFER_SIZE + 8]; + unsigned char *bit_buffer_end; + unsigned long frame_crc32; + unsigned long bit_count; + unsigned long bit_cache; + unsigned char *bitpos; + unsigned long lastpos; + + public: + unsigned long output_byte_count; + + BitWriter(HANDLE fd, unsigned long offset) : + frame_crc32(0xFFFFFFFFUL), + start_offset(offset), hOutFile (fd), + bit_count(0), bit_cache(0), + bitpos (bit_buffer), lastpos (0), output_byte_count (0), + bit_buffer_end (bit_buffer + BIT_BUFFER_SIZE) + { + SetFilePointer (hOutFile, start_offset, NULL, FILE_BEGIN); + } + + virtual ~BitWriter(void) {} + + virtual void PutHeader (TTAHeader ttahdr) + { + unsigned long result; + + ttahdr.TTAid = ENDSWAP_INT32(TTA1_SIGN); + ttahdr.AudioFormat = ENDSWAP_INT16(ttahdr.AudioFormat); + ttahdr.NumChannels = ENDSWAP_INT16(ttahdr.NumChannels); + ttahdr.BitsPerSample = ENDSWAP_INT16(ttahdr.BitsPerSample); + ttahdr.SampleRate = ENDSWAP_INT32(ttahdr.SampleRate); + ttahdr.DataLength = ENDSWAP_INT32(ttahdr.DataLength); + ttahdr.CRC32 = crc32((unsigned char *) &ttahdr, + sizeof(TTAHeader) - sizeof(long)); + ttahdr.CRC32 = ENDSWAP_INT32(ttahdr.CRC32); + + // write TTA header + if (!WriteFile(hOutFile, &ttahdr, sizeof(TTAHeader), &result, NULL) || + result != sizeof (TTAHeader)) + { + CloseHandle (hOutFile); + throw TTAException (WRITE_ERROR); + } + + lastpos = (output_byte_count += sizeof(TTAHeader)); + } + + virtual void PutSeekTable (unsigned long *seek_table, long st_size) + { + unsigned long result; + unsigned long *st; + + if (SetFilePointer (hOutFile, 0, NULL, FILE_CURRENT) != start_offset + sizeof(TTAHeader)) + SetFilePointer (hOutFile, start_offset + sizeof(TTAHeader), NULL, FILE_BEGIN); + else + lastpos = (output_byte_count += st_size * sizeof(long)); + + for (st = seek_table; st < (seek_table + st_size - 1); st++) + *st = ENDSWAP_INT32(*st); + seek_table[st_size - 1] = crc32((unsigned char *) seek_table, + (st_size - 1) * sizeof(long)); + seek_table[st_size - 1] = ENDSWAP_INT32(seek_table[st_size - 1]); + + if (!WriteFile(hOutFile, seek_table, st_size * sizeof(long), &result, NULL) || + result != st_size * sizeof(long)) + { + CloseHandle (hOutFile); + throw TTAException (WRITE_ERROR); + } + } + + virtual void PutBinary(unsigned long value, unsigned long bits) + { + while (bit_count >= 8) { + if (bitpos == bit_buffer_end) { + unsigned long result; + if (!WriteFile (hOutFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL) || + result != BIT_BUFFER_SIZE) + throw TTAException (WRITE_ERROR); + + output_byte_count += result; + bitpos = bit_buffer; + } + + *bitpos = (unsigned char) (bit_cache & 0xFF); + UPDATE_CRC32(*bitpos, frame_crc32); + bit_cache >>= 8; + bit_count -= 8; + bitpos++; + } + + bit_cache |= (value & bit_mask[bits]) << bit_count; + bit_count += bits; + } + + virtual void PutUnary(unsigned long value) + { + do { + while (bit_count >= 8) { + if (bitpos == bit_buffer_end) { + unsigned long result; + if (!WriteFile (hOutFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL) || + result != BIT_BUFFER_SIZE) + throw TTAException (WRITE_ERROR); + + output_byte_count += result; + bitpos = bit_buffer; + } + + *bitpos = (unsigned char) (bit_cache & 0xFF); + UPDATE_CRC32(*bitpos, frame_crc32); + bit_cache >>= 8; + bit_count -= 8; + bitpos++; + } + + if (value > 23) { + bit_cache |= bit_mask[23] << bit_count; + bit_count += 23; + value -= 23; + } else { + bit_cache |= bit_mask[value] << bit_count; + bit_count += value + 1; + value = 0; + } + } while (value); + } + + virtual int Done() + { + unsigned long res, bytes_to_write; + + while (bit_count) { + *bitpos = (unsigned char) (bit_cache & 0xFF); + UPDATE_CRC32(*bitpos, frame_crc32); + bit_cache >>= 8; + bit_count = (bit_count > 8) ? (bit_count - 8) : 0; + bitpos++; + } + + frame_crc32 ^= 0xFFFFFFFFUL; + frame_crc32 = ENDSWAP_INT32(frame_crc32); + CopyMemory(bitpos, &frame_crc32, 4); + bytes_to_write = bitpos + sizeof(long) - bit_buffer; + + if (!WriteFile(hOutFile, bit_buffer, bytes_to_write, &res, NULL) || + res != bytes_to_write) + throw TTAException (WRITE_ERROR); + + output_byte_count += res; + bitpos = bit_buffer; + frame_crc32 = 0xFFFFFFFFUL; + + res = output_byte_count - lastpos; + lastpos = output_byte_count; + + return res; + } + }; +}; diff --git a/ttalib-1.1/COPYING b/ttalib-1.1/COPYING new file mode 100644 index 0000000..7bfd1bc --- /dev/null +++ b/ttalib-1.1/COPYING @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + 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 + diff --git a/ttalib-1.1/ReadMe.txt b/ttalib-1.1/ReadMe.txt new file mode 100644 index 0000000..4ac2258 --- /dev/null +++ b/ttalib-1.1/ReadMe.txt @@ -0,0 +1,276 @@ +///////////////////////////////////////////////////////////////////////////// +////////////////// THE LOSSLESS TRUE AUDIO CODEC LIBRARY //////////////////// +///////////////////////////////////////////////////////////////////////////// + +This package contains a full-futured CODEC library for realtime encoding and +decoding of True Audio (TTA) files. + +The library has a 3 interface classes and 2 functions, which provides a +possibility to work in applications of any complexity. + +For maintenance of namespace wholeness, all functions and library classes +are transferred out to the separate namespace, named TTALib. + +For a simplicity of work with library namespace it's possible to use a +command: + +using namespace TTALib; + +///////////////////////////////////////////////////////////////////////////// +/////////////////// Wav2TTA, TTA2Wav & TTATest functions //////////////////// +///////////////////////////////////////////////////////////////////////////// + +For a simple use of the library we provide 3 basic functions: + +TTAError Wav2TTA ( const char *infile, + const char *outfile, + bool CopyID3v2Tag = true, + TTACALLBACK TTACallback = NULL, + void *uParam = NULL ); + +The Wav2TTA function is intended for convert a WAV files into the TTA format. + +Description of the function parameters: + + infile - the name of the input WAV file; + outfile - the name of the output TTA file; + CopyID3v2Tag - copy ID3v2 tag if it's present; + TTACallback - bool (*TTACALLBACK)(const TTAStat &stat, void *uParam), + the callback function, intended for the extension of + possibilities of the user program. Can be used to get + a statistics of the encoding process. This parameter + must be set to NULL if not used. The callback function + must return 'true' to continue of the encoding process, + or 'false' to interrupt it. In this case the Wav2TTA + function will return the TTA_CANCELED error. + uParam - users parameter, can be set to NULL; + +The TTA2Wav function is intended for convert a TTA files into the Wav format. + +TTAError TTA2Wav ( const char *infile, + const char *outfile, + bool CopyID3v2Tag = true, + TTACALLBACK TTACallback = NULL, + void *uParam = NULL ); + +Description of the function parameters: + + infile - the name of the input TTA file; + outfile - the name of the output WAV file; + CopyID3v2Tag - copy ID3v2 tag if it's present; + TTACallback - bool (*TTACALLBACK)(const TTAStat &stat, void *uParam), + the callback function, intended for the extension of + possibilities of the user program. Can be used to get + a statistics of the decoding process. This parameter + must be set to NULL if not used. The callback function + must return 'true' to continue of the decoding process, + or 'false' to interrupt it. In this case the TTA2Wav + function will return the TTA_CANCELED error. + uParam - users parameter, can be set to NULL; + +The TTA2Test function is intended for test a TTA files for errors. + +TTAError TTATest ( const char *infile, + TTACALLBACK TTACallback = NULL, + void *uParam = NULL ); + +Description of the function parameters: + + infile - the name of the input TTA file; + TTACallback - bool (*TTACALLBACK)(const TTAStat &stat, void *uParam), + the callback function, intended for the extension of + possibilities of the user program. Can be used to get + a statistics of the testing process. This parameter + must be set to NULL if not used. The callback function + must return 'true' to continue of the testing process, + or 'false' to interrupt it. In this case the TTA2Wav + function will return the TTA_CANCELED error. + uParam - users parameter, can be set to NULL; + +All of these functions returns the values of the TTAError type. +The error code can be easily converted into the text string, by calling the +GetErrStr() function, accepting a error code as a parameter. + +///////////////////////////////////////////////////////////////////////////// +//////////////// TTAEncoder, TTADecoder & WavFile classes /////////////////// +///////////////////////////////////////////////////////////////////////////// + +For using this library in advanced applications the TTAEncoder, TTADecoder +and the WavFile interface classes can be used. + +============================================================================ + TTAEncoder class +============================================================================ + +The TTAEncoder class is intended for coding PCM data with into the TTA file. + +The TTAEncoder class has a 2 constructors: + +TTAEncoder( const char *filename, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength ); + +TTAEncoder( HANDLE hInFile, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength ); + +The first of these 2 constructors accepts the name of the input file, +secondary constructor accepts the input file handle. The 'append' parameter +can be used to open input file for writing at the end of the file +(appending); creates the file first if it doesn't exist. + +The other parameters contains the information about the stream: + + AudioFormat - audio format: + WAVE_FORMAT_PCM or WAVE_FORMAT_IEEE_FLOAT; + NumChannels - number of channels; + BitsPerSample - count of bits per sample; + SampleRate - sample rate; + DataLength - overall number of input samples in file. + +The CompressBlock function can be used to compress a chunk of the input data: + + bool CompressBlock (long *buffer, long bufLen); + +Description of the function parameters: + + buffer - input data buffer; + bufLen - buffer length (number of input samples). + +Returns 'true' on success and 'false' on failure. + +The GetStat() function allows to get a compression statistics. + + TTAStat GetStat(); + +This function returns the TTAStat strucure: + + struct TTAStat + { + double ratio; + unsigned long input_bytes; + unsigned long output_bytes; + }; + +Description of the structure fields: + + ratio - compression ratio; + input_bytes - count of input bytes processed; + input_bytes - count of output bytes saved. + +============================================================================ + TTADecoder class +============================================================================ + +The TTADecoder class is intended for decoding of the TTA audio files. + +The TTADecoder class has a 2 constructors: + + TTADecoder (const char *filename); + TTADecoder (HANDLE hInFile); + +The first of these 2 constructors accepts the name of the input file, +secondary constructor accepts the input file handle. + +The next set of functions can be used to retrieve the information about the +stream: + + GetAudioFormat() - returns the audio format: + WAVE_FORMAT_PCM or WAVE_FORMAT_IEEE_FLOAT; + GetNumChannels() - returns the number of channels; + GetBitsPerSample() - returns the count of bits per sample; + GetSampleRate() - returns the sample rate; + GetDataLength() - returns the overall number of input samples + in file. + +The CompressBlock function can be used to get a chunk of the decompressed +data. + + long GetBlock (long **buffer); + +Returns the decompressed data into the 'buffer' and the buffer length (count +of samples) as a function value. Returns 0 if the end-of-file is reached. + +The GetStat() function allows to get a decompression statistics. + + TTAStat GetStat(); + +This function returns the the structure which has a TTAStat type, described +above. + +If an error occurs, the both of TTAEncoder and TTADecoder classes generates +exceptions of the TTAException type. The error code can be retrieved by +GetErrNo function of the exception value. The returned error code can be +converted into the text string by the GetErrStr() function, which accepts the +error value as a parameter. + +============================================================================ + WavFile class +============================================================================ + +The WavFile class provides a simple interface to work with a WAV format files. +The error code can be retrieved by GetErrNo function. The returned error code +can be converted into the text string by the GetErrStr() function, which +accepts the error value as a parameter. + + HANDLE Create(const char *filename); + +Creates the WAV file with a name, specified by the 'filename' parameter. +Returns the file HANDLE or INVALID_HANDLE_VALUE on error. + + HANDLE Open(const char *filename); + +Opens WAV file to read. Function accepts the file name as a parameter and +returns the file HANDLE or INVALID_HANDLE_VALUE on error. + + bool ReadHeaders(); + +This function is intended to get WAV file headers. Then, the read parameters +can be retrieved from class attributes 'wave_hdr' and 'subchunk_hdr'. +Function returns 'true' on success and 'false' on failure. + + bool Read(long *data, long byte_size, unsigned long *len); + +The function reads 'len' samples of data, each size 'byte_size' bytes, from +the input file into the buffer 'data'. Function returns 'true' on success +and 'false' on failure. + + bool WriteHeaders(); + +This function is intended to write WAV file headers. The writing headers +will be retrieved from class attributes 'wave_hdr' and 'subchunk_hdr'. +Function returns 'true' on success and 'false' on failure. + + bool Write(long *data, long byte_size, long num_chan, + unsigned long *len); + +The function writes 'len' samples of data, each size 'byte_size' bytes, +into the output file from the buffer 'data'. The 'num_chan' parameter +defines the number of audio channels. Function returns 'true' on success +and 'false' on failure. The actually wrote number of samples will be +returned back by the 'len' parameter. + + void Close(); // Closes the WAV file + + TTAError GetErrNo() const; // Returns the error code. + +The returned error code can be converted into the text string by the +GetErrStr() function, which accepts the error value as a parameter. + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +Copyright (c) 2004 Alexander Djourik. All rights reserved. +Copyright (c) 2004 Pavel Zhilin. All rights reserved. + +For the latest in news and downloads, please visit the official True Audio +project site: http://tta.sourceforge.net + diff --git a/ttalib-1.1/Stdafx.cpp b/ttalib-1.1/Stdafx.cpp new file mode 100644 index 0000000..3220eb3 --- /dev/null +++ b/ttalib-1.1/Stdafx.cpp @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// TTALib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/ttalib-1.1/Stdafx.h b/ttalib-1.1/Stdafx.h new file mode 100644 index 0000000..a1e5342 --- /dev/null +++ b/ttalib-1.1/Stdafx.h @@ -0,0 +1,8 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +//#using + diff --git a/ttalib-1.1/TTAError.h b/ttalib-1.1/TTAError.h new file mode 100644 index 0000000..d85e542 --- /dev/null +++ b/ttalib-1.1/TTAError.h @@ -0,0 +1,67 @@ +/* + * TTAError.h + * + * Description: Errors processor internal interface + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once +#include + +namespace TTALib +{ + enum TTAError + { + TTA_NO_ERROR = 0, + FORMAT_ERROR, + FILE_ERROR, + FIND_ERROR, + CREATE_ERROR, + OPEN_ERROR, + WRITE_ERROR, + READ_ERROR, + MEMORY_ERROR, + TTA_CANCELED + }; + + class TTAException : + public std::exception + { + TTAError errNo; + + public: + TTAException(TTAError err) : errNo (err) {} + + TTAException(const TTAException &ex) + { + if (&ex != this) errNo = ex.errNo; + } + + TTAError GetErrNo () { return errNo; } + + virtual ~TTAException(void) {} + }; +}; + diff --git a/ttalib-1.1/TTALib.cpp b/ttalib-1.1/TTALib.cpp new file mode 100644 index 0000000..b4aebe7 --- /dev/null +++ b/ttalib-1.1/TTALib.cpp @@ -0,0 +1,564 @@ +/* + * TTALib.cpp + * + * Description: TTA library functions + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#include "stdafx.h" +#include + +#include "TTALib.h" +#include "ttacommon.h" +#include "filters3.h" +#include "ttawriter.h" +#include "ttareader.h" +#include "WavFile.h" +#include "TTAError.h" +#include "TTATester.h" + +const char *TTAErrorsStr[] = { + "no errors found", + "not compatible file format", + "file is corrupted", + "file(s) not found", + "problem creating directory", + "can't open file", + "can't write to output file", + "can't read from input file", + "insufficient memory available", + "operation canceled" +}; + +// ******************* library functions prototypes ********************* + +const char * +TTALib::GetErrStr (TTALib::TTAError err) +{ + return TTAErrorsStr[err]; +} + +TTALib::TTAEncoder::TTAEncoder(const char *filename, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength) +{ + long offset = 0; + + if (!append) + hFile = CreateFile (filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); + else + { + hFile = CreateFile (filename, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); + offset = SetFilePointer (hFile, 0, NULL, FILE_END); + } + + if (hFile == INVALID_HANDLE_VALUE) + throw TTAException (OPEN_ERROR); + + + try { + writer = new TTAWriter(hFile, offset, AudioFormat, + NumChannels, BitsPerSample, SampleRate, DataLength); + } + + catch (std::exception ex) + { + CloseHandle (hFile); + throw ex; + } +} + +TTALib::TTAEncoder::TTAEncoder(HANDLE hInFile, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength) + : hFile (INVALID_HANDLE_VALUE) +{ + long offset = 0; + + if (hInFile == INVALID_HANDLE_VALUE) + throw TTAException (OPEN_ERROR); + + if (append) + offset = SetFilePointer (hInFile, 0, NULL, FILE_END); + + writer = new TTAWriter(hInFile, offset, AudioFormat, + NumChannels, BitsPerSample, SampleRate, DataLength); +} + +TTALib::TTAEncoder::~TTAEncoder() +{ + if (writer) delete writer; + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle (hFile); +} + +bool TTALib::TTAEncoder::CompressBlock (long *buf, long bufLen) +{ + return writer->CompressBlock (buf, bufLen); +} + +TTALib::TTAStat TTALib::TTAEncoder::GetStat () +{ + stat.input_bytes = writer->input_byte_count; + stat.output_bytes = writer->output_byte_count; + stat.ratio = writer->output_byte_count / (1. + writer->input_byte_count); + return stat; +} + +TTALib::TTADecoder::TTADecoder (const char *filename) +{ + struct { + unsigned char id[3]; + unsigned short version; + unsigned char flags; + unsigned char size[4]; + } __ATTRIBUTE_PACKED__ id3v2; + unsigned long result; + + if ((hFile = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + throw TTAException (OPEN_ERROR); + + // skip ID3V2 header + if (!ReadFile (hFile, &id3v2, sizeof(id3v2), &result, NULL)) + { + CloseHandle (hFile); + throw TTAException (READ_ERROR); + } + + if (id3v2.id[0] == 'I' && + id3v2.id[1] == 'D' && + id3v2.id[2] == '3') { + long len; + + if (id3v2.size[0] & 0x80) { + throw TTAException (FILE_ERROR); + } + + len = (id3v2.size[0] & 0x7f); + len = (len << 7) | (id3v2.size[1] & 0x7f); + len = (len << 7) | (id3v2.size[2] & 0x7f); + len = (len << 7) | (id3v2.size[3] & 0x7f); + len += 10; + if (id3v2.flags & (1 << 4)) len += 10; + + SetFilePointer (hFile, len, NULL, FILE_BEGIN); + } else SetFilePointer (hFile, 0, NULL, FILE_BEGIN); + + try + { + reader = new TTAReader(hFile); + } + + catch (std::exception ex) + { + CloseHandle (hFile); + throw ex; + } +} + +TTALib::TTADecoder::TTADecoder (HANDLE hInFile) + : hFile(INVALID_HANDLE_VALUE) +{ + reader = new TTAReader(hInFile); +} + +TTALib::TTADecoder::~TTADecoder() +{ + if (reader) + delete reader; + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle (hFile); +} + +long TTALib::TTADecoder::GetBlock (long **buf) +{ + return reader->GetBlock (buf); +} + +TTALib::TTAStat TTALib::TTADecoder::GetStat () +{ + stat.input_bytes = reader->input_byte_count; + stat.output_bytes = reader->output_byte_count; + stat.ratio = reader->output_byte_count / (1. + reader->input_byte_count); + return stat; +} + +long TTALib::TTADecoder::GetAudioFormat () +{ + return reader->ttahdr.AudioFormat; +} + +long TTALib::TTADecoder::GetNumChannels () +{ + return reader->ttahdr.NumChannels; +} + +long TTALib::TTADecoder::GetBitsPerSample () +{ + return reader->ttahdr.BitsPerSample; +} + +long TTALib::TTADecoder::GetSampleRate () +{ + return reader->ttahdr.SampleRate; +} + +long TTALib::TTADecoder::GetDataLength () +{ + return reader->ttahdr.DataLength; +} + +// ************************* basic functions ***************************** + +void rice_init(adapt *rice, unsigned long k0, unsigned long k1) +{ + rice->k0 = k0; + rice->k1 = k1; + rice->sum0 = shift_16[k0]; + rice->sum1 = shift_16[k1]; +} + +void encoder_init(encoder *tta, long nch, long byte_size) +{ + long *fset = flt_set[byte_size - 1]; + long i; + + for (i = 0; i < nch; i++) { + filter_init(&tta[i].fst, fset[0], fset[1]); + rice_init(&tta[i].rice, 10, 10); + tta[i].last = 0; + } +} + +TTALib::TTAError TTALib::CopyId3Header (HANDLE hInFile, HANDLE hOutFile, bool CopyID3v2Tag) +{ + struct { + unsigned char id[3]; + unsigned short version; + unsigned char flags; + unsigned char size[4]; + } __ATTRIBUTE_PACKED__ id3v2; + unsigned long data_len, offset = 0, result; + + if (!ReadFile (hInFile, &id3v2, sizeof(id3v2), &result, NULL)) + return TTALib::READ_ERROR; + + if (id3v2.id[0] == 'I' && + id3v2.id[1] == 'D' && + id3v2.id[2] == '3') { + char buffer[512]; + + if (id3v2.size[0] & 0x80) + return TTALib::FILE_ERROR; + + offset = (id3v2.size[0] & 0x7f); + offset = (offset << 7) | (id3v2.size[1] & 0x7f); + offset = (offset << 7) | (id3v2.size[2] & 0x7f); + offset = (offset << 7) | (id3v2.size[3] & 0x7f); + if (id3v2.flags & (1 << 4)) offset += 10; + data_len = offset, offset += 10; + + // write ID3V2 header + if (CopyID3v2Tag) + { + if (!WriteFile(hOutFile, &id3v2, sizeof(id3v2), &result, NULL) || + result != sizeof (id3v2)) + return TTALib::WRITE_ERROR; + + while (data_len > 0) { + unsigned long len = (data_len > sizeof(buffer))? sizeof(buffer):data_len; + if (!ReadFile (hInFile, buffer, len, &result, NULL)) + return TTALib::READ_ERROR; + if (!WriteFile(hOutFile, buffer, len, &result, NULL) || + result != len) + return TTALib::WRITE_ERROR; + data_len -= len; + } + } else SetFilePointer (hInFile, offset, NULL, FILE_BEGIN); + } else SetFilePointer (hInFile, 0, NULL, FILE_BEGIN); + return TTALib::TTA_NO_ERROR; +} + +TTALib::TTAError TTALib::Wav2TTA (const char *infile, const char *outfile, + bool CopyID3v2Tag, TTACALLBACK TTACallback, void *uParam) +{ + HANDLE hInFile, hOutFile; + unsigned long data_size, byte_size, data_len, framelen, is_float; + unsigned long offset = 0; + long *data = NULL; + TTALib::TTAEncoder *encoder; + TTALib::TTAError err; + TTALib::WaveFile wav; + + if ((hInFile = wav.Open (infile)) == INVALID_HANDLE_VALUE) + return wav.GetErrNo (); + + if ((hOutFile = CreateFile (outfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + { + wav.Close (); + return TTALib::OPEN_ERROR; + } + + // copy ID3V2 header if present + if ((err = TTALib::CopyId3Header (hInFile, hOutFile, CopyID3v2Tag)) != TTALib::TTA_NO_ERROR) + { + wav.Close (); + CloseHandle (hOutFile); + DeleteFile (outfile); + return err; + } + + offset = SetFilePointer (hOutFile, 0, NULL, FILE_CURRENT); + + if (!wav.ReadHeaders ()) + { + DeleteFile (outfile); + return wav.GetErrNo (); + } + + // check for supported formats + if ((wav.wave_hdr.ChunkID != RIFF_SIGN) || + (wav.wave_hdr.Format != WAVE_SIGN) || + (wav.wave_hdr.Subchunk1ID != fmt_SIGN) || + (wav.wave_hdr.Subchunk1Size > wav.wave_hdr.ChunkSize) || + (wav.wave_hdr.NumChannels == 0) || + (wav.wave_hdr.BitsPerSample > MAX_BPS)) { + wav.Close (); + CloseHandle (hOutFile); + DeleteFile (outfile); + return TTALib::FORMAT_ERROR; + } + + switch (wav.wave_hdr.AudioFormat) { + case WAVE_FORMAT_IEEE_FLOAT: is_float = 1; break; + case WAVE_FORMAT_PCM: is_float = 0; break; + default: + wav.Close (); + CloseHandle (hOutFile); + DeleteFile (outfile); + return TTALib::FORMAT_ERROR; + } + + if ((is_float && wav.wave_hdr.BitsPerSample != MAX_BPS) || + (!is_float && wav.wave_hdr.BitsPerSample == MAX_BPS)) { + wav.Close (); + CloseHandle (hOutFile); + DeleteFile (outfile); + return TTALib::FORMAT_ERROR; + } + + data_size = wav.subchunk_hdr.SubchunkSize; + byte_size = (wav.wave_hdr.BitsPerSample + 7) / 8; + data_len = data_size / (byte_size * wav.wave_hdr.NumChannels); + framelen = (long) (FRAME_TIME * wav.wave_hdr.SampleRate) - 7; + + err = TTALib::TTA_NO_ERROR; + try { + data = new long [(wav.wave_hdr.NumChannels << is_float) * framelen * sizeof(long)]; + + encoder = new TTALib::TTAEncoder (hOutFile, true, + wav.wave_hdr.AudioFormat, wav.wave_hdr.NumChannels, wav.wave_hdr.BitsPerSample, + wav.wave_hdr.SampleRate, data_len); + unsigned long len; + for (;;) + { + len = framelen * wav.wave_hdr.NumChannels; + if (!wav.Read (data, byte_size, &len)) + break; + if (!encoder->CompressBlock (data, len / wav.wave_hdr.NumChannels)) + break; + if (TTACallback) + if(!TTACallback(encoder->GetStat(), uParam)) + { + err = TTALib::TTA_CANCELED; + break; + } + } + delete encoder; + CloseHandle (hOutFile); + wav.Close (); + delete [] data; + + } + + catch (TTALib::TTAException ex) + { + wav.Close (); + delete [] data; + CloseHandle (hOutFile); + DeleteFile (outfile); + return ex.GetErrNo (); + } + + catch (...) + { + CloseHandle (hOutFile); + wav.Close (); + DeleteFile (outfile); + return TTALib::MEMORY_ERROR; + } + + return err; +} + +TTALib::TTAError TTALib::TTA2Wav (const char *infile, const char *outfile, + bool CopyID3v2Tag, TTACALLBACK TTACallback, void *uParam) +{ + HANDLE hInFile, hOutFile; + long *buf; + unsigned long byte_size, data_size, buflen; + TTALib::TTADecoder *decoder; + TTALib::TTAError err; + TTALib::WaveFile wav; + + if ((hInFile = CreateFile (infile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + return TTALib::OPEN_ERROR; + + if (((hOutFile = wav.Create (outfile))) == INVALID_HANDLE_VALUE) + { + CloseHandle (hInFile); + return wav.GetErrNo(); + } + + // copy ID3V2 header if present + if ((err = CopyId3Header (hInFile, hOutFile, CopyID3v2Tag)) != TTALib::TTA_NO_ERROR) + { + CloseHandle (hInFile); + wav.Close (); + DeleteFile (outfile); + return err; + } + + err = TTALib::TTA_NO_ERROR; + try + { + decoder = new TTADecoder (hInFile); + + byte_size = (decoder->GetBitsPerSample() + 7) / 8; + data_size = decoder->GetDataLength() * byte_size * decoder->GetNumChannels(); + + wav.wave_hdr.ChunkSize = data_size + 36; + wav.wave_hdr.AudioFormat =(unsigned short)decoder->GetAudioFormat(); + wav.wave_hdr.NumChannels = (unsigned short)decoder->GetNumChannels(); + wav.wave_hdr.SampleRate = decoder->GetSampleRate(); + wav.wave_hdr.BitsPerSample = (unsigned short)decoder->GetBitsPerSample(); + wav.wave_hdr.ByteRate = decoder->GetSampleRate() * byte_size * decoder->GetNumChannels(); + wav.wave_hdr.BlockAlign = (unsigned short) (decoder->GetNumChannels() * byte_size); + wav.subchunk_hdr.SubchunkSize = ENDSWAP_INT32(data_size); + + wav.WriteHeaders (); + + while ((buflen = decoder->GetBlock (&buf)) > 0) + { + if (!wav.Write (buf, byte_size, decoder->GetNumChannels(), &buflen)) + return wav.GetErrNo(); + if (TTACallback) + if(!TTACallback(decoder->GetStat(), uParam)) + { + err = TTALib::TTA_CANCELED; + break; + } + } + wav.Close (); + delete decoder; + CloseHandle (hInFile); + } + + catch (TTAException ex) + { + DeleteFile (outfile); + CloseHandle (hInFile); + return ex.GetErrNo (); + } + + return err; +} + +TTALib::TTAError TTALib::TTATest (const char *infile, + TTACALLBACK TTACallback, void *uParam) +{ + unsigned long result, len = 0; + TTALib::TTAError err; + TTALib::TTAStat stat = {0, 0, 0}; + TTATester *tester; + TTAHeader ttahdr; + HANDLE hFile; + + if ((hFile = CreateFile (infile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + return TTALib::OPEN_ERROR; + + // copy ID3V2 header if present + if ((err = CopyId3Header (hFile, 0, false)) != TTALib::TTA_NO_ERROR) + { + CloseHandle (hFile); + return err; + } + + tester = NULL; + try + { + tester = new TTATester(hFile); + + tester->GetHeader (&ttahdr); + while (tester->TestFrame()) + { + stat.input_bytes = tester->input_byte_count + len; + + if (TTACallback) + if(!TTACallback(stat, uParam)) + return TTALib::TTA_CANCELED; + } + } + catch (TTAException ex) + { + if (tester) + delete tester; + CloseHandle (hFile); + return ex.GetErrNo(); + } + catch (...) + { + return TTALib::MEMORY_ERROR; + } + delete tester; + + CloseHandle (hFile); + + return err; +} diff --git a/ttalib-1.1/TTALib.h b/ttalib-1.1/TTALib.h new file mode 100644 index 0000000..5ed7b16 --- /dev/null +++ b/ttalib-1.1/TTALib.h @@ -0,0 +1,125 @@ +/* + * TTALib.h + * + * Description: TTA library interface + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#ifndef TTALIB_H_ +#define TTALIB_H_ + +#include "TTAError.h" +#include "WavFile.h" +#include + +#pragma pack(push) +#pragma pack(1) + +#ifdef _WINDLL + #define DllExport __declspec( dllexport ) +#else + #define DllExport +#endif + +#define WAVE_FORMAT_PCM 1 +#define WAVE_FORMAT_IEEE_FLOAT 3 + +namespace TTALib +{ + struct DllExport TTAStat + { + double ratio; + unsigned long input_bytes; + unsigned long output_bytes; + }; + + class TTAReader; + class TTAWriter; + + class DllExport TTAEncoder + { + TTAWriter *writer; + HANDLE hFile; + TTAStat stat; + + public: + TTAEncoder(const char *filename, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength); + TTAEncoder(HANDLE hInFile, + bool append, + unsigned short AudioFormat, + unsigned short NumChannels, + unsigned short BitsPerSample, + unsigned long SampleRate, + unsigned long DataLength); + + ~TTAEncoder(); + + bool CompressBlock (long *buf, long bufLen); + + TTAStat GetStat (); + }; + + class DllExport TTADecoder + { + TTAReader *reader; + HANDLE hFile; + TTAStat stat; + + public: + TTADecoder (const char *filename); + TTADecoder (HANDLE hInFile); + ~TTADecoder(); + + long GetBlock (long **buf); + + long GetAudioFormat (); + long GetNumChannels (); + long GetBitsPerSample (); + long GetSampleRate (); + long GetDataLength (); + + TTAStat GetStat (); + }; + + typedef bool (*TTACALLBACK)(const TTAStat &stat, void *uParam); + DllExport const char *GetErrStr (TTAError err); + + DllExport TTAError CopyId3Header (HANDLE hInFile, HANDLE hOutFile, bool CopyID3v2Tag); + DllExport TTAError Wav2TTA (const char *infile, const char *outfile, + bool CopyID3v2Tag=true, TTACALLBACK TTACallback=NULL, void *uParam=NULL); + DllExport TTAError TTA2Wav (const char *infile, const char *outfile, + bool CopyID3v2Tag=true, TTACALLBACK TTACallback=NULL, void *uParam=NULL); + DllExport TTAError TTATest (const char *infile, + TTACALLBACK TTACallback=NULL, void *uParam=NULL); +} + +#pragma pack(pop) +#endif // TTALIB_H_ diff --git a/ttalib-1.1/TTALib.vcproj b/ttalib-1.1/TTALib.vcproj new file mode 100644 index 0000000..b2223fe --- /dev/null +++ b/ttalib-1.1/TTALib.vcproj @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ttalib-1.1/TTAReader.cpp b/ttalib-1.1/TTAReader.cpp new file mode 100644 index 0000000..aefd529 --- /dev/null +++ b/ttalib-1.1/TTAReader.cpp @@ -0,0 +1,175 @@ +/* + * TTAReader.cpp + * + * Description: TTA decompressor functions + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#include "stdafx.h" +#include "BitReader.h" +#include "TTAReader.h" +#include "filters3.h" + +namespace TTALib +{ + TTAReader::TTAReader (HANDLE fd) : hInFile(fd) + { + unsigned long data_size; + int st_size; + + // clear statistics + output_byte_count = 0; + bitReader = new BitReader (hInFile); + bitReader->GetHeader (&ttahdr); + + byte_size = (ttahdr.BitsPerSample + 7) / 8; + framelen = (long) (FRAME_TIME * ttahdr.SampleRate); + is_float = (ttahdr.AudioFormat == WAVE_FORMAT_IEEE_FLOAT); + num_chan = ttahdr.NumChannels << is_float; + data_size = ttahdr.DataLength * byte_size * ttahdr.NumChannels; + + lastlen = ttahdr.DataLength % framelen; + fframes = ttahdr.DataLength / framelen + (lastlen ? 1 : 0); + st_size = (fframes + 1); + st_state = 0; + + enc = tta = new encoder[num_chan]; + seek_table = new unsigned long[st_size]; + data = new long[framelen * num_chan]; + st_state = bitReader->GetSeekTable (seek_table, st_size); + encoder_init(tta, num_chan, byte_size); + } + + TTAReader::~TTAReader () + { + delete [] seek_table; + delete [] tta; + delete [] data; + delete bitReader; + } + + long TTAReader::GetBlock (long **buf) + { + long *p, value; + unsigned long unary, binary, depth, k; + + if (!fframes--) + return 0; + + if (!fframes && lastlen) framelen = lastlen; + + encoder_init(tta, num_chan, byte_size); + + for (p = data; p < data + framelen * num_chan; p++) { + fltst *fst = &enc->fst; + adapt *rice = &enc->rice; + long *last = &enc->last; + + // decode Rice unsigned + bitReader->GetUnary(&unary); + + switch (unary) + { + case 0: depth = 0; k = rice->k0; break; + default: + depth = 1; k = rice->k1; + unary--; + } + + if (k) { + bitReader->GetBinary(&binary, k); + value = (unary << k) + binary; + } else value = unary; + + switch (depth) + { + case 1: + rice->sum1 += value - (rice->sum1 >> 4); + if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1]) + rice->k1--; + else if (rice->sum1 > shift_16[rice->k1 + 1]) + rice->k1++; + value += bit_shift[rice->k0]; + default: + rice->sum0 += value - (rice->sum0 >> 4); + if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0]) + rice->k0--; + else if (rice->sum0 > shift_16[rice->k0 + 1]) + rice->k0++; + } + + *p = DEC(value); + + // decompress stage 1: adaptive hybrid filter + hybrid_filter(fst, p, 0); + + // decompress stage 2: fixed order 1 prediction + switch (byte_size) + { + case 1: *p += PREDICTOR1(*last, 4); break; // bps 8 + case 2: *p += PREDICTOR1(*last, 5); break; // bps 16 + case 3: *p += PREDICTOR1(*last, 5); break; // bps 24 + case 4: *p += *last; break; // bps 32 + } *last = *p; + + // combine data + if (is_float && ((p - data) & 1)) { + unsigned long negative = *p & 0x80000000; + unsigned long data_hi = *(p - 1); + unsigned long data_lo = abs(*p) - 1; + + data_hi += (data_hi || data_lo) ? 0x3F80 : 0; + *(p - 1) = (data_hi << 16) | SWAP16(data_lo) | negative; + } + + if (enc < tta + num_chan - 1) enc++; + else { + if (!is_float && num_chan > 1) { + long *r = p - 1; + for (*p += *r/2; r > p - num_chan; r--) + *r = *(r + 1) - *r; + } + enc = tta; + } + } + + if (bitReader->Done ()) // CRC error + { + if (st_state) + { + bitReader->SkipFrame (); + ZeroMemory(data, num_chan * framelen * sizeof(long)); + } + else throw TTAException (FILE_ERROR); + } + + *buf = data; + + input_byte_count = bitReader->input_byte_count; + output_byte_count += (p - data) * byte_size; + + return (p - data) / num_chan; + } +}; diff --git a/ttalib-1.1/TTAReader.h b/ttalib-1.1/TTAReader.h new file mode 100644 index 0000000..d680104 --- /dev/null +++ b/ttalib-1.1/TTAReader.h @@ -0,0 +1,63 @@ +/* + * TTAReader.h + * + * Description: TTA decompressor internals + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once + +#include "ttacommon.h" + +#define WAVE_FORMAT_PCM 1 +#define WAVE_FORMAT_IEEE_FLOAT 3 + +namespace TTALib +{ + class BitReader; + + class TTAReader + { + HANDLE hInFile; + long *data; + unsigned long offset, is_float, framelen, lastlen; + unsigned long fframes, byte_size, num_chan; + unsigned long *seek_table; + bool st_state; + encoder *tta, *enc; + + BitReader *bitReader; + + public: + TTAReader (HANDLE fd); + ~TTAReader (); + + unsigned long input_byte_count; + unsigned long output_byte_count; + TTAHeader ttahdr; + + long GetBlock (long **buf); + }; +} diff --git a/ttalib-1.1/TTATester.h b/ttalib-1.1/TTATester.h new file mode 100644 index 0000000..c88638a --- /dev/null +++ b/ttalib-1.1/TTATester.h @@ -0,0 +1,69 @@ +#pragma once +#include "bitreader.h" + +namespace TTALib +{ + + class TTATester : + public BitReader + { + unsigned char *data; + unsigned long *seek_table, *fst; + long fframes; + public: + + TTATester(HANDLE hFile) + : BitReader(hFile), data(NULL), seek_table(NULL), fframes(-1) + { + } + + virtual ~TTATester(void) + { + if (seek_table) + delete [] seek_table; + if (data) + delete [] data; + } + + virtual void GetHeader (TTAHeader *ttahdr) + { + BitReader::GetHeader (ttahdr); + + long framelen = (long) (FRAME_TIME * ttahdr->SampleRate); + long framesize = framelen * ttahdr->NumChannels * + (ttahdr->BitsPerSample + 7) / 8 + 4; + + long lastlen = ttahdr->DataLength % framelen; + fframes = ttahdr->DataLength / framelen + (lastlen ? 1 : 0); + + data = new unsigned char[framesize]; + seek_table = new unsigned long[fframes + 1]; + + if (!GetSeekTable (seek_table, fframes + 1)) + throw TTAException (FILE_ERROR); + fst = seek_table; + } + + + virtual bool TestFrame () + { + unsigned long frame_crc32, result; + + if (fst >= seek_table + fframes) + return false; + + if (!ReadFile(hInFile, data, *fst, &result, NULL) || + result != *fst) + throw TTAException (READ_ERROR); + else input_byte_count += result; + + CopyMemory(&frame_crc32, data + (result - 4), 4); + if (crc32(data, *fst - 4) != ENDSWAP_INT32(frame_crc32)) + throw TTAException (FILE_ERROR); + + fst ++; + return true; + } + }; + +}; \ No newline at end of file diff --git a/ttalib-1.1/TTAWriter.cpp b/ttalib-1.1/TTAWriter.cpp new file mode 100644 index 0000000..547811e --- /dev/null +++ b/ttalib-1.1/TTAWriter.cpp @@ -0,0 +1,203 @@ +/* + * TTAWriter.cpp + * + * Description: TTA compressor functions + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#include "stdafx.h" +#include "TTAWriter.h" +#include "filters3.h" + +namespace TTALib +{ + TTAWriter::TTAWriter (HANDLE fd, long offset, unsigned short AudioFormat, + unsigned short NumChannels, unsigned short BitsPerSample, + unsigned long SampleRate, unsigned long DataLength) + : hOutFile (fd) + { + ttahdr.AudioFormat = AudioFormat; + ttahdr.NumChannels = NumChannels; + ttahdr.BitsPerSample = BitsPerSample; + ttahdr.SampleRate = SampleRate; + ttahdr.DataLength = DataLength; + + switch (ttahdr.AudioFormat) + { + case WAVE_FORMAT_IEEE_FLOAT: is_float = 1; break; + case WAVE_FORMAT_PCM: is_float = 0; break; + default: throw TTAException (FORMAT_ERROR); + } + + if ((is_float && ttahdr.BitsPerSample != MAX_BPS) || + (!is_float && ttahdr.BitsPerSample == MAX_BPS)) + throw TTAException (FORMAT_ERROR); + + framelen = (long) (FRAME_TIME * ttahdr.SampleRate); + num_chan = ttahdr.NumChannels << is_float; + byte_size = (ttahdr.BitsPerSample + 7) / 8; + + input_byte_count = 0; + output_byte_count = 0; + + lastlen = ttahdr.DataLength % framelen; + fframes = ttahdr.DataLength / framelen + (lastlen ? 1 : 0); + st_size = (fframes + 1); + + // grab some space for an encoder buffers + st = seek_table = new unsigned long[st_size]; + enc = tta = new encoder[num_chan]; + + bitWriter = new BitWriter (hOutFile, offset); + bitWriter->PutHeader (ttahdr); + bitWriter->PutSeekTable (seek_table, st_size); + + data_pos = 0; + encoder_init(tta, num_chan, byte_size); + fframes--; + + max_bytes = (num_chan * byte_size * ttahdr.DataLength) >> is_float; + } + + TTAWriter::~TTAWriter () + { + bitWriter->PutSeekTable (seek_table, st_size); + delete bitWriter; + + delete [] seek_table; + delete [] tta; + }; + + bool TTAWriter::CompressBlock (long *data, long data_len) + { + long *p, tmp, prev; + unsigned long value, k, unary, binary; + long len; + bool ret = false; + + if (data_len > (long)(max_bytes - input_byte_count)) + data_len = (long) (max_bytes - input_byte_count); + + input_byte_count += (num_chan * byte_size * data_len) >> is_float; + + while (data_len > 0 && fframes >= 0) + { + if (data_len < (long)(framelen - data_pos)) + len = data_len; + else + len = framelen - data_pos; + data_len -= len; + + for (p = data, prev = 0; p < data + len * num_chan; p++) + { + fltst *fst = &enc->fst; + adapt *rice = &enc->rice; + long *last = &enc->last; + + // transform data + if (!is_float) { + if (enc < tta + num_chan - 1) + *p = prev = *(p + 1) - *p; + else *p -= prev / 2; + } else if (!((p - data) & 1)) { + unsigned long t = *p; + unsigned long negative = (t & 0x80000000) ? -1 : 1; + unsigned long data_hi = (t & 0x7FFF0000) >> 16; + unsigned long data_lo = (t & 0x0000FFFF); + + *p = (data_hi || data_lo) ? (data_hi - 0x3F80) : 0; + *(p + 1) = (SWAP16(data_lo) + 1) * negative; + } + + // compress stage 1: fixed order 1 prediction + tmp = *p; + switch (byte_size) + { + case 1: *p -= PREDICTOR1(*last, 4); break; // bps 8 + case 2: *p -= PREDICTOR1(*last, 5); break; // bps 16 + case 3: *p -= PREDICTOR1(*last, 5); break; // bps 24 + case 4: *p -= *last; break; // bps 32 + } + *last = tmp; + + // compress stage 2: adaptive hybrid filter + hybrid_filter(fst, p, 1); + + value = ENC(*p); + + // encode Rice unsigned + k = rice->k0; + + rice->sum0 += value - (rice->sum0 >> 4); + if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0]) + rice->k0--; + else if (rice->sum0 > shift_16[rice->k0 + 1]) + rice->k0++; + + if (value >= bit_shift[k]) { + value -= bit_shift[k]; + k = rice->k1; + + rice->sum1 += value - (rice->sum1 >> 4); + if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1]) + rice->k1--; + else if (rice->sum1 > shift_16[rice->k1 + 1]) + rice->k1++; + + unary = 1 + (value >> k); + } else unary = 0; + + bitWriter->PutUnary(unary); + if (k) { + binary = value & bit_mask[k]; + bitWriter->PutBinary(binary, k); + } + + if (enc < tta + num_chan - 1) enc++; + else enc = tta; + } + + data_pos += len; + + if (data_pos == framelen) + { + *st++ = bitWriter->Done (); + + fframes--; + if (!fframes && lastlen) framelen = lastlen; + encoder_init(tta, num_chan, byte_size); + data_pos = 0; + } + + data += (num_chan * len); + + ret = true; + } + + output_byte_count = bitWriter->output_byte_count; + return ret; + } + +}; diff --git a/ttalib-1.1/TTAWriter.h b/ttalib-1.1/TTAWriter.h new file mode 100644 index 0000000..bfe6767 --- /dev/null +++ b/ttalib-1.1/TTAWriter.h @@ -0,0 +1,62 @@ +/* + * TTAWriter.h + * + * Description: TTA compressor internals + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once +#include "BitWriter.h" +#include "TTAError.h" +#include "TTACommon.h" + +#define WAVE_FORMAT_PCM 1 +#define WAVE_FORMAT_IEEE_FLOAT 3 + +namespace TTALib +{ + class TTAWriter + { + HANDLE hOutFile; + TTAHeader ttahdr; + BitWriter *bitWriter; + unsigned long *seek_table, st_size, *st; + unsigned long offset, is_float, framelen, lastlen; + unsigned long fframes, byte_size, num_chan; + unsigned long data_pos, max_bytes; + encoder *tta, *enc; + + public: + TTAWriter (HANDLE fd, long offset, unsigned short AudioFormat, + unsigned short NumChannels, unsigned short BitsPerSample, + unsigned long SampleRate, unsigned long DataLength); + ~TTAWriter (); + + unsigned long input_byte_count; + unsigned long output_byte_count; + + bool CompressBlock (long *data, long data_len); + }; +} diff --git a/ttalib-1.1/WavFile.cpp b/ttalib-1.1/WavFile.cpp new file mode 100644 index 0000000..3cb81ca --- /dev/null +++ b/ttalib-1.1/WavFile.cpp @@ -0,0 +1,266 @@ +/* + * WavFile.cpp + * + * Description: Wraps working with WAV files + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#include "stdafx.h" +#include +#include "TTACommon.h" +#include "TTAError.h" +#include "WavFile.h" + +/************************** WAV functions ******************************/ + +TTALib::WaveFile::WaveFile () : fd (INVALID_HANDLE_VALUE) +{ +} + +TTALib::WaveFile::~WaveFile () +{ + if (fd != INVALID_HANDLE_VALUE) + CloseHandle (fd); +} + +HANDLE TTALib::WaveFile::Create (const char *filename) +{ + errNo = TTALib::TTA_NO_ERROR; + if ((fd = CreateFile (filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + { + errNo = TTALib::OPEN_ERROR; + return INVALID_HANDLE_VALUE; + } + return fd; +} + +HANDLE TTALib::WaveFile::Open (const char *filename) +{ + errNo = TTALib::TTA_NO_ERROR; + if ((fd = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE) + errNo = TTALib::OPEN_ERROR; + return fd; +} + +bool TTALib::WaveFile::ReadHeaders () +{ + unsigned long result; + + // Read WAVE header + if (!ReadFile(fd, &wave_hdr, sizeof(wave_hdr), &result, NULL)) + { + CloseHandle (fd); + errNo = TTALib::READ_ERROR; + return false; + } + + wave_hdr.ChunkID = ENDSWAP_INT32(wave_hdr.ChunkID); + wave_hdr.ChunkSize = ENDSWAP_INT32(wave_hdr.ChunkSize); + wave_hdr.Format = ENDSWAP_INT32(wave_hdr.Format); + wave_hdr.Subchunk1ID = ENDSWAP_INT32(wave_hdr.Subchunk1ID); + wave_hdr.Subchunk1Size = ENDSWAP_INT32(wave_hdr.Subchunk1Size); + wave_hdr.AudioFormat = ENDSWAP_INT16(wave_hdr.AudioFormat); + wave_hdr.NumChannels = ENDSWAP_INT16(wave_hdr.NumChannels); + wave_hdr.SampleRate = ENDSWAP_INT32(wave_hdr.SampleRate); + wave_hdr.ByteRate = ENDSWAP_INT32(wave_hdr.ByteRate); + wave_hdr.BlockAlign = ENDSWAP_INT16(wave_hdr.BlockAlign); + wave_hdr.BitsPerSample = ENDSWAP_INT16(wave_hdr.BitsPerSample); + + // skip extra format bytes + if (wave_hdr.Subchunk1Size > 16) { + SetFilePointer (fd, wave_hdr.Subchunk1Size - 16, NULL, FILE_CURRENT); + } + + // skip unsupported chunks + while (ReadFile(fd, &subchunk_hdr, sizeof(subchunk_hdr), &result, NULL) && + subchunk_hdr.SubchunkID != ENDSWAP_INT32(data_SIGN)) { + char chunk_id[5]; + + subchunk_hdr.SubchunkSize = ENDSWAP_INT32(subchunk_hdr.SubchunkSize); + subchunk_hdr.SubchunkID = ENDSWAP_INT32(subchunk_hdr.SubchunkID); + + if (subchunk_hdr.SubchunkSize & 0x80000000UL) { + CloseHandle (fd); + errNo = TTALib::FILE_ERROR; + return false; + } + + CopyMemory(chunk_id, &subchunk_hdr.SubchunkID, 4); + chunk_id[4] = 0; + + SetFilePointer(fd, subchunk_hdr.SubchunkSize, NULL, FILE_CURRENT); + } + subchunk_hdr.SubchunkSize = ENDSWAP_INT32(subchunk_hdr.SubchunkSize); + return true; +} + +bool TTALib::WaveFile::WriteHeaders () +{ + unsigned long result; + + errNo = TTALib::TTA_NO_ERROR; + wave_hdr.ChunkID = ENDSWAP_INT32(RIFF_SIGN); + wave_hdr.ChunkSize = ENDSWAP_INT32(wave_hdr.ChunkSize); + wave_hdr.Format = ENDSWAP_INT32(WAVE_SIGN); + wave_hdr.Subchunk1ID = ENDSWAP_INT32(fmt_SIGN); + wave_hdr.Subchunk1Size = ENDSWAP_INT32(16); + wave_hdr.AudioFormat = ENDSWAP_INT16(wave_hdr.AudioFormat); + wave_hdr.NumChannels = ENDSWAP_INT16(wave_hdr.NumChannels); + wave_hdr.SampleRate = ENDSWAP_INT32(wave_hdr.SampleRate); + wave_hdr.ByteRate = ENDSWAP_INT32(wave_hdr.ByteRate); + wave_hdr.BlockAlign = ENDSWAP_INT16(wave_hdr.BlockAlign); + wave_hdr.BitsPerSample = ENDSWAP_INT16(wave_hdr.BitsPerSample); + subchunk_hdr.SubchunkID = ENDSWAP_INT32(data_SIGN); + subchunk_hdr.SubchunkSize = ENDSWAP_INT32(subchunk_hdr.SubchunkSize); + + // write WAVE header + if (!WriteFile(fd, &wave_hdr, sizeof(wave_hdr), &result, NULL) || + result != sizeof(wave_hdr)) + { + errNo = TTALib::WRITE_ERROR; + return false; + } + // write Subchunk header + if (!WriteFile(fd, &subchunk_hdr, sizeof(subchunk_hdr), &result, NULL) || + result != sizeof(subchunk_hdr)) + { + errNo = TTALib::WRITE_ERROR; + return false; + } + return true; +} + +bool TTALib::WaveFile::Read(long *data, long byte_size, unsigned long *len) +{ + unsigned long res; + unsigned char *buffer, *src; + long *dst = data; + + errNo = TTALib::TTA_NO_ERROR; + if (!(src = buffer = (unsigned char *)calloc(*len, byte_size))) + { + errNo = TTALib::MEMORY_ERROR; + return false; + } + + if (!ReadFile (fd, buffer, *len * byte_size, &res, NULL)) + { + errNo = TTALib::READ_ERROR; + return false; + } + + switch (byte_size) { + case 1: for (; src < buffer + res; dst++) + *dst = (signed long) *src++ - 0x80; + break; + case 2: for (; src < buffer + res; dst++) { + *dst = (unsigned char) *src++; + *dst |= (signed char) *src++ << 8; + } + break; + case 3: for (; src < buffer + res; dst++) { + *dst = (unsigned char) *src++; + *dst |= (unsigned char) *src++ << 8; + *dst |= (signed char) *src++ << 16; + } + break; + case 4: for (; src < buffer + res; dst += 2) { + *dst = (unsigned char) *src++; + *dst |= (unsigned char) *src++ << 8; + *dst |= (unsigned char) *src++ << 16; + *dst |= (signed char) *src++ << 24; + } + break; + } + + *len = res / byte_size; + free(buffer); + + return true; +} + +bool TTALib::WaveFile::Write(long *data, long byte_size, long num_chan, unsigned long *len) +{ + unsigned long res; + unsigned char *buffer, *dst; + long *src = data; + + errNo = TTALib::TTA_NO_ERROR; + if (!(dst = buffer = (unsigned char *)calloc(*len * num_chan, byte_size))) + { + errNo = TTALib::MEMORY_ERROR; + return false; + } + + switch (byte_size) { + case 1: for (; src < data + (*len * num_chan); src++) + *dst++ = (unsigned char) (*src + 0x80); + break; + case 2: for (; src < data + (*len * num_chan); src++) { + *dst++ = (unsigned char) *src; + *dst++ = (unsigned char) (*src >> 8); + } + break; + case 3: for (; src < data + (*len * num_chan); src++) { + *dst++ = (unsigned char) *src; + *dst++ = (unsigned char) (*src >> 8); + *dst++ = (unsigned char) (*src >> 16); + } + break; + case 4: for (; src < data + (*len * num_chan * 2); src += 2) { + *dst++ = (unsigned char) *src; + *dst++ = (unsigned char) (*src >> 8); + *dst++ = (unsigned char) (*src >> 16); + *dst++ = (unsigned char) (*src >> 24); + } + break; + } + + if (!WriteFile (fd, buffer, *len * num_chan * byte_size, &res, NULL) + || res != *len * num_chan * byte_size) + { + errNo = TTALib::WRITE_ERROR; + return false; + } + + *len = res / byte_size; + free(buffer); + + return true; +} + +TTALib::TTAError TTALib::WaveFile::GetErrNo () const +{ + return errNo; +} + +void TTALib::WaveFile::Close () +{ + errNo = TTALib::TTA_NO_ERROR; + CloseHandle (fd); + fd = INVALID_HANDLE_VALUE; +} diff --git a/ttalib-1.1/WavFile.h b/ttalib-1.1/WavFile.h new file mode 100644 index 0000000..ac6fce1 --- /dev/null +++ b/ttalib-1.1/WavFile.h @@ -0,0 +1,86 @@ +/* + * WavFile.h + * + * Description: Wraps working with WAV files + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#pragma once +#define RIFF_SIGN 0x46464952 +#define WAVE_SIGN 0x45564157 +#define fmt_SIGN 0x20746D66 +#define data_SIGN 0x61746164 + +#ifdef _WINDLL + #define DllExport __declspec( dllexport ) +#else + #define DllExport +#endif + + +namespace TTALib +{ + class DllExport WaveFile + { + TTAError errNo; + + public: + HANDLE fd; + struct { + unsigned long ChunkID; + unsigned long ChunkSize; + unsigned long Format; + unsigned long Subchunk1ID; + unsigned long Subchunk1Size; + unsigned short AudioFormat; + unsigned short NumChannels; + unsigned long SampleRate; + unsigned long ByteRate; + unsigned short BlockAlign; + unsigned short BitsPerSample; + } wave_hdr; + struct { + unsigned long SubchunkID; + unsigned long SubchunkSize; + } subchunk_hdr; + + + WaveFile (); + ~WaveFile (); + + HANDLE Create (const char *filename); + HANDLE Open (const char *filename); + + bool ReadHeaders (); + bool Read(long *data, long byte_size, unsigned long *len); + + bool WriteHeaders (); + bool Write(long *data, long byte_size, long num_chan, unsigned long *len); + + void Close (); + + TTAError GetErrNo () const; + }; +}; diff --git a/ttalib-1.1/crc32.h b/ttalib-1.1/crc32.h new file mode 100644 index 0000000..e548cdc --- /dev/null +++ b/ttalib-1.1/crc32.h @@ -0,0 +1,114 @@ +/* + * crc32.h + * + * Description: CRC32 functions + * Developed by: Alexander Djourik + * Pavel Zhilin + * + * Copyright (c) 1999-2004 Alexander Djourik. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#ifndef CRC32_H +#define CRC32_H + +const unsigned long crc32_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +#define UPDATE_CRC32(x, crc) crc = \ + (((crc>>8) & 0x00FFFFFF) ^ crc32_table[(crc^x) & 0xFF]) + +static unsigned long +crc32 (unsigned char *buffer, unsigned long len) { + unsigned long i; + unsigned long crc = 0xFFFFFFFF; + + for (i = 0; i < len; i++) UPDATE_CRC32(buffer[i], crc); + + return (crc ^ 0xFFFFFFFF); +} + +#endif // CRC32_H diff --git a/ttalib-1.1/filters3.h b/ttalib-1.1/filters3.h new file mode 100644 index 0000000..cf53059 --- /dev/null +++ b/ttalib-1.1/filters3.h @@ -0,0 +1,115 @@ +/* + * filters.h + * + * Description: TTAv1 filters functions + * Developed by: Alexander Djourik + * Pavel Zhilin + * + * Copyright (c) 1999-2004 Alexander Djourik. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +///////// Filter Settings ////////// +static long flt_set [4][2] = { + {10,1}, {9,1}, {10,1}, {12,0} +}; + +static __inline void +memshl (register long *pA, register long *pB) { + *pA++ = *pB++; + *pA++ = *pB++; + *pA++ = *pB++; + *pA++ = *pB++; + *pA++ = *pB++; + *pA++ = *pB++; + *pA++ = *pB++; + *pA = *pB; +} + +__inline void +hybrid_filter (fltst *fs, long *in, long mode) { + register long *pA = fs->dl; + register long *pB = fs->qm; + register long *pM = fs->dx; + register long sum = fs->round; + + if (!fs->error) { + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; + sum += *pA++ * *pB, pB++; pM += 8; + } else if (fs->error < 0) { + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + sum += *pA++ * (*pB -= *pM++), pB++; + } else { + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + sum += *pA++ * (*pB += *pM++), pB++; + } + + *(pM-0) = ((*(pA-1) >> 30) | 1) << 2; + *(pM-1) = ((*(pA-2) >> 30) | 1) << 1; + *(pM-2) = ((*(pA-3) >> 30) | 1) << 1; + *(pM-3) = ((*(pA-4) >> 30) | 1); + + if (mode) { + *pA = *in; + *in -= (sum >> fs->shift); + fs->error = *in; + } else { + fs->error = *in; + *in += (sum >> fs->shift); + *pA = *in; + } + + if (fs->mutex) { + *(pA-1) = *(pA-0) - *(pA-1); + *(pA-2) = *(pA-1) - *(pA-2); + *(pA-3) = *(pA-2) - *(pA-3); + } + + memshl (fs->dl, fs->dl + 1); + memshl (fs->dx, fs->dx + 1); +} + +__inline void +filter_init (fltst *fs, long shift, long mode) { + memset (fs, 0, sizeof(fltst)); + fs->shift = shift; + fs->round = 1 << (shift - 1); + fs->mutex = mode; +} diff --git a/ttalib-1.1/ttacommon.h b/ttalib-1.1/ttacommon.h new file mode 100644 index 0000000..8d79230 --- /dev/null +++ b/ttalib-1.1/ttacommon.h @@ -0,0 +1,147 @@ +/* + * ttacommon.h + * + * Description: TTA library common definitions and prototypes + * + * Copyright (c) 2004 Alexander Djourik. All rights reserved. + * Copyright (c) 2004 Pavel Zhilin. All rights reserved. + * + */ + +/* + * 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 + * aint with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please see the file COPYING in this directory for full copyright + * information. + */ + +#ifndef TTACOMMON_H_ +#define TTACOMMON_H_ + +#define MAX_BPS 32 +#define FRAME_TIME 1.04489795918367346939 + +#define TTA1_SIGN 0x31415454 + +#define MAX_ORDER 16 +#define BIT_BUFFER_SIZE (1024*1024) + +#ifdef _BIG_ENDIAN + #define ENDSWAP_INT16(x) (((((x)>>8)&0xFF)|(((x)&0xFF)<<8))) + #define ENDSWAP_INT32(x) (((((x)>>24)&0xFF)|(((x)>>8)&0xFF00)|(((x)&0xFF00)<<8)|(((x)&0xFF)<<24))) +#else + #define ENDSWAP_INT16(x) (x) + #define ENDSWAP_INT32(x) (x) +#endif + +#define SWAP16(x) (\ + (((x)&(1<< 0))?(1<<15):0) | \ + (((x)&(1<< 1))?(1<<14):0) | \ + (((x)&(1<< 2))?(1<<13):0) | \ + (((x)&(1<< 3))?(1<<12):0) | \ + (((x)&(1<< 4))?(1<<11):0) | \ + (((x)&(1<< 5))?(1<<10):0) | \ + (((x)&(1<< 6))?(1<< 9):0) | \ + (((x)&(1<< 7))?(1<< 8):0) | \ + (((x)&(1<< 8))?(1<< 7):0) | \ + (((x)&(1<< 9))?(1<< 6):0) | \ + (((x)&(1<<10))?(1<< 5):0) | \ + (((x)&(1<<11))?(1<< 4):0) | \ + (((x)&(1<<12))?(1<< 3):0) | \ + (((x)&(1<<13))?(1<< 2):0) | \ + (((x)&(1<<14))?(1<< 1):0) | \ + (((x)&(1<<15))?(1<< 0):0)) + +#ifdef _WIN32 + #pragma pack(1) + #define __ATTRIBUTE_PACKED__ + typedef unsigned __int64 uint64; +#else + #define __ATTRIBUTE_PACKED__ __attribute__((packed)) + typedef unsigned long long uint64; +#endif + +#define PREDICTOR1(x, k) ((long)((((uint64)x << k) - x) >> k)) + +#define ENC(x) (((x)>0)?((x)<<1)-1:(-(x)<<1)) +#define DEC(x) (((x)&1)?(++(x)>>1):(-(x)>>1)) + +// basics structures definitions +struct adapt +{ + unsigned long k0; + unsigned long k1; + unsigned long sum0; + unsigned long sum1; +}; + +struct fltst +{ + long shift; + long round; + long error; + long mutex; + long qm[MAX_ORDER]; + long dx[MAX_ORDER]; + long dl[MAX_ORDER]; +}; + +struct encoder +{ + fltst fst; + adapt rice; + long last; +}; + +struct TTAHeader { + unsigned long TTAid; + unsigned short AudioFormat; + unsigned short NumChannels; + unsigned short BitsPerSample; + unsigned long SampleRate; + unsigned long DataLength; + unsigned long CRC32; +}; + +// ****************** static variables and structures ******************* +static const unsigned long bit_mask[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; +static const unsigned long bit_shift[] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0x80000000, 0x80000000, 0x80000000, 0x80000000 +}; +static const unsigned long *shift_16 = bit_shift + 4; + +void rice_init(adapt *rice, unsigned long k0, unsigned long k1); +void encoder_init(encoder *tta, long nch, long byte_size); + +#endif // TTACOMMON_H_