musepack_src_r495/0000775000000000000000000000000012765302354013027 5ustar rootrootmusepack_src_r495/Makefile.cvs0000664000000000000000000000004410613151105015241 0ustar rootrootdefault: all all: autoreconf -vif musepack_src_r495/wavcmp/0000775000000000000000000000000012765302354014324 5ustar rootrootmusepack_src_r495/wavcmp/Makefile.am0000664000000000000000000000034611234134160016347 0ustar rootrootAM_CPPFLAGS = -I$(top_srcdir)/libwavformat if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO bin_PROGRAMS = wavcmp wavcmp_SOURCES = wavcmp.c wavcmp_LDADD = $(top_builddir)/libwavformat/libwavformat.a musepack_src_r495/wavcmp/wavcmp.c0000664000000000000000000000706010612204267015761 0ustar rootroot/* * C Implementation: wavcmp * * Description: * * * Author: Nicolas Botti , (C) 2007 * * Copyright: See COPYING file that comes with this distribution * */ #include #include #include t_wav_uint32 wav_write(void* p_user_data, void const* p_buffer, t_wav_uint32 p_bytes) { return (t_wav_uint32) fwrite(p_buffer, 1, p_bytes, (FILE*) p_user_data); } t_wav_uint32 wav_seek(void* p_user_data, t_wav_uint32 p_position) { return (t_wav_uint32) !fseek((FILE*) p_user_data, p_position, SEEK_SET); } t_wav_uint32 wav_read(void * p_user_data,void * p_buffer,t_wav_uint32 p_bytes) { return (t_wav_uint32) fread(p_buffer, 1, p_bytes, (FILE*) p_user_data); } static void usage(const char *exename) { printf("Usage: %s []\n", exename); } int main(int argc, char **argv) { t_wav_output_file wav_output; t_wav_input_file wav_in_1; t_wav_input_file wav_in_2; int is_wav_output; int err; int total_samples, total_diff; if(4 < argc && argc < 3) { usage(argv[0]); return 0; } t_wav_input_file_callback wavi_fc; memset(&wav_in_1, 0, sizeof wav_in_1); wavi_fc.m_read = wav_read; wavi_fc.m_user_data = fopen(argv[1], "rb"); if(!wavi_fc.m_user_data) return 1; if (! waveformat_input_open(&wav_in_1, wavi_fc)) return 1; memset(&wav_in_2, 0, sizeof wav_in_2); wavi_fc.m_read = wav_read; wavi_fc.m_user_data = fopen(argv[2], "rb"); if(!wavi_fc.m_user_data) return 1; if (! waveformat_input_open(&wav_in_2, wavi_fc)) return 1; if (wav_in_1.m_channels != wav_in_2.m_channels) { printf("Channel number doesn't match\n"); return 1; } if (wav_in_1.m_samples_per_sec != wav_in_2.m_samples_per_sec) { printf("Sample rate doesn't match\n"); return 1; } if (wav_in_1.m_bits_per_sample != wav_in_2.m_bits_per_sample) { printf("Sample size doesn't match\n"); return 1; } if (wav_in_1.m_data_size != wav_in_2.m_data_size) { printf("File length doesn't match\n"); return 1; } is_wav_output = argc > 3; if(is_wav_output) { t_wav_output_file_callback wavo_fc; memset(&wav_output, 0, sizeof wav_output); wavo_fc.m_seek = wav_seek; wavo_fc.m_write = wav_write; wavo_fc.m_user_data = fopen(argv[3], "wb"); if(!wavo_fc.m_user_data) return 1; err = waveformat_output_open(&wav_output, wavo_fc, wav_in_1.m_channels, wav_in_1.m_bits_per_sample, 0, wav_in_1.m_samples_per_sec, wav_in_2.m_data_size); if(!err) return 1; } total_samples = 0; total_diff = 0; while(1) { short sample_buff[2][512]; unsigned int samples[2]; samples[0] = waveformat_input_process_int16(& wav_in_1, sample_buff[0], 512); samples[1] = waveformat_input_process_int16(& wav_in_2, sample_buff[1], 512); if (samples[0] != samples[1] || samples[0] == 0) break; int i = 0; for( ; i < samples[0]; i++) { sample_buff[0][i] -= sample_buff[1][i]; if (sample_buff[0][i]) { printf("diff @ sample %i channel %i : %i\n", (total_samples + i) / wav_in_1.m_channels, (total_samples + i) % wav_in_1.m_channels, sample_buff[0][i]); total_diff++; } } total_samples += samples[0]; if(is_wav_output) if(waveformat_output_process_int16(&wav_output, sample_buff[0], samples[0]) < 0) break; } if (total_diff != 0) printf("%i diff found\n", total_diff); else printf("no diff found\n"); waveformat_input_close(&wav_in_1); waveformat_input_close(&wav_in_2); fclose(wav_in_1.m_callback.m_user_data); fclose(wav_in_2.m_callback.m_user_data); if(is_wav_output) { waveformat_output_close(&wav_output); fclose(wav_output.m_callback.m_user_data); } return 0; } musepack_src_r495/wavcmp/CMakeLists.txt0000664000000000000000000000035511417031041017050 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/libwavformat) link_directories(${libmpc_BINARY_DIR}/libwavformat) add_executable(wavcmp wavcmp.c) target_link_libraries(wavcmp wavformat_static) install(TARGETS wavcmp RUNTIME DESTINATION bin) musepack_src_r495/libmpcdec/0000775000000000000000000000000012765302354014751 5ustar rootrootmusepack_src_r495/libmpcdec/mpc_bits_reader.h0000664000000000000000000001153311150567164020246 0ustar rootroot/* Copyright (c) 2007-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define MAX_ENUM 32 MPC_API int mpc_bits_get_block(mpc_bits_reader * r, mpc_block * p_block); mpc_int32_t mpc_bits_golomb_dec(mpc_bits_reader * r, const mpc_uint_t k); MPC_API unsigned int mpc_bits_get_size(mpc_bits_reader * r, mpc_uint64_t * p_size); mpc_uint32_t mpc_bits_log_dec(mpc_bits_reader * r, mpc_uint_t max); extern const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM]; extern const mpc_uint8_t Cnk_len[MAX_ENUM / 2][MAX_ENUM]; extern const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM]; // can read up to 31 bits static mpc_inline mpc_uint32_t mpc_bits_read(mpc_bits_reader * r, const unsigned int nb_bits) { mpc_uint32_t ret; r->buff -= (int)(r->count - nb_bits) >> 3; r->count = (r->count - nb_bits) & 0x07; ret = (r->buff[0] | (r->buff[-1] << 8)) >> r->count; if (nb_bits > (16 - r->count)) { ret |= (mpc_uint32_t)((r->buff[-2] << 16) | (r->buff[-3] << 24)) >> r->count; if (nb_bits > 24 && r->count != 0) ret |= r->buff[-4] << (32 - r->count); } return ret & ((1 << nb_bits) - 1); } // basic huffman decoding routine // works with maximum lengths up to 16 static mpc_inline mpc_int32_t mpc_bits_huff_dec(mpc_bits_reader * r, const mpc_huffman *Table) { mpc_uint16_t code; code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); while (code < Table->Code) Table++; r->buff -= (int)(r->count - Table->Length) >> 3; r->count = (r->count - Table->Length) & 0x07; return Table->Value; } static mpc_inline mpc_int32_t mpc_bits_can_dec(mpc_bits_reader * r, const mpc_can_data *can) { mpc_uint16_t code; mpc_huff_lut tmp; const mpc_huffman * Table; code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); tmp = can->lut[code >> (16 - LUT_DEPTH)]; if (tmp.Length != 0) { r->buff -= (int)(r->count - tmp.Length) >> 3; r->count = (r->count - tmp.Length) & 0x07; return tmp.Value; } Table = can->table + (unsigned char)tmp.Value; while (code < Table->Code) Table++; r->buff -= (int)(r->count - Table->Length) >> 3; r->count = (r->count - Table->Length) & 0x07; return can->sym[(Table->Value - (code >> (16 - Table->Length))) & 0xFF] ; } // LUT-based huffman decoding routine // works with maximum lengths up to 16 static mpc_inline mpc_int32_t mpc_bits_huff_lut(mpc_bits_reader * r, const mpc_lut_data *lut) { mpc_uint16_t code; mpc_huff_lut tmp; const mpc_huffman * Table; code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); tmp = lut->lut[code >> (16 - LUT_DEPTH)]; if (tmp.Length != 0) { r->buff -= (int)(r->count - tmp.Length) >> 3; r->count = (r->count - tmp.Length) & 0x07; return tmp.Value; } Table = lut->table + (unsigned char)tmp.Value; while (code < Table->Code) Table++; r->buff -= (int)(r->count - Table->Length) >> 3; r->count = (r->count - Table->Length) & 0x07; return Table->Value; } static mpc_inline mpc_uint32_t mpc_bits_enum_dec(mpc_bits_reader * r, mpc_uint_t k, mpc_uint_t n) { mpc_uint32_t bits = 0; mpc_uint32_t code; const mpc_uint32_t * C = Cnk[k-1]; code = mpc_bits_read(r, Cnk_len[k-1][n-1] - 1); if (code >= Cnk_lost[k-1][n-1]) code = ((code << 1) | mpc_bits_read(r, 1)) - Cnk_lost[k-1][n-1]; do { n--; if (code >= C[n]) { bits |= 1 << n; code -= C[n]; C -= MAX_ENUM; k--; } } while(k > 0); return bits; } musepack_src_r495/libmpcdec/mpc_bits_reader.c0000664000000000000000000002546411614327662020253 0ustar rootroot/* Copyright (c) 2007-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "internal.h" #include "huffman.h" #include "mpc_bits_reader.h" const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, {0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465}, {0, 0, 0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, 2300, 2600, 2925, 3276, 3654, 4060, 4495}, {0, 0, 0, 0, 1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465}, {0, 0, 0, 0, 0, 1, 6, 21, 56, 126, 252, 462, 792, 1287, 2002, 3003, 4368, 6188, 8568, 11628, 15504, 20349, 26334, 33649, 42504, 53130, 65780, 80730, 98280, 118755, 142506, 169911}, {0, 0, 0, 0, 0, 0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003, 5005, 8008, 12376, 18564, 27132, 38760, 54264, 74613, 100947, 134596, 177100, 230230, 296010, 376740, 475020, 593775, 736281}, {0, 0, 0, 0, 0, 0, 0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435, 11440, 19448, 31824, 50388, 77520, 116280, 170544, 245157, 346104, 480700, 657800, 888030, 1184040, 1560780, 2035800, 2629575}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870, 24310, 43758, 75582, 125970, 203490, 319770, 490314, 735471, 1081575, 1562275, 2220075, 3108105, 4292145, 5852925, 7888725}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92378, 167960, 293930, 497420, 817190, 1307504, 2042975, 3124550, 4686825, 6906900, 10015005, 14307150, 20160075}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758, 92378, 184756, 352716, 646646, 1144066, 1961256, 3268760, 5311735, 8436285, 13123110, 20030010, 30045015, 44352165}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 78, 364, 1365, 4368, 12376, 31824, 75582, 167960, 352716, 705432, 1352078, 2496144, 4457400, 7726160, 13037895, 21474180, 34597290, 54627300, 84672315}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 91, 455, 1820, 6188, 18564, 50388, 125970, 293930, 646646, 1352078, 2704156, 5200300, 9657700, 17383860, 30421755, 51895935, 86493225, 141120525}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 105, 560, 2380, 8568, 27132, 77520, 203490, 497420, 1144066, 2496144, 5200300, 10400600, 20058300, 37442160, 67863915, 119759850, 206253075}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 120, 680, 3060, 11628, 38760, 116280, 319770, 817190, 1961256, 4457400, 9657700, 20058300, 40116600, 77558760, 145422675, 265182525}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 136, 816, 3876, 15504, 54264, 170544, 490314, 1307504, 3268760, 7726160, 17383860, 37442160, 77558760, 155117520, 300540195}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 153, 969, 4845, 20349, 74613, 245157, 735471, 2042975, 5311735, 13037895, 30421755, 67863915, 145422675, 300540195} }; const mpc_uint8_t Cnk_len[MAX_ENUM / 2][MAX_ENUM] = { {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, {0, 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9}, {0, 0, 0, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13}, {0, 0, 0, 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, {0, 0, 0, 0, 0, 3, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18}, {0, 0, 0, 0, 0, 0, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20}, {0, 0, 0, 0, 0, 0, 0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22}, {0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 23, 24}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 25, 26, 26}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 28}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 29}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 16, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 28, 29}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 10, 12, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30} }; const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM] = { {0, 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, {0, 0, 1, 2, 6, 1, 11, 4, 28, 19, 9, 62, 50, 37, 23, 8, 120, 103, 85, 66, 46, 25, 3, 236, 212, 187, 161, 134, 106, 77, 47, 16}, {0, 0, 0, 0, 6, 12, 29, 8, 44, 8, 91, 36, 226, 148, 57, 464, 344, 208, 55, 908, 718, 508, 277, 24, 1796, 1496, 1171, 820, 442, 36, 3697, 3232}, {0, 0, 0, 0, 3, 1, 29, 58, 2, 46, 182, 17, 309, 23, 683, 228, 1716, 1036, 220, 3347, 2207, 877, 7529, 5758, 3734, 1434, 15218, 12293, 9017, 5363, 1303, 29576}, {0, 0, 0, 0, 0, 2, 11, 8, 2, 4, 50, 232, 761, 46, 1093, 3824, 2004, 7816, 4756, 880, 12419, 6434, 31887, 23032, 12406, 65292, 50342, 32792, 12317, 119638, 92233, 60768}, {0, 0, 0, 0, 0, 0, 1, 4, 44, 46, 50, 100, 332, 1093, 3187, 184, 4008, 14204, 5636, 26776, 11272, 56459, 30125, 127548, 85044, 31914, 228278, 147548, 49268, 454801, 312295, 142384}, {0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 182, 232, 332, 664, 1757, 4944, 13320, 944, 15148, 53552, 14792, 91600, 16987, 178184, 43588, 390776, 160546, 913112, 536372, 61352, 1564729, 828448}, {0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 91, 17, 761, 1093, 1757, 3514, 8458, 21778, 55490, 5102, 58654, 204518, 33974, 313105, 1015577, 534877, 1974229, 1086199, 4096463, 2535683, 499883, 6258916}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 36, 309, 46, 3187, 4944, 8458, 16916, 38694, 94184, 230358, 26868, 231386, 789648, 54177, 1069754, 3701783, 1481708, 6762211, 2470066, 13394357, 5505632}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 62, 226, 23, 1093, 184, 13320, 21778, 38694, 77388, 171572, 401930, 953086, 135896, 925544, 3076873, 8340931, 3654106, 13524422, 3509417, 22756699, 2596624}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 50, 148, 683, 3824, 4008, 944, 55490, 94184, 171572, 343144, 745074, 1698160, 3931208, 662448, 3739321, 12080252, 32511574, 12481564, 49545413, 5193248}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 57, 228, 2004, 14204, 15148, 5102, 230358, 401930, 745074, 1490148, 3188308, 7119516, 16170572, 3132677, 15212929, 47724503, 127314931, 42642616}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 464, 1716, 7816, 5636, 53552, 58654, 26868, 953086, 1698160, 3188308, 6376616, 13496132, 29666704, 66353813, 14457878, 62182381, 189497312}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 344, 1036, 4756, 26776, 14792, 204518, 231386, 135896, 3931208, 7119516, 13496132, 26992264, 56658968, 123012781, 3252931, 65435312}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 208, 220, 880, 11272, 91600, 33974, 789648, 925544, 662448, 16170572, 29666704, 56658968, 113317936, 236330717, 508019104}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 103, 55, 3347, 12419, 56459, 16987, 313105, 54177, 3076873, 3739321, 3132677, 66353813, 123012781, 236330717} }; static const mpc_uint8_t log2[32] = { 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6}; static const mpc_uint8_t log2_lost[32] = { 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31}; mpc_int32_t mpc_bits_golomb_dec(mpc_bits_reader * r, const mpc_uint_t k) { unsigned int l = 0; unsigned int code = r->buff[0] & ((1 << r->count) - 1); while( code == 0 ) { l += r->count; r->buff++; code = r->buff[0]; r->count = 8; } while( ((1 << (r->count - 1)) & code) == 0 ) { l++; r->count--; } r->count--; while( r->count < k ) { r->buff++; r->count += 8; code = (code << 8) | r->buff[0]; } r->count -= k; return (l << k) | ((code >> r->count) & ((1 << k) - 1)); } mpc_uint32_t mpc_bits_log_dec(mpc_bits_reader * r, mpc_uint_t max) { mpc_uint32_t value = 0; if (max == 0) return 0; if (log2[max - 1] > 1) value = mpc_bits_read(r, log2[max - 1] - 1); if (value >= log2_lost[max - 1]) value = ((value << 1) | mpc_bits_read(r, 1)) - log2_lost[max - 1]; return value; } unsigned int mpc_bits_get_size(mpc_bits_reader * r, mpc_uint64_t * p_size) { unsigned char tmp; mpc_uint64_t size = 0; unsigned int ret = 0; do { tmp = mpc_bits_read(r, 8); size = (size << 7) | (tmp & 0x7F); ret++; } while((tmp & 0x80)); *p_size = size; return ret; } int mpc_bits_get_block(mpc_bits_reader * r, mpc_block * p_block) { int size = 2; p_block->size = 0; p_block->key[0] = mpc_bits_read(r, 8); p_block->key[1] = mpc_bits_read(r, 8); size += mpc_bits_get_size(r, &(p_block->size)); if (p_block->size >= size) // check if the block size doesn't conflict with the header size p_block->size -= size; return size; } musepack_src_r495/libmpcdec/mpc_reader.c0000664000000000000000000001125411614327662017222 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file mpc_reader.c /// Contains implementations for simple file-based mpc_reader #include #include "internal.h" #include #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... typedef struct mpc_reader_stdio_t { FILE *p_file; int file_size; mpc_bool_t is_seekable; mpc_int32_t magic; } mpc_reader_stdio; /// mpc_reader callback implementations static mpc_int32_t read_stdio(mpc_reader *p_reader, void *ptr, mpc_int32_t size) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; return (mpc_int32_t) fread(ptr, 1, size, p_stdio->p_file); } static mpc_bool_t seek_stdio(mpc_reader *p_reader, mpc_int32_t offset) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return MPC_FALSE; return p_stdio->is_seekable ? fseek(p_stdio->p_file, offset, SEEK_SET) == 0 : MPC_FALSE; } static mpc_int32_t tell_stdio(mpc_reader *p_reader) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; return ftell(p_stdio->p_file); } static mpc_int32_t get_size_stdio(mpc_reader *p_reader) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; return p_stdio->file_size; } static mpc_bool_t canseek_stdio(mpc_reader *p_reader) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return MPC_FALSE; return p_stdio->is_seekable; } mpc_status mpc_reader_init_stdio_stream(mpc_reader * p_reader, FILE * p_file) { mpc_reader tmp_reader; mpc_reader_stdio *p_stdio; int err; p_stdio = NULL; memset(&tmp_reader, 0, sizeof tmp_reader); p_stdio = malloc(sizeof *p_stdio); if(!p_stdio) return MPC_STATUS_FAIL; memset(p_stdio, 0, sizeof *p_stdio); p_stdio->magic = STDIO_MAGIC; p_stdio->p_file = p_file; p_stdio->is_seekable = MPC_TRUE; err = fseek(p_stdio->p_file, 0, SEEK_END); if(err < 0) goto clean; err = ftell(p_stdio->p_file); if(err < 0) goto clean; p_stdio->file_size = err; err = fseek(p_stdio->p_file, 0, SEEK_SET); if(err < 0) goto clean; tmp_reader.data = p_stdio; tmp_reader.canseek = canseek_stdio; tmp_reader.get_size = get_size_stdio; tmp_reader.read = read_stdio; tmp_reader.seek = seek_stdio; tmp_reader.tell = tell_stdio; *p_reader = tmp_reader; return MPC_STATUS_OK; clean: if(p_stdio && p_stdio->p_file) fclose(p_stdio->p_file); free(p_stdio); return MPC_STATUS_FAIL; } mpc_status mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename) { FILE * stream = fopen(filename, "rb"); if (stream == NULL) return MPC_STATUS_FAIL; return mpc_reader_init_stdio_stream(p_reader,stream); } void mpc_reader_exit_stdio(mpc_reader *p_reader) { mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; if(p_stdio->magic != STDIO_MAGIC) return; fclose(p_stdio->p_file); free(p_stdio); p_reader->data = NULL; } musepack_src_r495/libmpcdec/ChangeLog0000664000000000000000000000244411151034026016511 0ustar rootroot1.3.0 * first sv8 release * major changes in the API (decoder and demuxer are split) 1.2.3 * Reduced memory usage and code size. Patch by Peter Pawlowski 1.2.2 * Fixed compilation under OpenBSD * Unix EOF again 1.2.1 * Warnings cleanup, patch by Tomas Salfischberger, Thom Johansen and Daniel Stenberg (Rockbox) * Mplayer interface, patch by Reimar Doffinger * Unix EOF everywhere 1.2 * 1.1.1 broke the API (BOOL type changed to mpc_bool_t). Version bumped to 1.2 to reflect the major change. Sorry to those who were caught by this error * Fixed relative/absolute includes (#include "stuff.h" in /include/mpcdec, #include in src/) * Added msvc project files * Changed mpc_reader_t structure, any specific data of the reader's implementations should be hidden behind the (void*) data pointer. (example in default implementation mpc_reader_file) * Renamed to libmpcdec (to make room for libmpcenc) 1.1.1 * fix for fixed-point mode bug 1.1 * add compliance & cleanup patches from Michael Roitzsch of xine project * switch to BSD license * port to pure C * add doxygen documentation * revise API somewhat 1.0.3 * autotools build process * sample binary added * floating-point mode by default musepack_src_r495/libmpcdec/COPYING0000664000000000000000000000303310526367046016005 0ustar rootrootCopyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. musepack_src_r495/libmpcdec/Makefile.am0000664000000000000000000000113712644540176017011 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif common_sources = ../common/crc32.c \ ../common/huffman-bcl.c METASOURCES = AUTO lib_LTLIBRARIES = libmpcdec.la libmpcdec_la_SOURCES = huffman.c mpc_decoder.c mpc_reader.c \ requant.c streaminfo.c synth_filter.c mpc_bits_reader.c mpc_demux.c \ mpc_bits_reader.h huffman.h decoder.h internal.h requant.h mpcdec_math.h \ $(common_sources) # version info shoud match the one in CMakeLists.txt libmpcdec_la_LDFLAGS = -no-undefined -version-info 7:0:1 libmpcdec_la_LIBADD = -lm musepack_src_r495/libmpcdec/mpcdec_math.h0000664000000000000000000001176011234562720017366 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file mpcdec_math.h /// Libmpcdec internal math routines. #ifndef _MPCDEC_MATH_H_ #define _MPCDEC_MATH_H_ #ifdef WIN32 #pragma once #endif #include #ifdef __cplusplus extern "C" { #endif #ifdef MPC_FIXED_POINT #ifdef _WIN32_WCE #include #define MPC_HAVE_MULHIGH #endif //in fixedpoint mode, results in decode output buffer are in -MPC_FIXED_POINT_SCALE ... MPC_FIXED_POINT_SCALE range typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY; #define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<> MPC_FIXED_POINT_FRACTPART) #define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) #ifdef _DEBUG static mpc_inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2) { MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2); assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); return (MPC_SAMPLE_FORMAT)temp; } static mpc_inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift) { MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_EX_NOTRUNCATE(item1,item2,shift); assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); return (MPC_SAMPLE_FORMAT)temp; } #else #define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y)) #define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z)) #endif #ifdef MPC_HAVE_MULHIGH #define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) #else #define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) #endif #define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) #define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) #define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) ( MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) << (Z) ) #define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) #define MPC_SCALE_CONST(X,Y,Z) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)) #define MPC_SCALE_CONST_SHL(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)-(S)) #define MPC_SCALE_CONST_SHR(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)+(S)) #define MPC_SHR(X,Y) ((X)>>(Y)) #define MPC_SHL(X,Y) ((X)<<(Y)) #else //in floating-point mode, decoded samples are in -1...1 range #define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X)) #define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X)) #define MPC_MULTIPLY_FRACT(X,Y) ((X)*(Y)) #define MPC_MAKE_FRACT_CONST(X) (X) #define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) #define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) #define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) #define MPC_MULTIPLY(X,Y) ((X)*(Y)) #define MPC_MULTIPLY_EX(X,Y,Z) ((X)*(Y)) #define MPC_SCALE_CONST(X,Y,Z) ((X)*(Y)) #define MPC_SCALE_CONST_SHL(X,Y,Z,S) ((X)*(Y)) #define MPC_SCALE_CONST_SHR(X,Y,Z,S) ((X)*(Y)) #define MPC_SHR(X,Y) (X) #define MPC_SHL(X,Y) (X) #endif #ifdef __cplusplus } #endif #endif musepack_src_r495/libmpcdec/huffman.c0000664000000000000000000005471211150567164016551 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file huffman.c /// Implementations of sv7/sv8 huffman decoding functions. #include "huffman.h" // sv7 huffman tables static const mpc_huffman mpc_table_HuffHdr [10] = { {0x8000, 1, 0}, {0x6000, 3, 1}, {0x5e00, 7, -4}, {0x5d80, 9, 3}, {0x5d00, 9, 4}, {0x5c00, 8, -5}, {0x5800, 6, 2}, {0x5000, 5, -3}, {0x4000, 4, -2}, {0x0, 2, -1} }; mpc_lut_data mpc_HuffHdr = {mpc_table_HuffHdr}; const mpc_huffman mpc_table_HuffSCFI [4] = { {0x8000, 1, 1}, {0x6000, 3, 2}, {0x4000, 3, 0}, {0x0, 2, 3} }; static const mpc_huffman mpc_table_HuffDSCF [16] = { {0xf800, 5, 5}, {0xf000, 5, -4}, {0xe000, 4, 3}, {0xd000, 4, -3}, {0xc000, 4, 8}, {0xa000, 3, 1}, {0x9000, 4, 0}, {0x8800, 5, -5}, {0x8400, 6, 7}, {0x8000, 6, -7}, {0x6000, 3, -1}, {0x4000, 3, 2}, {0x3000, 4, 4}, {0x2800, 5, 6}, {0x2000, 5, -6}, {0x0, 3, -2} }; mpc_lut_data mpc_HuffDSCF = {mpc_table_HuffDSCF}; static const mpc_huffman mpc_table_HuffQ1 [2] [27] = { { {0xe000, 3, 13}, {0xdc00, 6, 26}, {0xd800, 6, 0}, {0xd400, 6, 20}, {0xd000, 6, 6}, {0xc000, 4, 14}, {0xb000, 4, 12}, {0xa000, 4, 4}, {0x9000, 4, 22}, {0x8c00, 6, 8}, {0x8800, 6, 18}, {0x8400, 6, 24}, {0x8000, 6, 2}, {0x7000, 4, 16}, {0x6000, 4, 10}, {0x5800, 5, 17}, {0x5000, 5, 9}, {0x4800, 5, 1}, {0x4000, 5, 25}, {0x3800, 5, 5}, {0x3000, 5, 21}, {0x2800, 5, 3}, {0x2000, 5, 11}, {0x1800, 5, 15}, {0x1000, 5, 23}, {0x800, 5, 19}, {0x0, 5, 7} }, { {0x8000, 1, 13}, {0x7e00, 7, 15}, {0x7c00, 7, 1}, {0x7a00, 7, 11}, {0x7800, 7, 7}, {0x7600, 7, 17}, {0x7400, 7, 25}, {0x7200, 7, 19}, {0x7180, 9, 8}, {0x7100, 9, 18}, {0x7080, 9, 2}, {0x7000, 9, 24}, {0x6e00, 7, 3}, {0x6c00, 7, 23}, {0x6a00, 7, 21}, {0x6800, 7, 5}, {0x6700, 8, 0}, {0x6600, 8, 26}, {0x6500, 8, 6}, {0x6400, 8, 20}, {0x6000, 6, 9}, {0x5000, 4, 14}, {0x4000, 4, 12}, {0x3000, 4, 4}, {0x2000, 4, 22}, {0x1000, 4, 16}, {0x0, 4, 10} } }; static const mpc_huffman mpc_table_HuffQ2 [2] [25] = { { {0xf000, 4, 13}, {0xe000, 4, 17}, {0xd000, 4, 7}, {0xc000, 4, 11}, {0xbc00, 6, 1}, {0xb800, 6, 23}, {0xb600, 7, 4}, {0xb400, 7, 20}, {0xb200, 7, 0}, {0xb000, 7, 24}, {0xa800, 5, 22}, {0xa000, 5, 10}, {0x8000, 3, 12}, {0x7800, 5, 2}, {0x7000, 5, 14}, {0x6000, 4, 6}, {0x5000, 4, 18}, {0x4000, 4, 8}, {0x3000, 4, 16}, {0x2800, 5, 9}, {0x2000, 5, 5}, {0x1800, 5, 15}, {0x1000, 5, 21}, {0x800, 5, 19}, {0x0, 5, 3} }, { {0xf800, 5, 18}, {0xf000, 5, 6}, {0xe800, 5, 8}, {0xe700, 8, 3}, {0xe6c0, 10, 24}, {0xe680, 10, 4}, {0xe640, 10, 0}, {0xe600, 10, 20}, {0xe400, 7, 23}, {0xe200, 7, 1}, {0xe000, 7, 19}, {0xd800, 5, 16}, {0xd600, 7, 15}, {0xd400, 7, 21}, {0xd200, 7, 9}, {0xd000, 7, 5}, {0xcc00, 6, 2}, {0xc800, 6, 10}, {0xc400, 6, 14}, {0xc000, 6, 22}, {0x8000, 2, 12}, {0x6000, 3, 13}, {0x4000, 3, 17}, {0x2000, 3, 11}, {0x0, 3, 7} } }; static const mpc_huffman mpc_table_HuffQ3 [2] [7] = { { {0xe000, 3, 1}, {0xd000, 4, 3}, {0xc000, 4, -3}, {0xa000, 3, 2}, {0x8000, 3, -2}, {0x4000, 2, 0}, {0x0, 2, -1} }, { {0xc000, 2, 0}, {0x8000, 2, -1}, {0x4000, 2, 1}, {0x3000, 4, -2}, {0x2800, 5, 3}, {0x2000, 5, -3}, {0x0, 3, 2} } }; static const mpc_huffman mpc_table_HuffQ4 [2] [9] = { { {0xe000, 3, 0}, {0xc000, 3, -1}, {0xa000, 3, 1}, {0x8000, 3, -2}, {0x6000, 3, 2}, {0x5000, 4, -4}, {0x4000, 4, 4}, {0x2000, 3, 3}, {0x0, 3, -3} }, { {0xe000, 3, 1}, {0xd000, 4, 2}, {0xc000, 4, -3}, {0x8000, 2, 0}, {0x6000, 3, -2}, {0x5000, 4, 3}, {0x4800, 5, -4}, {0x4000, 5, 4}, {0x0, 2, -1} } }; static const mpc_huffman mpc_table_HuffQ5 [2] [15] = { { {0xf000, 4, 2}, {0xe800, 5, 5}, {0xe400, 6, -7}, {0xe000, 6, 7}, {0xd000, 4, -3}, {0xc000, 4, 3}, {0xb800, 5, -6}, {0xb000, 5, 6}, {0xa000, 4, -4}, {0x9000, 4, 4}, {0x8000, 4, -5}, {0x6000, 3, 0}, {0x4000, 3, -1}, {0x2000, 3, 1}, {0x0, 3, -2} }, { {0xf000, 4, 3}, {0xe800, 5, 4}, {0xe600, 7, 6}, {0xe500, 8, -7}, {0xe400, 8, 7}, {0xe000, 6, -6}, {0xc000, 3, 0}, {0xa000, 3, -1}, {0x8000, 3, 1}, {0x6000, 3, -2}, {0x4000, 3, 2}, {0x3800, 5, -5}, {0x3000, 5, 5}, {0x2000, 4, -4}, {0x0, 3, -3} } }; static const mpc_huffman mpc_table_HuffQ6 [2] [31] = { { {0xf800, 5, 3}, {0xf000, 5, -4}, {0xec00, 6, -11}, {0xe800, 6, 12}, {0xe000, 5, 4}, {0xd800, 5, 6}, {0xd000, 5, -5}, {0xc800, 5, 5}, {0xc000, 5, 7}, {0xb800, 5, -7}, {0xb400, 6, -12}, {0xb000, 6, -13}, {0xa800, 5, -6}, {0xa000, 5, 8}, {0x9800, 5, -8}, {0x9000, 5, 9}, {0x8800, 5, -9}, {0x8400, 6, 13}, {0x8200, 7, -15}, {0x8000, 7, 15}, {0x7000, 4, 0}, {0x6800, 5, -10}, {0x6000, 5, 10}, {0x5000, 4, -1}, {0x4000, 4, 2}, {0x3000, 4, 1}, {0x2000, 4, -2}, {0x1c00, 6, 14}, {0x1800, 6, -14}, {0x1000, 5, 11}, {0x0, 4, -3} }, { {0xf800, 5, -6}, {0xf000, 5, 6}, {0xe000, 4, 1}, {0xd000, 4, -1}, {0xce00, 7, 10}, {0xcc00, 7, -10}, {0xcb00, 8, -11}, {0xca80, 9, -12}, {0xca60, 11, 13}, {0xca58, 13, 15}, {0xca50, 13, -14}, {0xca48, 13, 14}, {0xca40, 13, -15}, {0xca00, 10, -13}, {0xc900, 8, 11}, {0xc800, 8, 12}, {0xc400, 6, -9}, {0xc000, 6, 9}, {0xb000, 4, -2}, {0xa000, 4, 2}, {0x9000, 4, 3}, {0x8000, 4, -3}, {0x7800, 5, -7}, {0x7000, 5, 7}, {0x6000, 4, -4}, {0x5000, 4, 4}, {0x4800, 5, -8}, {0x4000, 5, 8}, {0x3000, 4, 5}, {0x2000, 4, -5}, {0x0, 3, 0} } }; static const mpc_huffman mpc_table_HuffQ7 [2] [63] = { { {0xfc00, 6, 7}, {0xf800, 6, 8}, {0xf400, 6, 9}, {0xf000, 6, -8}, {0xec00, 6, 11}, {0xea00, 7, 21}, {0xe900, 8, -28}, {0xe800, 8, 28}, {0xe400, 6, -9}, {0xe200, 7, -22}, {0xe000, 7, -21}, {0xdc00, 6, -10}, {0xd800, 6, -11}, {0xd400, 6, 10}, {0xd000, 6, 12}, {0xcc00, 6, -13}, {0xca00, 7, 22}, {0xc800, 7, 23}, {0xc400, 6, -12}, {0xc000, 6, 13}, {0xbc00, 6, 14}, {0xb800, 6, -14}, {0xb600, 7, -23}, {0xb500, 8, -29}, {0xb400, 8, 29}, {0xb000, 6, -15}, {0xac00, 6, 15}, {0xa800, 6, 16}, {0xa400, 6, -16}, {0xa200, 7, -24}, {0xa000, 7, 24}, {0x9c00, 6, 17}, {0x9a00, 7, -25}, {0x9900, 8, -30}, {0x9800, 8, 30}, {0x9400, 6, -17}, {0x9000, 6, 18}, {0x8c00, 6, -18}, {0x8a00, 7, 25}, {0x8800, 7, 26}, {0x8400, 6, 19}, {0x8200, 7, -26}, {0x8000, 7, -27}, {0x7800, 5, 2}, {0x7400, 6, -19}, {0x7000, 6, 20}, {0x6800, 5, -1}, {0x6700, 8, -31}, {0x6600, 8, 31}, {0x6400, 7, 27}, {0x6000, 6, -20}, {0x5800, 5, 1}, {0x5000, 5, -5}, {0x4800, 5, -3}, {0x4000, 5, 3}, {0x3800, 5, 0}, {0x3000, 5, -2}, {0x2800, 5, -4}, {0x2000, 5, 4}, {0x1800, 5, 5}, {0x1000, 5, -6}, {0x800, 5, 6}, {0x0, 5, -7} }, { {0xf800, 5, -1}, {0xf000, 5, 2}, {0xe800, 5, -2}, {0xe000, 5, 3}, {0xdf00, 8, -20}, {0xdec0, 10, 24}, {0xdebc, 14, 28}, {0xdeb8, 14, -28}, {0xdeb4, 14, -30}, {0xdeb0, 14, 30}, {0xdea0, 12, -27}, {0xde9c, 14, 29}, {0xde98, 14, -29}, {0xde94, 14, 31}, {0xde90, 14, -31}, {0xde80, 12, 27}, {0xde00, 9, -22}, {0xdc00, 7, -17}, {0xd800, 6, -11}, {0xd000, 5, -3}, {0xc800, 5, 4}, {0xc000, 5, -4}, {0xbe00, 7, 17}, {0xbd00, 8, 20}, {0xbc80, 9, 22}, {0xbc40, 10, -25}, {0xbc00, 10, -26}, {0xb800, 6, 12}, {0xb000, 5, 5}, {0xa800, 5, -5}, {0xa000, 5, 6}, {0x9800, 5, -6}, {0x9400, 6, -12}, {0x9200, 7, -18}, {0x9000, 7, 18}, {0x8c00, 6, 13}, {0x8800, 6, -13}, {0x8000, 5, -7}, {0x7c00, 6, 14}, {0x7b00, 8, 21}, {0x7a00, 8, -21}, {0x7800, 7, -19}, {0x7000, 5, 7}, {0x6800, 5, 8}, {0x6400, 6, -14}, {0x6000, 6, -15}, {0x5800, 5, -8}, {0x5400, 6, 15}, {0x5200, 7, 19}, {0x51c0, 10, 25}, {0x5180, 10, 26}, {0x5100, 9, -23}, {0x5080, 9, 23}, {0x5000, 9, -24}, {0x4800, 5, -9}, {0x4000, 5, 9}, {0x3c00, 6, 16}, {0x3800, 6, -16}, {0x3000, 5, 10}, {0x2000, 4, 0}, {0x1800, 5, -10}, {0x1000, 5, 11}, {0x0, 4, 1} } }; mpc_lut_data mpc_HuffQ [7] [2] = { {{mpc_table_HuffQ1[0]}, {mpc_table_HuffQ1[1]}}, {{mpc_table_HuffQ2[0]}, {mpc_table_HuffQ2[1]}}, {{mpc_table_HuffQ3[0]}, {mpc_table_HuffQ3[1]}}, {{mpc_table_HuffQ4[0]}, {mpc_table_HuffQ4[1]}}, {{mpc_table_HuffQ5[0]}, {mpc_table_HuffQ5[1]}}, {{mpc_table_HuffQ6[0]}, {mpc_table_HuffQ6[1]}}, {{mpc_table_HuffQ7[0]}, {mpc_table_HuffQ7[1]}} }; // sv8 huffman tables static const mpc_huffman mpc_huff_SCFI_1 [3] = { {0x8000, 1, 1}, {0x4000, 2, 2}, {0x0, 3, 3} }; // 3 static const mpc_int8_t mpc_sym_SCFI_1 [4] = { 2, 3, 1, 0 }; static const mpc_huffman mpc_huff_SCFI_2 [5] = { {0x8000, 2, 3}, {0x4000, 3, 5}, {0x1800, 5, 11}, {0x400, 6, 14}, {0x0, 7, 15} }; // 5 static const mpc_int8_t mpc_sym_SCFI_2 [16] = { 15, 10, 14, 11, 13, 9, 7, 6, 5, 12, 8, 3, 2, 0, 4, 1 }; mpc_can_data mpc_can_SCFI[2] = {{mpc_huff_SCFI_1, mpc_sym_SCFI_1}, {mpc_huff_SCFI_2, mpc_sym_SCFI_2}}; static const mpc_huffman mpc_huff_DSCF_1 [12] = { {0xa000, 3, 7}, {0x4000, 4, 12}, {0x2800, 5, 16}, {0x1800, 6, 21}, {0xe00, 7, 27}, {0x700, 8, 34}, {0x380, 9, 41}, {0x140, 10, 48}, {0x80, 11, 53}, {0x30, 12, 57}, {0x18, 13, 60}, {0x0, 14, 63} }; // 12 static const mpc_int8_t mpc_sym_DSCF_1 [64] = { 35, 34, 33, 36, 32, 30, 29, 27, 26, 37, 28, 25, 39, 38, 24, 23, 40, 22, 21, 20, 19, 43, 42, 41, 18, 17, 16, 15, 46, 45, 44, 14, 13, 12, 11, 49, 48, 47, 31, 10, 9, 8, 7, 6, 52, 51, 50, 5, 4, 3, 54, 53, 2, 1, 0, 57, 56, 55, 63, 62, 61, 60, 59, 58 }; static const mpc_huffman mpc_huff_DSCF_2 [13] = { {0x6000, 3, 7}, {0x3000, 4, 10}, {0x1800, 5, 13}, {0x1000, 6, 16}, {0xa00, 7, 20}, {0x600, 8, 25}, {0x380, 9, 31}, {0x1c0, 10, 38}, {0xe0, 11, 45}, {0x50, 12, 52}, {0x20, 13, 57}, {0xc, 14, 61}, {0x0, 15, 64} }; // 13 static const mpc_int8_t mpc_sym_DSCF_2 [65] = { 33, 32, 31, 30, 29, 34, 28, 27, 36, 35, 26, 37, 25, 38, 24, 23, 40, 39, 22, 21, 42, 41, 20, 19, 18, 45, 44, 43, 17, 16, 15, 14, 48, 47, 46, 13, 12, 11, 10, 64, 52, 51, 50, 49, 9, 8, 7, 6, 55, 54, 53, 5, 4, 3, 58, 57, 56, 2, 1, 63, 62, 61, 60, 59, 0 }; mpc_can_data mpc_can_DSCF[2] = {{mpc_huff_DSCF_1, mpc_sym_DSCF_1}, {mpc_huff_DSCF_2, mpc_sym_DSCF_2}}; static const mpc_huffman mpc_huff_Bands [12] = { {0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 5, 6}, {0x800, 6, 8}, {0x600, 7, 10}, {0x300, 8, 13}, {0x200, 9, 16}, {0x140, 10, 20}, {0xc0, 11, 25}, {0x10, 12, 31}, {0x0, 13, 32} }; // 12 static const mpc_int8_t mpc_sym_Bands [33] = { 0, 32, 1, 31, 2, 30, 3, 4, 29, 6, 5, 28, 7, 27, 26, 8, 25, 24, 23, 9, 22, 21, 20, 18, 17, 16, 15, 14, 12, 11, 10, 19, 13 }; mpc_can_data mpc_can_Bands = {mpc_huff_Bands, mpc_sym_Bands}; static const mpc_huffman mpc_huff_Res_1 [16] = { {0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 4, 4}, {0x800, 5, 5}, {0x400, 6, 6}, {0x200, 7, 7}, {0x100, 8, 8}, {0x80, 9, 9}, {0x40, 10, 10}, {0x20, 11, 11}, {0x10, 12, 12}, {0x8, 13, 13}, {0x4, 14, 14}, {0x2, 15, 15}, {0x0, 16, 16} }; // 16 static const mpc_int8_t mpc_sym_Res_1 [17] = { 0, 1, 16, 2, 3, 4, 5, 15, 6, 7, 8, 9, 10, 11, 12, 14, 13 }; static const mpc_huffman mpc_huff_Res_2 [12] = { {0x4000, 2, 3}, {0x2000, 3, 4}, {0x1000, 4, 5}, {0x800, 5, 6}, {0x400, 6, 7}, {0x200, 7, 8}, {0x100, 8, 9}, {0x80, 9, 10}, {0x40, 10, 11}, {0x20, 11, 12}, {0x10, 12, 13}, {0x0, 14, 16} }; // 12 static const mpc_int8_t mpc_sym_Res_2 [17] = { 16, 1, 0, 2, 15, 3, 14, 4, 5, 13, 6, 12, 7, 11, 10, 9, 8 }; mpc_can_data mpc_can_Res[2] = {{mpc_huff_Res_1, mpc_sym_Res_1}, {mpc_huff_Res_2, mpc_sym_Res_2}}; static const mpc_huffman mpc_huff_Q1 [10] = { {0x6000, 3, 7}, {0x1000, 4, 10}, {0x800, 5, 11}, {0x400, 6, 12}, {0x200, 7, 13}, {0x100, 8, 14}, {0x80, 9, 15}, {0x40, 10, 16}, {0x20, 11, 17}, {0x0, 12, 18} }; // 10 static const mpc_int8_t mpc_sym_Q1 [19] = { 7, 6, 5, 4, 3, 10, 9, 8, 2, 1, 11, 0, 12, 13, 14, 15, 16, 18, 17 }; mpc_can_data mpc_can_Q1 = {mpc_huff_Q1, mpc_sym_Q1}; static const mpc_huffman mpc_huff_Q2_1 [10] = { {0xe000, 3, 7}, {0x8000, 4, 14}, {0x3c00, 6, 38}, {0x2a00, 7, 53}, {0x1200, 8, 74}, {0x600, 9, 92}, {0x3c0, 10, 104}, {0x60, 11, 119}, {0x20, 12, 122}, {0x0, 13, 124} }; // 10 static const mpc_int8_t mpc_sym_Q2_1 [125] = { 62, 87, 67, 63, 61, 57, 37, 93, 92, 88, 86, 83, 82, 81, 68, 66, 58, 56, 42, 41, 38, 36, 32, 31, 112, 91, 72, 64, 60, 52, 43, 33, 12, 117, 113, 111, 107, 97, 89, 85, 77, 73, 71, 69, 65, 59, 55, 53, 51, 47, 39, 35, 27, 17, 13, 11, 7, 118, 116, 108, 106, 98, 96, 94, 90, 84, 80, 78, 76, 48, 46, 44, 40, 34, 30, 28, 26, 18, 16, 8, 6, 122, 110, 102, 74, 70, 54, 50, 22, 2, 123, 121, 119, 115, 114, 109, 105, 103, 101, 99, 95, 79, 75, 49, 45, 29, 25, 23, 21, 19, 15, 14, 10, 9, 5, 3, 1, 124, 104, 20, 0, 120, 100, 24, 4 }; static const mpc_huffman mpc_huff_Q2_2 [9] = { {0xf000, 4, 15}, {0x7000, 5, 30}, {0x4800, 6, 44}, {0x3c00, 7, 62}, {0xc00, 8, 92}, {0x780, 9, 104}, {0xc0, 10, 119}, {0x40, 11, 122}, {0x0, 12, 124} }; // 9 static const mpc_int8_t mpc_sym_Q2_2 [125] = { 62, 92, 87, 86, 82, 68, 67, 66, 63, 61, 58, 57, 56, 42, 38, 37, 32, 93, 91, 88, 83, 81, 43, 41, 36, 33, 31, 112, 72, 64, 60, 52, 12, 118, 117, 116, 113, 111, 108, 107, 106, 98, 97, 96, 94, 90, 89, 85, 84, 80, 78, 77, 76, 73, 71, 69, 65, 59, 55, 53, 51, 48, 47, 46, 44, 40, 39, 35, 34, 30, 28, 27, 26, 18, 17, 16, 13, 11, 8, 7, 6, 122, 110, 74, 70, 54, 50, 22, 14, 2, 123, 121, 119, 115, 114, 109, 105, 103, 102, 101, 99, 95, 79, 75, 49, 45, 29, 25, 23, 21, 19, 15, 10, 9, 5, 3, 1, 124, 104, 20, 0, 120, 100, 24, 4 }; static const mpc_huffman mpc_huff_Q3 [7] = { {0xe000, 3, 7}, {0x8000, 4, 14}, {0x5000, 5, 22}, {0x2400, 6, 32}, {0xa00, 7, 41}, {0x200, 8, 46}, {0x0, 9, 48} }; // 7 static const mpc_int8_t mpc_sym_Q3 [49] = { 0, 17, 16, 1, 15, -16, -1, 32, 31, 2, 14, -15, -32, 34, 33, 47, 46, 18, 30, -14, -2, -31, -17, -18, 49, 48, 63, 19, 29, 3, 13, -13, -3, -30, -47, -48, -33, 50, 62, 35, 45, -29, -19, -46, -34, 51, 61, -45, -35 }; static const mpc_huffman mpc_huff_Q4 [8] = { {0xf000, 4, 15}, {0x9000, 5, 30}, {0x3400, 6, 48}, {0x1800, 7, 61}, {0x500, 8, 73}, {0x100, 9, 78}, {0x0, 10, 80}, {0x0, 0, 90} }; // 8 static const mpc_int8_t mpc_sym_Q4 [91] = { 0, 32, 17, 16, 31, 2, 1, 15, 14, -15, -16, -1, -32, 49, 48, 34, 33, 47, 46, 19, 18, 30, 29, 3, 13, -13, -14, -2, -3, -30, -31, -17, -18, -47, -48, -33, 64, 50, 63, 62, 35, 45, 4, 12, -29, -19, -46, -34, -64, -49, 66, 65, 79, 78, 51, 61, 36, 44, 20, 28, -12, -4, -28, -20, -45, -35, -62, -63, -50, 67, 77, 52, 60, -44, -36, -61, -51, 68, 76, -60, -52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const mpc_huffman mpc_huff_Q5_1 [6] = { {0xc000, 2, 3}, {0x4000, 3, 6}, {0x2000, 4, 8}, {0x1000, 5, 10}, {0x800, 6, 12}, {0x0, 7, 14} }; // 6 static const mpc_int8_t mpc_sym_Q5_1 [15] = { 0, 2, 1, -1, -2, 3, -3, 4, -4, 5, -5, 7, 6, -6, -7 }; static const mpc_huffman mpc_huff_Q5_2 [4] = { {0x6000, 3, 7}, {0x2000, 4, 10}, {0x1000, 5, 12}, {0x0, 6, 14} }; // 4 static const mpc_int8_t mpc_sym_Q5_2 [15] = { 2, 1, 0, -1, -2, 4, 3, -3, -4, 5, -5, 7, 6, -6, -7 }; static const mpc_huffman mpc_huff_Q6_1 [8] = { {0xc000, 2, 3}, {0x8000, 3, 6}, {0x4000, 4, 10}, {0x2800, 5, 14}, {0xc00, 6, 19}, {0x800, 7, 22}, {0x400, 8, 26}, {0x0, 9, 30} }; // 8 static const mpc_int8_t mpc_sym_Q6_1 [31] = { 0, 1, -1, 3, 2, -2, -3, 4, -4, -5, 8, 7, 6, 5, -6, -7, -8, 9, -9, 11, 10, -10, -11, 15, 14, 13, 12, -12, -13, -14, -15 }; static const mpc_huffman mpc_huff_Q6_2 [5] = { {0x5000, 4, 15}, {0x2000, 5, 20}, {0x1000, 6, 24}, {0x400, 7, 28}, {0x0, 8, 30} }; // 5 static const mpc_int8_t mpc_sym_Q6_2 [31] = { 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, 8, 7, 6, -6, -7, -8, 10, 9, -9, -10, 13, 12, 11, -11, -12, -13, 15, 14, -14, -15 }; static const mpc_huffman mpc_huff_Q7_1 [9] = { {0xc000, 2, 3}, {0x8000, 3, 6}, {0x6000, 4, 10}, {0x4000, 5, 16}, {0x2800, 6, 24}, {0x1400, 7, 34}, {0xa00, 8, 44}, {0x400, 9, 54}, {0x0, 10, 62} }; // 9 static const mpc_int8_t mpc_sym_Q7_1 [63] = { 0, 1, -1, 2, -2, 4, 3, -3, -4, 7, 6, 5, -5, -6, -7, 13, 11, 10, 9, 8, -8, -9, -10, -11, -12, 17, 16, 15, 14, 12, -13, -14, -15, -16, -17, 28, 27, 21, 20, 19, 18, -18, -19, -20, -21, -27, -28, 31, 30, 29, 26, 25, 24, 23, 22, -22, -23, -24, -25, -26, -29, -30, -31 }; static const mpc_huffman mpc_huff_Q7_2 [5] = { {0x6000, 5, 31}, {0x2400, 6, 43}, {0x1000, 7, 52}, {0x200, 8, 60}, {0x0, 9, 62} }; // 5 static const mpc_int8_t mpc_sym_Q7_2 [63] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 17, 16, 15, 14, 13, 12, 11, -10, -11, -12, -13, -14, -15, -16, -17, 22, 21, 20, 19, 18, -18, -19, -20, -21, -22, 29, 28, 27, 26, 25, 24, 23, -23, -24, -25, -26, -27, -28, -29, 31, 30, -30, -31 }; static const mpc_huffman mpc_huff_Q8_1 [11] = { {0xc000, 2, 3}, {0x8000, 3, 6}, {0x7000, 4, 10}, {0x5800, 5, 17}, {0x3800, 6, 28}, {0x2800, 7, 42}, {0x1900, 8, 62}, {0xd00, 9, 87}, {0x280, 10, 113}, {0x60, 11, 123}, {0x0, 12, 126} }; // 11 static const mpc_int8_t mpc_sym_Q8_1 [127] = { 0, 1, -1, -2, 3, 2, -3, 7, 6, 5, 4, -4, -5, -6, -7, 11, 10, 9, 8, -8, -9, -10, -11, 19, 18, 17, 16, 15, 14, 13, 12, -12, -13, -14, -15, -16, -17, -19, 56, 55, 31, 28, 27, 26, 25, 24, 23, 22, 21, 20, -18, -20, -21, -22, -23, -24, -25, -26, -27, -33, -54, -56, 63, 62, 61, 60, 59, 58, 57, 54, 53, 43, 40, 39, 38, 37, 36, 35, 34, 33, 32, 30, 29, -28, -29, -30, -31, -32, -34, -35, -36, -37, -38, -39, -40, -41, -43, -53, -55, -57, -58, -59, -60, -61, 49, 47, 46, 45, 44, 42, 41, -42, -44, -45, -46, -47, -48, -49, -50, -62, -63, 52, 51, 50, 48, -51, -52 }; static const mpc_huffman mpc_huff_Q8_2 [4] = { {0x9800, 6, 63}, {0x2a00, 7, 101}, {0x400, 8, 122}, {0x0, 9, 126} }; // 4 static const mpc_int8_t mpc_sym_Q8_2 [127] = { 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 12, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -40, -41, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, -42, -43, -44, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, 63, 62, 61, 60, -60, -61, -62, -63 }; static const mpc_huffman mpc_huff_Q9up [6] = { {0xf800, 6, 63}, {0xac00, 7, 125}, {0x2600, 8, -45}, {0x280, 9, -7}, {0x40, 10, -2}, {0x0, 11, -1} }; // 6 static const mpc_int8_t mpc_sym_Q9up [256] = { -128, 127, -108, -110, -111, -112, -113, -114, -115, -116, -117, -118, -119, -120, -121, -122, -123, -124, -125, -126, -127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, -44, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -82, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -109, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 40, 20, 19, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, 41, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, -3, -4, -5, -6, 4, 3, 2, 1, 0, -1, -2 }; mpc_can_data mpc_can_Q9up = {mpc_huff_Q9up, mpc_sym_Q9up}; mpc_can_data mpc_can_Q [6][2] = { {{mpc_huff_Q2_1, mpc_sym_Q2_1}, {mpc_huff_Q2_2, mpc_sym_Q2_2}}, {{mpc_huff_Q3, mpc_sym_Q3}, {mpc_huff_Q4, mpc_sym_Q4}}, {{mpc_huff_Q5_1, mpc_sym_Q5_1}, {mpc_huff_Q5_2, mpc_sym_Q5_2}}, {{mpc_huff_Q6_1, mpc_sym_Q6_1}, {mpc_huff_Q6_2, mpc_sym_Q6_2}}, {{mpc_huff_Q7_1, mpc_sym_Q7_1}, {mpc_huff_Q7_2, mpc_sym_Q7_2}}, {{mpc_huff_Q8_1, mpc_sym_Q8_1}, {mpc_huff_Q8_2, mpc_sym_Q8_2}} }; static void huff_fill_lut(const mpc_huffman * table, mpc_huff_lut * lut, const int bits) { int i, idx = 0; const int shift = 16 - bits; for (i = (1 << bits) - 1; i >= 0 ; i--) { if ((table[idx].Code >> shift) < i) { lut[i].Length = table[idx].Length; lut[i].Value = table[idx].Value; } else { if (table[idx].Length <= bits) { lut[i].Length = table[idx].Length; lut[i].Value = table[idx].Value; } else { lut[i].Length = 0; lut[i].Value = idx; } if (i != 0) do { idx++; } while ((table[idx].Code >> shift) == i); } } } static void can_fill_lut(mpc_can_data * data, const int bits) { int i, idx = 0; const int shift = 16 - bits; const mpc_huffman * table = data->table; const mpc_int8_t * sym = data->sym; mpc_huff_lut * lut = data->lut; for (i = (1 << bits) - 1; i >= 0 ; i--) { if ((table[idx].Code >> shift) < i) { if (table[idx].Length <= bits) { lut[i].Length = table[idx].Length; lut[i].Value = sym[(table[idx].Value - (i >> (bits - table[idx].Length))) & 0xFF]; } else { lut[i].Length = 0; lut[i].Value = idx; } } else { if (table[idx].Length <= bits) { lut[i].Length = table[idx].Length; lut[i].Value = sym[(table[idx].Value - (i >> (bits - table[idx].Length))) & 0xFF]; } else { lut[i].Length = 0; lut[i].Value = idx; } if (i != 0) do { idx++; } while ((table[idx].Code >> shift) == i); } } } void huff_init_lut(const int bits) { int i, j; huff_fill_lut(mpc_HuffDSCF.table, mpc_HuffDSCF.lut, bits); huff_fill_lut(mpc_HuffHdr.table, mpc_HuffHdr.lut, bits); can_fill_lut(&mpc_can_SCFI[0], bits); can_fill_lut(&mpc_can_SCFI[1], bits); can_fill_lut(&mpc_can_DSCF[0], bits); can_fill_lut(&mpc_can_DSCF[1], bits); can_fill_lut(&mpc_can_Res[0], bits); can_fill_lut(&mpc_can_Res[1], bits); can_fill_lut(&mpc_can_Q1, bits); can_fill_lut(&mpc_can_Q9up, bits); for( i = 0; i < 7; i++){ for( j = 0; j < 2; j++){ if (i != 6) can_fill_lut(&mpc_can_Q[i][j], bits); huff_fill_lut(mpc_HuffQ[i][j].table, mpc_HuffQ[i][j].lut, bits); } } } musepack_src_r495/libmpcdec/internal.h0000664000000000000000000000737111614327662016747 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file internal.h /// Definitions and structures used only internally by the libmpcdec. #ifndef _MPCDEC_INTERNAL_H_ #define _MPCDEC_INTERNAL_H_ #ifdef WIN32 #pragma once #endif #ifdef __cplusplus extern "C" { #endif #include /// Big/little endian 32 bit byte swapping routine. static mpc_inline mpc_uint32_t mpc_swap32(mpc_uint32_t val) { return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24)); } typedef struct mpc_block_t { char key[2]; // block key mpc_uint64_t size; // block size minus the block header size } mpc_block; #define MAX_FRAME_SIZE 4352 #define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box struct mpc_demux_t { mpc_reader * r; mpc_decoder * d; mpc_streaminfo si; // buffer mpc_uint8_t buffer[DEMUX_BUFFER_SIZE + MAX_FRAME_SIZE]; mpc_size_t bytes_total; mpc_bits_reader bits_reader; mpc_int32_t block_bits; /// bits remaining in current audio block mpc_uint_t block_frames; /// frames remaining in current audio block // seeking mpc_seek_t * seek_table; mpc_uint_t seek_pwr; /// distance between 2 frames in seek_table = 2^seek_pwr mpc_uint32_t seek_table_size; /// used size in seek_table // chapters mpc_seek_t chap_pos; /// supposed position of the first chapter block mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter) mpc_chap_info * chap; /// chapters position and tag }; /** * checks if a block key is valid * @param key the two caracters key to check * @return MPC_STATUS_FAIL if the key is invalid, MPC_STATUS_OK else */ static mpc_inline mpc_status mpc_check_key(char * key) { if (key[0] < 65 || key[0] > 90 || key[1] < 65 || key[1] > 90) return MPC_STATUS_FAIL; return MPC_STATUS_OK; } /// helper functions used by multiple files mpc_uint32_t mpc_random_int(mpc_decoder *d); // in synth_filter.c void mpc_decoder_init_quant(mpc_decoder *d, double scale_factor); void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData, mpc_int_t channels); #define MPC_IS_FAILURE(X) ((int)(X) < (int)MPC_STATUS_OK) #define MPC_AUTO_FAIL(X) { mpc_status s = (X); if (MPC_IS_FAILURE(s)) return s; } #ifdef __cplusplus } #endif #endif musepack_src_r495/libmpcdec/mpc_demux.c0000664000000000000000000005441312645277514017113 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "internal.h" #include "decoder.h" #include "huffman.h" #include "mpc_bits_reader.h" /// maximum number of seek points in the table. The distance between points will /// be adapted so this value is never exceeded. #define MAX_SEEK_TABLE_SIZE 65536 // streaminfo.c mpc_status streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in, mpc_size_t block_size); mpc_status streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r_in); void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in); void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in); // mpc_decoder.c void mpc_decoder_reset_scf(mpc_decoder * d, int value); enum { MPC_BUFFER_SWAP = 1, MPC_BUFFER_FULL = 2, }; static void mpc_demux_clear_buff(mpc_demux * d) { d->bytes_total = 0; d->bits_reader.buff = d->buffer; d->bits_reader.count = 8; d->block_bits = 0; d->block_frames = 0; } // Returns the amount of unread bytes in the demux buffer. // Unchecked version - may return a negative value when we've been reading // past the end of the valid data as a result of some problem with the file. static mpc_int32_t mpc_unread_bytes_unchecked(mpc_demux * d) { return d->bytes_total + d->buffer - d->bits_reader.buff - ((8 - d->bits_reader.count) >> 3); } // Returns the number of bytes available in the buffer. static mpc_uint32_t mpc_demux_fill(mpc_demux * d, mpc_uint32_t min_bytes, int flags) { mpc_uint32_t unread_bytes = (mpc_uint32_t) mpc_unread_bytes_unchecked(d); int offset = 0; if ((mpc_int32_t) unread_bytes < 0) return 0; // Error - we've been reading past the end of the buffer - abort if (min_bytes == 0 || min_bytes > DEMUX_BUFFER_SIZE || (unread_bytes < min_bytes && (flags & MPC_BUFFER_FULL) != 0 )) min_bytes = DEMUX_BUFFER_SIZE; if (unread_bytes < min_bytes) { mpc_uint32_t bytes2read = min_bytes - unread_bytes; mpc_uint32_t bytes_free = DEMUX_BUFFER_SIZE - d->bytes_total; mpc_uint32_t bytesread; if (flags & MPC_BUFFER_SWAP) { bytes2read &= -1 << 2; offset = (unread_bytes + 3) & ( -1 << 2); offset -= unread_bytes; } if (bytes2read > bytes_free) { if (d->bits_reader.count == 0) { d->bits_reader.count = 8; d->bits_reader.buff++; } memmove(d->buffer + offset, d->bits_reader.buff, unread_bytes); d->bits_reader.buff = d->buffer + offset; d->bytes_total = unread_bytes + offset; } bytesread = d->r->read(d->r, d->buffer + d->bytes_total, bytes2read); if (bytesread < bytes2read) { memset(d->buffer + d->bytes_total + bytesread, 0, bytes2read - bytesread); // FIXME : why ? } if (flags & MPC_BUFFER_SWAP) { unsigned int i, * tmp = (unsigned int *) (d->buffer + d->bytes_total); for(i = 0 ;i < (bytes2read >> 2); i++) tmp[i] = mpc_swap32(tmp[i]); } d->bytes_total += bytesread; unread_bytes += bytesread; } return unread_bytes; } /** * seek to a bit position in the stream * @param d demuxer context * @param fpos position in the stream in bits from the beginning of mpc datas * @param min_bytes number of bytes to load after seeking */ static mpc_status mpc_demux_seek(mpc_demux * d, mpc_seek_t fpos, mpc_uint32_t min_bytes) { mpc_seek_t start_pos, end_pos; mpc_int_t bit_offset; // get current buffer position end_pos = ((mpc_seek_t)(d->r->tell(d->r))) << 3; start_pos = end_pos - (d->bytes_total << 3); if (fpos >= start_pos && fpos < end_pos) { d->bits_reader.buff = d->buffer + ((fpos - start_pos) >> 3); bit_offset = fpos & 7; d->block_bits = 0; d->block_frames = 0; } else { mpc_seek_t next_pos = fpos >> 3; if (d->si.stream_version == 7) next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position; bit_offset = (int) (fpos - (next_pos << 3)); mpc_demux_clear_buff(d); if (!d->r->seek(d->r, (mpc_int32_t) next_pos)) return MPC_STATUS_FAIL; } if (d->si.stream_version == 7) mpc_demux_fill(d, (min_bytes + ((bit_offset + 7) >> 3) + 3) & (~3), MPC_BUFFER_SWAP); else mpc_demux_fill(d, min_bytes + ((bit_offset + 7) >> 3), 0); d->bits_reader.buff += bit_offset >> 3; d->bits_reader.count = 8 - (bit_offset & 7); return MPC_STATUS_OK; } /** * return the current position in the stream (in bits) from the beginning * of the file * @param d demuxer context * @return current stream position in bits */ mpc_seek_t mpc_demux_pos(mpc_demux * d) { return (((mpc_seek_t)(d->r->tell(d->r)) - d->bytes_total + d->bits_reader.buff - d->buffer) << 3) + 8 - d->bits_reader.count; } /** * Searches for a ID3v2-tag and reads the length (in bytes) of it. * * @param d demuxer context * @return size of tag, in bytes * @return MPC_STATUS_FAIL on errors of any kind */ static mpc_int32_t mpc_demux_skip_id3v2(mpc_demux * d) { mpc_uint8_t tmp [4]; mpc_bool_t footerPresent; // ID3v2.4-flag mpc_int32_t size; // we must be at the beginning of the stream mpc_demux_fill(d, 3, 0); // check id3-tag if ( 0 != memcmp( d->bits_reader.buff, "ID3", 3 ) ) return 0; mpc_demux_fill(d, 10, 0); mpc_bits_read(&d->bits_reader, 24); // read ID3 mpc_bits_read(&d->bits_reader, 16); // read tag version tmp[0] = mpc_bits_read(&d->bits_reader, 8); // read flags footerPresent = tmp[0] & 0x10; if ( tmp[0] & 0x0F ) return MPC_STATUS_FAIL; // not (yet???) allowed tmp[0] = mpc_bits_read(&d->bits_reader, 8); // read size tmp[1] = mpc_bits_read(&d->bits_reader, 8); // read size tmp[2] = mpc_bits_read(&d->bits_reader, 8); // read size tmp[3] = mpc_bits_read(&d->bits_reader, 8); // read size if ( (tmp[0] | tmp[1] | tmp[2] | tmp[3]) & 0x80 ) return MPC_STATUS_FAIL; // not allowed // read headerSize (syncsave: 4 * $0xxxxxxx = 28 significant bits) size = tmp[0] << 21; size |= tmp[1] << 14; size |= tmp[2] << 7; size |= tmp[3]; size += 10; //header if ( footerPresent ) size += 10; // This is called before file headers get read, streamversion etc isn't yet known, demuxing isn't properly initialized and we can't call mpc_demux_seek() from here. mpc_demux_clear_buff(d); if (!d->r->seek(d->r, size)) return MPC_STATUS_FAIL; return size; } static mpc_status mpc_demux_seek_init(mpc_demux * d) { size_t seek_table_size; if (d->seek_table != 0) return MPC_STATUS_OK; d->seek_pwr = 6; if (d->si.block_pwr > d->seek_pwr) d->seek_pwr = d->si.block_pwr; seek_table_size = (2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr)); while (seek_table_size > MAX_SEEK_TABLE_SIZE) { d->seek_pwr++; seek_table_size = (2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr)); } d->seek_table = malloc((size_t)(seek_table_size * sizeof(mpc_seek_t))); if (d->seek_table == 0) return MPC_STATUS_FAIL; d->seek_table[0] = (mpc_seek_t)mpc_demux_pos(d); d->seek_table_size = 1; return MPC_STATUS_OK; } static mpc_status mpc_demux_ST(mpc_demux * d) { mpc_uint64_t tmp; mpc_seek_t * table, last[2]; mpc_bits_reader r = d->bits_reader; mpc_uint_t i, diff_pwr = 0, mask; mpc_uint32_t file_table_size; if (d->seek_table != 0) return MPC_STATUS_OK; mpc_bits_get_size(&r, &tmp); file_table_size = (mpc_seek_t) tmp; d->seek_pwr = d->si.block_pwr + mpc_bits_read(&r, 4); tmp = 2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr); while (tmp > MAX_SEEK_TABLE_SIZE) { d->seek_pwr++; diff_pwr++; tmp = 2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr); } if ((file_table_size >> diff_pwr) > tmp) file_table_size = tmp << diff_pwr; d->seek_table = malloc((size_t) (tmp * sizeof(mpc_seek_t))); d->seek_table_size = (file_table_size + ((1 << diff_pwr) - 1)) >> diff_pwr; table = d->seek_table; mpc_bits_get_size(&r, &tmp); table[0] = last[0] = (mpc_seek_t) (tmp + d->si.header_position) * 8; if (d->seek_table_size == 1) return MPC_STATUS_OK; mpc_bits_get_size(&r, &tmp); last[1] = (mpc_seek_t) (tmp + d->si.header_position) * 8; if (diff_pwr == 0) table[1] = last[1]; mask = (1 << diff_pwr) - 1; for (i = 2; i < file_table_size; i++) { int code = mpc_bits_golomb_dec(&r, 12); if (code & 1) code = -(code & (-1 << 1)); code <<= 2; last[i & 1] = code + 2 * last[(i-1) & 1] - last[i & 1]; if ((i & mask) == 0) table[i >> diff_pwr] = last[i & 1]; } return MPC_STATUS_OK; } static mpc_status mpc_demux_SP(mpc_demux * d, int size, int block_size) { mpc_seek_t cur; mpc_uint64_t ptr; mpc_block b; int st_head_size; cur = mpc_demux_pos(d); mpc_bits_get_size(&d->bits_reader, &ptr); MPC_AUTO_FAIL( mpc_demux_seek(d, (ptr - size) * 8 + cur, 11) ); st_head_size = mpc_bits_get_block(&d->bits_reader, &b); if (memcmp(b.key, "ST", 2) == 0) { d->chap_pos = (ptr - size + b.size + st_head_size) * 8 + cur; d->chap_nb = -1; if (mpc_demux_fill(d, (mpc_uint32_t) b.size, 0) < b.size) return MPC_STATUS_FAIL; MPC_AUTO_FAIL( mpc_demux_ST(d) ); } return mpc_demux_seek(d, cur, 11 + block_size); } static void mpc_demux_chap_empty(mpc_demux * d) { free(d->chap); d->chap = 0; d->chap_nb = 0; // -1 for undefined, 0 for no chapters d->chap_pos = 0; } static mpc_status mpc_demux_chap_find_inner(mpc_demux * d) { mpc_block b; int tag_size = 0, chap_size = 0, size, i = 0; d->chap_nb = 0; if (d->si.stream_version < 8) return MPC_STATUS_OK; if (d->chap_pos == 0) { mpc_uint64_t cur_pos = (d->si.header_position + 4) * 8; MPC_AUTO_FAIL( mpc_demux_seek(d, cur_pos, 11) ); // seek to the beginning of the stream size = mpc_bits_get_block(&d->bits_reader, &b); while (memcmp(b.key, "SE", 2) != 0) { mpc_uint64_t new_pos = cur_pos + (size + b.size) * 8; MPC_AUTO_FAIL(mpc_check_key(b.key)); if (memcmp(b.key, "CT", 2) == 0) { if (d->chap_pos == 0) d->chap_pos = cur_pos; } else { d->chap_pos = 0; } if (new_pos <= cur_pos) return MPC_STATUS_FAIL; cur_pos = new_pos; MPC_AUTO_FAIL( mpc_demux_seek(d, cur_pos, 11) ); size = mpc_bits_get_block(&d->bits_reader, &b); } if (d->chap_pos == 0) d->chap_pos = cur_pos; } mpc_demux_seek(d, d->chap_pos, 20); size = mpc_bits_get_block(&d->bits_reader, &b); while (memcmp(b.key, "CT", 2) == 0) { mpc_uint64_t chap_sample; d->chap_nb++; chap_size += size; size = mpc_bits_get_size(&d->bits_reader, &chap_sample) + 4; chap_size += size; tag_size += b.size - size; MPC_AUTO_FAIL( mpc_demux_seek(d, d->chap_pos + (chap_size + tag_size) * 8, 20) ); size = mpc_bits_get_block(&d->bits_reader, &b); } if (d->chap_nb > 0) { char * ptag; d->chap = malloc(sizeof(mpc_chap_info) * d->chap_nb + tag_size); if (d->chap == 0) return MPC_STATUS_FAIL; ptag = (char*)(d->chap + d->chap_nb); MPC_AUTO_FAIL( mpc_demux_seek(d, d->chap_pos, 11) ); size = mpc_bits_get_block(&d->bits_reader, &b); while (memcmp(b.key, "CT", 2) == 0) { mpc_uint_t tmp_size; char * tmp_ptag = ptag; if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0) < b.size) return MPC_STATUS_FAIL; size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample) + 4; d->chap[i].gain = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); d->chap[i].peak = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); tmp_size = b.size - size; do { mpc_uint_t rd_size = tmp_size; mpc_uint8_t * tmp_buff = d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3); mpc_uint32_t avail_bytes = d->bytes_total + d->buffer - tmp_buff; rd_size = mini(rd_size, avail_bytes); memcpy(tmp_ptag, tmp_buff, rd_size); tmp_size -= rd_size; tmp_ptag += rd_size; d->bits_reader.buff += rd_size; mpc_demux_fill(d, tmp_size, 0); } while (tmp_size > 0); d->chap[i].tag_size = b.size - size; d->chap[i].tag = ptag; ptag += b.size - size; i++; size = mpc_bits_get_block(&d->bits_reader, &b); } } d->bits_reader.buff -= size; return MPC_STATUS_OK; } static mpc_status mpc_demux_chap_find(mpc_demux * d) { mpc_status s = mpc_demux_chap_find_inner(d); if (MPC_IS_FAILURE(s)) mpc_demux_chap_empty(d); return s; } /** * Gets the number of chapters in the stream * @param d pointer to a musepack demuxer * @return the number of chapters found in the stream */ mpc_int_t mpc_demux_chap_nb(mpc_demux * d) { if (d->chap_nb == -1) mpc_demux_chap_find(d); return d->chap_nb; } /** * Gets datas associated to a given chapter * The chapter tag is an APEv2 tag without the preamble * @param d pointer to a musepack demuxer * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) * @return the chapter information structure */ mpc_chap_info const * mpc_demux_chap(mpc_demux * d, int chap_nb) { if (d->chap_nb == -1) mpc_demux_chap_find(d); if (chap_nb >= d->chap_nb || chap_nb < 0) return 0; return &d->chap[chap_nb]; } static mpc_status mpc_demux_header(mpc_demux * d) { char magic[4]; d->si.pns = 0xFF; d->si.profile_name = "n.a."; // get header position d->si.header_position = mpc_demux_skip_id3v2(d); if(d->si.header_position < 0) return MPC_STATUS_FAIL; d->si.tag_offset = d->si.total_file_length = d->r->get_size(d->r); mpc_demux_fill(d, 4, 0); magic[0] = mpc_bits_read(&d->bits_reader, 8); magic[1] = mpc_bits_read(&d->bits_reader, 8); magic[2] = mpc_bits_read(&d->bits_reader, 8); magic[3] = mpc_bits_read(&d->bits_reader, 8); if (memcmp(magic, "MP+", 3) == 0) { d->si.stream_version = magic[3] & 15; d->si.pns = magic[3] >> 4; if (d->si.stream_version != 7) return MPC_STATUS_FAIL; if (mpc_demux_fill(d, 6 * 4, MPC_BUFFER_SWAP) < 6 * 4) // header block size + endian convertion return MPC_STATUS_FAIL; MPC_AUTO_FAIL( streaminfo_read_header_sv7(&d->si, &d->bits_reader) ); } else if (memcmp(magic, "MPCK", 4) == 0) { mpc_block b; int size; mpc_demux_fill(d, 11, 0); // max header block size size = mpc_bits_get_block(&d->bits_reader, &b); while( memcmp(b.key, "AP", 2) != 0 ){ // scan all blocks until audio if (mpc_check_key(b.key) != MPC_STATUS_OK) return MPC_STATUS_FAIL; if (b.size > (mpc_uint64_t) DEMUX_BUFFER_SIZE - 11) return MPC_STATUS_FAIL; if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0) <= b.size) return MPC_STATUS_FAIL; if (memcmp(b.key, "SH", 2) == 0) { MPC_AUTO_FAIL( streaminfo_read_header_sv8(&d->si, &d->bits_reader, (mpc_uint32_t) b.size) ); } else if (memcmp(b.key, "RG", 2) == 0) { streaminfo_gain(&d->si, &d->bits_reader); } else if (memcmp(b.key, "EI", 2) == 0) { streaminfo_encoder_info(&d->si, &d->bits_reader); } else if (memcmp(b.key, "SO", 2) == 0) { MPC_AUTO_FAIL( mpc_demux_SP(d, size, (mpc_uint32_t) b.size) ); } else if (memcmp(b.key, "ST", 2) == 0) { MPC_AUTO_FAIL( mpc_demux_ST(d) ); } d->bits_reader.buff += b.size; size = mpc_bits_get_block(&d->bits_reader, &b); } d->bits_reader.buff -= size; if (d->si.stream_version == 0) // si not initialized !!! return MPC_STATUS_FAIL; } else { return MPC_STATUS_FAIL; } return MPC_STATUS_OK; } mpc_demux * mpc_demux_init(mpc_reader * p_reader) { mpc_demux* p_tmp = malloc(sizeof(mpc_demux)); if (p_tmp != 0) { memset(p_tmp, 0, sizeof(mpc_demux)); p_tmp->r = p_reader; p_tmp->chap_nb = -1; mpc_demux_clear_buff(p_tmp); if (mpc_demux_header(p_tmp) == MPC_STATUS_OK && mpc_demux_seek_init(p_tmp) == MPC_STATUS_OK) { p_tmp->d = mpc_decoder_init(&p_tmp->si); } else { if (p_tmp->seek_table) free(p_tmp->seek_table); free(p_tmp); p_tmp = 0; } } return p_tmp; } void mpc_demux_exit(mpc_demux * d) { mpc_decoder_exit(d->d); free(d->seek_table); free(d->chap); free(d); } void mpc_demux_get_info(mpc_demux * d, mpc_streaminfo * i) { memcpy(i, &d->si, sizeof d->si); } mpc_status mpc_demux_decode_inner(mpc_demux * d, mpc_frame_info * i) { mpc_bits_reader r; if (d->si.stream_version >= 8) { i->is_key_frame = MPC_FALSE; if (d->block_frames == 0) { mpc_block b = {{0,0},0}; d->bits_reader.count &= -8; if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); d->seek_table_size ++; } mpc_demux_fill(d, 11, MPC_BUFFER_FULL); // max header block size mpc_bits_get_block(&d->bits_reader, &b); while( memcmp(b.key, "AP", 2) != 0 ) { // scan all blocks until audio MPC_AUTO_FAIL( mpc_check_key(b.key) ); if (memcmp(b.key, "SE", 2) == 0) { // end block i->bits = -1; return MPC_STATUS_OK; } if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, MPC_BUFFER_FULL) < b.size) return MPC_STATUS_FAIL; d->bits_reader.buff += b.size; mpc_bits_get_block(&d->bits_reader, &b); } d->block_bits = (mpc_uint32_t) b.size * 8; d->block_frames = 1 << d->si.block_pwr; i->is_key_frame = MPC_TRUE; } if (d->buffer + d->bytes_total - d->bits_reader.buff <= MAX_FRAME_SIZE) mpc_demux_fill(d, (d->block_bits >> 3) + 1, MPC_BUFFER_FULL); r = d->bits_reader; mpc_decoder_decode_frame(d->d, &d->bits_reader, i); d->block_bits -= ((d->bits_reader.buff - r.buff) << 3) + r.count - d->bits_reader.count; d->block_frames--; if (d->block_bits < 0 || (d->block_frames == 0 && d->block_bits > 7)) return MPC_STATUS_FAIL; } else { if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); d->seek_table_size ++; } mpc_demux_fill(d, MAX_FRAME_SIZE, MPC_BUFFER_FULL | MPC_BUFFER_SWAP); d->block_bits = (mpc_int_t) mpc_bits_read(&d->bits_reader, 20); // read frame size if (MPC_FRAME_LENGTH > d->d->samples - d->d->decoded_samples - 1) d->block_bits += 11; // we will read last frame size r = d->bits_reader; mpc_decoder_decode_frame(d->d, &d->bits_reader, i); if (i->bits != -1 && d->block_bits != ((d->bits_reader.buff - r.buff) << 3) + r.count - d->bits_reader.count) return MPC_STATUS_FAIL; } if (i->bits != -1 && d->buffer + d->bytes_total < d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3)) return MPC_STATUS_FAIL; return MPC_STATUS_OK; } mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i) { for(;;) { // mpc_demux_decode_inner may return 0 samples and require repeated calls after a seek. Loop over until we have data to return. mpc_status s = mpc_demux_decode_inner(d, i); if (MPC_IS_FAILURE(s)) i->bits = -1; // we pretend it's end of file if (i->bits == -1 || i->samples > 0) return s; } } mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds) { return mpc_demux_seek_sample(d, (mpc_int64_t)(seconds * (double)d->si.sample_freq + 0.5)); } mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_uint64_t destsample) { mpc_uint32_t fwd, samples_to_skip, i; mpc_uint32_t block_samples = MPC_FRAME_LENGTH << d->si.block_pwr; mpc_seek_t fpos; destsample += d->si.beg_silence; if (destsample > d->si.samples) destsample = d->si.samples; fwd = (mpc_uint32_t) (destsample / block_samples); samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t) (destsample % block_samples); if (d->si.stream_version == 7) { if (fwd > 32) { fwd -= 32; samples_to_skip += MPC_FRAME_LENGTH * 32; } else { samples_to_skip += MPC_FRAME_LENGTH * fwd; fwd = 0; } } i = fwd >> (d->seek_pwr - d->si.block_pwr); if (i >= d->seek_table_size) i = d->seek_table_size - 1; fpos = d->seek_table[i]; i <<= d->seek_pwr - d->si.block_pwr; d->d->decoded_samples = i * block_samples; if (d->si.stream_version >= 8) { mpc_block b; int size; mpc_demux_seek(d, fpos, 11); size = mpc_bits_get_block(&d->bits_reader, &b); while(i < fwd) { if (memcmp(b.key, "AP", 2) == 0) { if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d) - 8 * size; d->seek_table_size ++; } d->d->decoded_samples += block_samples; i++; } fpos += ((mpc_uint32_t)b.size + size) * 8; mpc_demux_seek(d, fpos, 11); size = mpc_bits_get_block(&d->bits_reader, &b); } d->bits_reader.buff -= size; } else { mpc_decoder_reset_scf(d->d, fwd != 0); mpc_demux_seek(d, fpos, 4); for( ; i < fwd; i++){ if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); d->seek_table_size ++; } d->d->decoded_samples += block_samples; fpos += mpc_bits_read(&d->bits_reader, 20) + 20; mpc_demux_seek(d, fpos, 4); } } d->d->samples_to_skip = samples_to_skip; return MPC_STATUS_OK; } void mpc_set_replay_level(mpc_demux * d, float level, mpc_bool_t use_gain, mpc_bool_t use_title, mpc_bool_t clip_prevention) { float peak = (float) ( use_title ? d->si.peak_title : d->si.peak_album ); float gain = (float) ( use_title ? d->si.gain_title : d->si.gain_album ); if(!use_gain && !clip_prevention) return; if(!peak) peak = 1.; else peak = (float) ( (1 << 15) / pow(10, peak / (20 * 256)) ); if(!gain) gain = 1.; else gain = (float) pow(10, (level - gain / 256) / 20); if(clip_prevention && (peak < gain || !use_gain)) gain = peak; mpc_decoder_scale_output(d->d, gain); } musepack_src_r495/libmpcdec/README0000664000000000000000000000030511150572662015625 0ustar rootrootMusepack Decoder Library: run "./configure [--prefix=/usr]; make" To create a sample app using the musepack decoder library Check ../mpcdec/mpcdec.c and ../include/mpc/mpcdec.h for more details. musepack_src_r495/libmpcdec/mpc_decoder.c0000664000000000000000000006274012660171312017362 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file mpc_decoder.c /// Core decoding routines and logic. #include #include #include #include "decoder.h" #include "huffman.h" #include "internal.h" #include "mpcdec_math.h" #include "requant.h" #include "mpc_bits_reader.h" //SV7 tables extern const mpc_lut_data mpc_HuffQ [7] [2]; extern const mpc_lut_data mpc_HuffHdr; extern const mpc_huffman mpc_table_HuffSCFI [ 4]; extern const mpc_lut_data mpc_HuffDSCF; //SV8 tables extern const mpc_can_data mpc_can_Bands; extern const mpc_can_data mpc_can_SCFI[2]; extern const mpc_can_data mpc_can_DSCF[2]; extern const mpc_can_data mpc_can_Res [2]; extern const mpc_can_data mpc_can_Q [8][2]; extern const mpc_can_data mpc_can_Q1; extern const mpc_can_data mpc_can_Q9up; //------------------------------------------------------------------------------ // types //------------------------------------------------------------------------------ enum { MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size MEMSIZE2 = (MEMSIZE/2), // size of one buffer MEMMASK = (MEMSIZE-1) }; //------------------------------------------------------------------------------ // forward declarations //------------------------------------------------------------------------------ void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r); void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame); static void mpc_decoder_requantisierung(mpc_decoder *d); /** * set the scf indexes for seeking use * needed only for sv7 seeking * @param d */ void mpc_decoder_reset_scf(mpc_decoder * d, int value) { memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L ); memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R ); } void mpc_decoder_setup(mpc_decoder *d) { memset(d, 0, sizeof *d); d->__r1 = 1; d->__r2 = 1; mpc_decoder_init_quant(d, 1.0f); } void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) { d->stream_version = si->stream_version; d->ms = si->ms; d->max_band = si->max_band; d->channels = si->channels; d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + si->beg_silence; if (si->stream_version == 7 && si->is_true_gapless) d->samples = ((si->samples + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH) * MPC_FRAME_LENGTH; else d->samples = si->samples; } mpc_decoder * mpc_decoder_init(mpc_streaminfo *si) { mpc_decoder* p_tmp = malloc(sizeof(mpc_decoder)); if (p_tmp != 0) { mpc_decoder_setup(p_tmp); mpc_decoder_set_streaminfo(p_tmp, si); huff_init_lut(LUT_DEPTH); // FIXME : this needs to be called only once when the library is loaded } return p_tmp; } void mpc_decoder_exit(mpc_decoder *d) { free(d); } void mpc_decoder_decode_frame(mpc_decoder * d, mpc_bits_reader * r, mpc_frame_info * i) { mpc_bits_reader r_sav = *r; mpc_int64_t samples_left; samples_left = d->samples - d->decoded_samples + MPC_DECODER_SYNTH_DELAY; if (samples_left <= 0 && d->samples != 0) { i->samples = 0; i->bits = -1; return; } if (d->stream_version == 8) mpc_decoder_read_bitstream_sv8(d, r, i->is_key_frame); else mpc_decoder_read_bitstream_sv7(d, r); if (d->samples_to_skip < MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY) { mpc_decoder_requantisierung(d); mpc_decoder_synthese_filter_float(d, i->buffer, d->channels); } d->decoded_samples += MPC_FRAME_LENGTH; // reconstruct exact filelength if (d->decoded_samples - d->samples < MPC_FRAME_LENGTH && d->stream_version == 7) { int last_frame_samples = mpc_bits_read(r, 11); if (d->decoded_samples == d->samples) { if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH; d->samples += last_frame_samples - MPC_FRAME_LENGTH; samples_left += last_frame_samples - MPC_FRAME_LENGTH; } } i->samples = samples_left > MPC_FRAME_LENGTH ? MPC_FRAME_LENGTH : samples_left < 0 ? 0 : (mpc_uint32_t) samples_left; i->bits = (mpc_uint32_t) (((r->buff - r_sav.buff) << 3) + r_sav.count - r->count); if (d->samples_to_skip) { if (i->samples <= d->samples_to_skip) { d->samples_to_skip -= i->samples; i->samples = 0; } else { i->samples -= d->samples_to_skip; memmove(i->buffer, i->buffer + d->samples_to_skip * d->channels, i->samples * d->channels * sizeof (MPC_SAMPLE_FORMAT)); d->samples_to_skip = 0; } } } void mpc_decoder_requantisierung(mpc_decoder *d) { mpc_int32_t Band; mpc_int32_t n; MPC_SAMPLE_FORMAT facL; MPC_SAMPLE_FORMAT facR; MPC_SAMPLE_FORMAT templ; MPC_SAMPLE_FORMAT tempr; MPC_SAMPLE_FORMAT* YL; MPC_SAMPLE_FORMAT* YR; mpc_int16_t* L; mpc_int16_t* R; const mpc_int32_t Last_Band = d->max_band; #ifdef MPC_FIXED_POINT #if MPC_FIXED_POINT_FRACTPART == 14 #define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx]) #else #error FIXME, Cc table is in 18.14 format #endif #else #define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ MPC_MULTIPLY(CcVal, d->SCF[SCF_idx]) #endif // requantization and scaling of subband-samples for ( Band = 0; Band <= Last_Band; Band++ ) { // setting pointers YL = d->Y_L[0] + Band; YR = d->Y_R[0] + Band; L = d->Q[Band].L; R = d->Q[Band].R; /************************** MS-coded **************************/ if ( d->MS_Flag [Band] ) { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // M!=0, S!=0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } } else { // M!=0, S==0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } } } else { if (d->Res_R[Band]) // M==0, S!=0 { facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } } else { // M==0, S==0 for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = 0; } } } } /************************** LR-coded **************************/ else { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // L!=0, R!=0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for (n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for (; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for (; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } } else { // L!=0, R==0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } } } else { if ( d->Res_R [Band] ) { // L==0, R!=0 facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } } else { // L==0, R==0 for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = 0; } } } } } } void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r) { // these arrays hold decoding results for bundled quantizers (3- and 5-step) static const mpc_int32_t idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; static const mpc_int32_t idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; static const mpc_int32_t idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; static const mpc_int32_t idx50[] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; static const mpc_int32_t idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; mpc_int32_t n, idx, Max_used_Band = 0; /***************************** Header *****************************/ // first subband d->Res_L[0] = mpc_bits_read(r, 4); d->Res_R[0] = mpc_bits_read(r, 4); if (!(d->Res_L[0] == 0 && d->Res_R[0] == 0)) { if (d->ms) d->MS_Flag[0] = mpc_bits_read(r, 1); Max_used_Band = 1; } // consecutive subbands for ( n = 1; n <= d->max_band; n++ ) { idx = mpc_bits_huff_lut(r, & mpc_HuffHdr); d->Res_L[n] = (idx!=4) ? d->Res_L[n - 1] + idx : (int) mpc_bits_read(r, 4); idx = mpc_bits_huff_lut(r, & mpc_HuffHdr); d->Res_R[n] = (idx!=4) ? d->Res_R[n - 1] + idx : (int) mpc_bits_read(r, 4); if (!(d->Res_L[n] == 0 && d->Res_R[n] == 0)) { if (d->ms) d->MS_Flag[n] = mpc_bits_read(r, 1); Max_used_Band = n + 1; } } /****************************** SCFI ******************************/ for ( n = 0; n < Max_used_Band; n++ ) { if (d->Res_L[n]) d->SCFI_L[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI); if (d->Res_R[n]) d->SCFI_R[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI); } /**************************** SCF/DSCF ****************************/ for ( n = 0; n < Max_used_Band; n++ ) { mpc_int32_t * SCF = d->SCF_Index_L[n]; mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n]; do { if (Res) { switch (SCFI) { case 1: idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6); SCF[2] = SCF[1]; break; case 3: idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); SCF[1] = SCF[0]; SCF[2] = SCF[1]; break; case 2: idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); SCF[1] = SCF[0]; idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6); break; case 0: idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6); idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6); break; default: return; } if (SCF[0] > 1024) SCF[0] = 0x8080; if (SCF[1] > 1024) SCF[1] = 0x8080; if (SCF[2] > 1024) SCF[2] = 0x8080; } Res = d->Res_R[n]; SCFI = d->SCFI_R[n]; } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n])); } /***************************** Samples ****************************/ for ( n = 0; n < Max_used_Band; n++ ) { mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n]; do { mpc_int32_t k; const mpc_lut_data *Table; switch (Res) { case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: case 0: break; case -1: for (k=0; k<36; k++ ) { mpc_uint32_t tmp = mpc_random_int(d); q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } break; case 1: Table = & mpc_HuffQ[0][mpc_bits_read(r, 1)]; for ( k = 0; k < 36; k += 3) { idx = mpc_bits_huff_lut(r, Table); q[k] = idx30[idx]; q[k + 1] = idx31[idx]; q[k + 2] = idx32[idx]; } break; case 2: Table = & mpc_HuffQ[1][mpc_bits_read(r, 1)]; for ( k = 0; k < 36; k += 2) { idx = mpc_bits_huff_lut(r, Table); q[k] = idx50[idx]; q[k + 1] = idx51[idx]; } break; case 3: case 4: case 5: case 6: case 7: Table = & mpc_HuffQ[Res - 1][mpc_bits_read(r, 1)]; for ( k = 0; k < 36; k++ ) q[k] = mpc_bits_huff_lut(r, Table); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: for ( k = 0; k < 36; k++ ) q[k] = (mpc_int32_t)mpc_bits_read(r, Res_bit[Res]) - Dc[Res]; break; default: return; } Res = d->Res_R[n]; } while (q == d->Q[n].L && (q = d->Q[n].R)); } } void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame) { // these arrays hold decoding results for bundled quantizers (3- and 5-step) static const mpc_int8_t idx50[125] = {-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2}; static const mpc_int8_t idx51[125] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; static const mpc_int8_t idx52[125] = {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; mpc_int32_t n, Max_used_Band; const mpc_can_data * Table, * Tables[2]; /***************************** Header *****************************/ if (is_key_frame == MPC_TRUE) { Max_used_Band = mpc_bits_log_dec(r, d->max_band + 1); } else { Max_used_Band = d->last_max_band + mpc_bits_can_dec(r, & mpc_can_Bands); if (Max_used_Band > 32) Max_used_Band -= 33; } d->last_max_band = Max_used_Band; if (Max_used_Band) { d->Res_L[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]); d->Res_R[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]); if (d->Res_L[Max_used_Band-1] > 15) d->Res_L[Max_used_Band-1] -= 17; if (d->Res_R[Max_used_Band-1] > 15) d->Res_R[Max_used_Band-1] -= 17; for ( n = Max_used_Band - 2; n >= 0; n--) { d->Res_L[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_L[n + 1] > 2]) + d->Res_L[n + 1]; if (d->Res_L[n] > 15) d->Res_L[n] -= 17; d->Res_R[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_R[n + 1] > 2]) + d->Res_R[n + 1]; if (d->Res_R[n] > 15) d->Res_R[n] -= 17; } if (d->ms) { mpc_uint_t cnt = 0, tot = 0; mpc_uint32_t tmp = 0; for( n = 0; n < Max_used_Band; n++) if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) tot++; cnt = mpc_bits_log_dec(r, tot); if (cnt != 0 && cnt != tot) tmp = mpc_bits_enum_dec(r, mini(cnt, tot-cnt), tot); if (cnt * 2 > tot) tmp = ~tmp; for( n = Max_used_Band - 1; n >= 0; n--) if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) { d->MS_Flag[n] = tmp & 1; tmp >>= 1; } } } for( n = Max_used_Band; n <= d->max_band; n++) d->Res_L[n] = d->Res_R[n] = 0; /****************************** SCFI ******************************/ if (is_key_frame == MPC_TRUE){ for( n = 0; n < 32; n++) d->DSCF_Flag_L[n] = d->DSCF_Flag_R[n] = 1; // new block -> force key frame } Tables[0] = & mpc_can_SCFI[0]; Tables[1] = & mpc_can_SCFI[1]; for ( n = 0; n < Max_used_Band; n++ ) { int tmp = 0, cnt = -1; if (d->Res_L[n]) cnt++; if (d->Res_R[n]) cnt++; if (cnt >= 0) { tmp = mpc_bits_can_dec(r, Tables[cnt]); if (d->Res_L[n]) d->SCFI_L[n] = tmp >> (2 * cnt); if (d->Res_R[n]) d->SCFI_R[n] = tmp & 3; } } /**************************** SCF/DSCF ****************************/ for ( n = 0; n < Max_used_Band; n++ ) { mpc_int32_t * SCF = d->SCF_Index_L[n]; mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n]; mpc_bool_t * DSCF_Flag = &d->DSCF_Flag_L[n]; do { if ( Res ) { int m; if (*DSCF_Flag == 1) { SCF[0] = (mpc_int32_t)mpc_bits_read(r, 7) - 6; *DSCF_Flag = 0; } else { mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[1]); if (tmp == 64) tmp += mpc_bits_read(r, 6); SCF[0] = ((SCF[2] - 25 + tmp) & 127) - 6; } for( m = 0; m < 2; m++){ if (((SCFI << m) & 2) == 0) { mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[0]); if (tmp == 31) tmp = 64 + mpc_bits_read(r, 6); SCF[m + 1] = ((SCF[m] - 25 + tmp) & 127) - 6; } else SCF[m + 1] = SCF[m]; } } Res = d->Res_R[n]; SCFI = d->SCFI_R[n]; DSCF_Flag = &d->DSCF_Flag_R[n]; } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n])); } /***************************** Samples ****************************/ for ( n = 0; n < Max_used_Band; n++ ) { mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n]; static const unsigned int thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8}; static const mpc_int8_t HuffQ2_var[5*5*5] = {6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6}; do { mpc_uint32_t k = 0, idx = 1; if (Res != 0) { if (Res == 2) { Tables[0] = & mpc_can_Q [0][0]; Tables[1] = & mpc_can_Q [0][1]; idx = 2 * thres[Res]; for ( ; k < 36; k += 3) { int tmp = mpc_bits_can_dec(r, Tables[idx > thres[Res]]); q[k] = idx50[tmp]; q[k + 1] = idx51[tmp]; q[k + 2] = idx52[tmp]; idx = (idx >> 1) + HuffQ2_var[tmp]; } } else if (Res == 1) { Table = & mpc_can_Q1; for( ; k < 36; ){ mpc_uint32_t kmax = k + 18; mpc_uint_t cnt = mpc_bits_can_dec(r, Table); idx = 0; if (cnt > 0 && cnt < 18) idx = mpc_bits_enum_dec(r, cnt <= 9 ? cnt : 18 - cnt, 18); if (cnt > 9) idx = ~idx; for ( ; k < kmax; k++) { q[k] = 0; if ( idx & (1 << 17) ) q[k] = (mpc_bits_read(r, 1) << 1) - 1; idx <<= 1; } } } else if (Res == -1) { for ( ; k<36; k++ ) { mpc_uint32_t tmp = mpc_random_int(d); q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } } else if (Res <= 4) { Table = & mpc_can_Q[1][Res - 3]; for ( ; k < 36; k += 2 ) { union { mpc_int8_t sym; struct { mpc_int8_t s1:4, s2:4; }; } tmp; tmp.sym = mpc_bits_can_dec(r, Table); q[k] = tmp.s1; q[k + 1] = tmp.s2; } } else if (Res <= 8) { Tables[0] = & mpc_can_Q [Res - 3][0]; Tables[1] = & mpc_can_Q [Res - 3][1]; idx = 2 * thres[Res]; for ( ; k < 36; k++ ) { q[k] = mpc_bits_can_dec(r, Tables[idx > thres[Res]]); idx = (idx >> 1) + absi(q[k]); } } else { for ( ; k < 36; k++ ) { q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up); if (Res != 9) q[k] = (q[k] << (Res - 9)) | mpc_bits_read(r, Res - 9); q[k] -= Dc[Res]; } } } Res = d->Res_R[n]; } while (q == d->Q[n].L && (q = d->Q[n].R)); } } musepack_src_r495/libmpcdec/requant.h0000664000000000000000000000414011735410651016574 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file requant.h /// Requantization function definitions. #ifndef _MPCDEC_REQUANT_H_ #define _MPCDEC_REQUANT_H_ #ifdef WIN32 #pragma once #endif #include #ifdef __cplusplus extern "C" { #endif /* C O N S T A N T S */ extern const mpc_uint8_t Res_bit [18]; ///< Bits per sample for chosen quantizer extern const MPC_SAMPLE_FORMAT __Cc [1 + 18]; ///< Requantization coefficients extern const mpc_int16_t __Dc [1 + 18]; ///< Requantization offset #define Cc (__Cc + 1) #define Dc (__Dc + 1) #ifdef __cplusplus } #endif #endif musepack_src_r495/libmpcdec/CMakeLists.txt0000664000000000000000000000260112660175216017507 0ustar rootrootSET(mpcdec_VERSION_MAJOR 7) SET(mpcdec_VERSION_MINOR 0) SET(mpcdec_VERSION_PATCH 1) set(mpcdec_VERSION ${mpcdec_VERSION_MAJOR}.${mpcdec_VERSION_MINOR}.${mpcdec_VERSION_PATCH}) install(FILES ${libmpc_SOURCE_DIR}/include/mpc/mpcdec.h ${libmpc_SOURCE_DIR}/include/mpc/reader.h ${libmpc_SOURCE_DIR}/include/mpc/streaminfo.h ${libmpc_SOURCE_DIR}/include/mpc/mpc_types.h DESTINATION include/mpc COMPONENT headers) include_directories(${libmpc_SOURCE_DIR}/include) if(SHARED) add_library(mpcdec_shared SHARED huffman mpc_decoder mpc_reader streaminfo mpc_bits_reader mpc_demux requant synth_filter ${libmpc_SOURCE_DIR}/common/crc32) set_target_properties(mpcdec_shared PROPERTIES OUTPUT_NAME mpcdec CLEAN_DIRECT_OUTPUT 1 VERSION ${mpcdec_VERSION} SOVERSION ${mpcdec_VERSION_MAJOR}) install(TARGETS mpcdec_shared LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}" COMPONENT libraries) target_link_libraries(mpcdec_shared m) else(SHARED) add_library(mpcdec_static STATIC huffman mpc_decoder mpc_reader streaminfo mpc_bits_reader mpc_demux requant synth_filter ${libmpc_SOURCE_DIR}/common/crc32) set_target_properties(mpcdec_static PROPERTIES OUTPUT_NAME mpcdec CLEAN_DIRECT_OUTPUT 1) install(TARGETS mpcdec_static LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}" COMPONENT libraries) target_link_libraries(mpcdec_static m) endif(SHARED) musepack_src_r495/libmpcdec/decoder.h0000664000000000000000000000726711150567164016542 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file decoder.h #ifndef _MPCDEC_DECODER_H_ #define _MPCDEC_DECODER_H_ #ifdef WIN32 #pragma once #endif #include #ifdef __cplusplus extern "C" { #endif #define SEEKING_TABLE_SIZE 256u // set it to SLOW_SEEKING_WINDOW to not use fast seeking #define FAST_SEEKING_WINDOW 32 // set it to FAST_SEEKING_WINDOW to only use fast seeking #define SLOW_SEEKING_WINDOW 0x80000000 enum { MPC_V_MEM = 2304, MPC_DECODER_MEMSIZE = 16384, // overall buffer size }; struct mpc_decoder_t { /// @name internal state variables //@{ mpc_uint32_t stream_version; ///< Streamversion of stream mpc_int32_t max_band; ///< Maximum band-index used in stream (0...31) mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on) mpc_uint32_t channels; ///< Number of channels in stream mpc_uint64_t samples; ///< Number of samples in stream mpc_uint64_t decoded_samples; ///< Number of samples decoded from file begining mpc_uint32_t samples_to_skip; ///< Number samples to skip (used for seeking) mpc_int32_t last_max_band; ///< number of bands used in the last frame // randomizer state variables mpc_uint32_t __r1; mpc_uint32_t __r2; mpc_int32_t SCF_Index_L [32] [3]; mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices mpc_quantizer Q [32]; // holds quantized samples mpc_int32_t Res_L [32]; mpc_int32_t Res_R [32]; // holds the chosen quantizer for each subband mpc_bool_t DSCF_Flag_L [32]; mpc_bool_t DSCF_Flag_R [32]; // differential SCF used? mpc_int32_t SCFI_L [32]; mpc_int32_t SCFI_R [32]; // describes order of transmitted SCF mpc_bool_t MS_Flag[32]; // MS used? #ifdef MPC_FIXED_POINT mpc_uint8_t SCF_shift[256]; #endif MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960]; MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; MPC_SAMPLE_FORMAT Y_L[36][32]; MPC_SAMPLE_FORMAT Y_R[36][32]; MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention) //@} }; #ifdef __cplusplus } #endif #endif musepack_src_r495/libmpcdec/AUTHORS0000664000000000000000000000043210526367046016022 0ustar rootrootlibmpcdec is the result of the work of many people: * Andree Buschmann and Frank Klemm Original implementation and core development. * Peter Pawlowski and Benoit Amiaux Portability and further optimizations. * Miles Egan Port to pure C, documentation, and api refinements. musepack_src_r495/libmpcdec/streaminfo.c0000664000000000000000000002021511700102077017250 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file streaminfo.c /// Implementation of streaminfo reading functions. #include #include #include #include #include "internal.h" #include "huffman.h" #include "mpc_bits_reader.h" unsigned long mpc_crc32(unsigned char *buf, int len); static const char na[] = "n.a."; static char const * const versionNames[] = { na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'", "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Extreme'", "'Insane'", "'BrainDead'", "'quality 9'", "'quality 10'" }; static const mpc_int32_t samplefreqs[8] = { 44100, 48000, 37800, 32000 }; static const char * mpc_get_version_string(float profile) // profile is 0...15, where 7...13 is used { return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile]; } static void mpc_get_encoder_string(mpc_streaminfo* si) { int ver = si->encoder_version; if (si->stream_version >= 8) ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF); if (ver <= 116) { if (ver == 0) { sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05"); } else { switch (ver % 10) { case 0: sprintf(si->encoder, "Release %u.%u", ver / 100, ver / 10 % 10); break; case 2: case 4: case 6: case 8: sprintf(si->encoder, "Beta %u.%02u", ver / 100, ver % 100); break; default: sprintf(si->encoder, "--Alpha-- %u.%02u", ver / 100, ver % 100); break; } } } else { int major = si->encoder_version >> 24; int minor = (si->encoder_version >> 16) & 0xFF; int build = (si->encoder_version >> 8) & 0xFF; char * tmp = "--Stable--"; if (minor & 1) tmp = "--Unstable--"; sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build); } } static mpc_status check_streaminfo(mpc_streaminfo * si) { if (si->max_band == 0 || si->max_band >= 32 || si->channels > 2 || si->channels == 0 || si->sample_freq == 0) return MPC_STATUS_FAIL; return MPC_STATUS_OK; } /// Reads streaminfo from SV7 header. mpc_status streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r) { mpc_uint32_t frames, last_frame_samples; si->bitrate = 0; frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16); mpc_bits_read(r, 1); // intensity stereo : should be 0 si->ms = mpc_bits_read(r, 1); si->max_band = mpc_bits_read(r, 6); si->profile = mpc_bits_read(r, 4); si->profile_name = mpc_get_version_string(si->profile); mpc_bits_read(r, 2); // Link ? si->sample_freq = samplefreqs[mpc_bits_read(r, 2)]; mpc_bits_read(r, 16); // skip MaxLevel (maximum level of input PCM) si->gain_title = (mpc_uint16_t) mpc_bits_read(r, 16); si->peak_title = (mpc_uint16_t) mpc_bits_read(r, 16); si->gain_album = (mpc_uint16_t) mpc_bits_read(r, 16); si->peak_album = (mpc_uint16_t) mpc_bits_read(r, 16); si->is_true_gapless = mpc_bits_read(r, 1); // true gapless: used? last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame si->fast_seek = mpc_bits_read(r, 1); // fast seeking mpc_bits_read(r, 19); // unused si->encoder_version = mpc_bits_read(r, 8); si->channels = 2; si->block_pwr = 0; // convert gain info if (si->gain_title != 0) { int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_title / 100.) * 256. + .5); if (tmp >= (1 << 16) || tmp < 0) tmp = 0; si->gain_title = (mpc_int16_t) tmp; } if (si->gain_album != 0) { int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_album / 100.) * 256. + .5); if (tmp >= (1 << 16) || tmp < 0) tmp = 0; si->gain_album = (mpc_int16_t) tmp; } if (si->peak_title != 0) si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5); if (si->peak_album != 0) si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5); mpc_get_encoder_string(si); if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH; else if (last_frame_samples > MPC_FRAME_LENGTH) return MPC_STATUS_FAIL; si->samples = (mpc_int64_t) frames * MPC_FRAME_LENGTH; if (si->is_true_gapless) si->samples -= (MPC_FRAME_LENGTH - last_frame_samples); else si->samples -= MPC_DECODER_SYNTH_DELAY; si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 * si->sample_freq / si->samples; return check_streaminfo(si); } /// Reads replay gain datas void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in) { mpc_bits_reader r = *r_in; int version = mpc_bits_read(&r, 8); // gain version if (version != 1) // we only know ver 1 return; si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16); si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16); si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16); si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16); } /// Reads streaminfo from SV8 header. mpc_status streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in, mpc_size_t block_size) { mpc_uint32_t CRC; mpc_bits_reader r = *r_in; CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16); if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4)) return MPC_STATUS_FAIL; si->stream_version = mpc_bits_read(&r, 8); if (si->stream_version != 8) return MPC_STATUS_FAIL; mpc_bits_get_size(&r, &si->samples); mpc_bits_get_size(&r, &si->beg_silence); si->is_true_gapless = 1; si->sample_freq = samplefreqs[mpc_bits_read(&r, 3)]; si->max_band = mpc_bits_read(&r, 5) + 1; si->channels = mpc_bits_read(&r, 4) + 1; si->ms = mpc_bits_read(&r, 1); si->block_pwr = mpc_bits_read(&r, 3) * 2; si->bitrate = 0; if ((si->samples - si->beg_silence) != 0) si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 * si->sample_freq / (si->samples - si->beg_silence); return check_streaminfo(si); } /// Reads encoder informations void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in) { mpc_bits_reader r = *r_in; si->profile = mpc_bits_read(&r, 7) / 8.; si->profile_name = mpc_get_version_string(si->profile); si->pns = mpc_bits_read(&r, 1); si->encoder_version = mpc_bits_read(&r, 8) << 24; // major si->encoder_version |= mpc_bits_read(&r, 8) << 16; // minor si->encoder_version |= mpc_bits_read(&r, 8) << 8; // build mpc_get_encoder_string(si); } double mpc_streaminfo_get_length(mpc_streaminfo * si) { return (double) (si->samples - si->beg_silence) / si->sample_freq; } mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si) { return si->samples - si->beg_silence; } musepack_src_r495/libmpcdec/requant.c0000664000000000000000000000764511150567164016607 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file requant.c /// Requantization function implementations. /// \todo document me #include #include "requant.h" #include "mpcdec_math.h" #include "decoder.h" /* C O N S T A N T S */ // Bits per sample for chosen quantizer const mpc_uint8_t Res_bit [18] = { 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // Requantization coefficients // 65536/step bzw. 65536/(2*D+1) #define _(X) MAKE_MPC_SAMPLE_EX(X,14) const MPC_SAMPLE_FORMAT __Cc [1 + 18] = { _(111.285962475327f), // 32768/2/255*sqrt(3) _(65536.000000000000f), _(21845.333333333332f), _(13107.200000000001f), _(9362.285714285713f), _(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f), _(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f), _(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f), _(2.000061037018f), _(1.000015259021f) }; #undef _ // Requantization offset // 2*D+1 = steps of quantizer const mpc_int16_t __Dc [1 + 18] = { 2, 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; #ifdef MPC_FIXED_POINT static mpc_uint32_t find_shift(double fval) { mpc_int64_t val = (mpc_int64_t) fval; mpc_uint32_t ptr = 0; if(val<0) val = -val; while(val) { val >>= 1; ptr++; } return ptr > 31 ? 0 : 31 - ptr; } #endif /* F U N C T I O N S */ #define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (mpc_uint8_t) find_shift(X)); void mpc_decoder_scale_output(mpc_decoder *d, double factor) { mpc_int32_t n; double f1, f2; #ifndef MPC_FIXED_POINT factor *= 1.0 / (double) (1<<(MPC_FIXED_POINT_SHIFT-1)); #else factor *= 1.0 / (double) (1<<(16-MPC_FIXED_POINT_SHIFT)); #endif f1 = f2 = factor; // handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476 SET_SCF(1,factor); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; for ( n = 1; n <= 128; n++ ) { SET_SCF((mpc_uint8_t)(1+n),f1); SET_SCF((mpc_uint8_t)(1-n),f2); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; } } void mpc_decoder_init_quant(mpc_decoder *d, double scale_factor) { mpc_decoder_scale_output(d, scale_factor); } musepack_src_r495/libmpcdec/huffman.h0000664000000000000000000000477511150567164016562 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file huffman.h /// Data structures and functions for huffman coding. #ifndef _MPCDEC_HUFFMAN_H_ #define _MPCDEC_HUFFMAN_H_ #ifdef WIN32 #pragma once #endif #include #ifdef __cplusplus extern "C" { #endif // LUT size parameter, LUT size is 1 << LUT_DEPTH #define LUT_DEPTH 6 /// Huffman table entry. typedef struct mpc_huffman_t { mpc_uint16_t Code; mpc_uint8_t Length; mpc_int8_t Value; } mpc_huffman; /// Huffman LUT entry. typedef struct mpc_huff_lut_t { mpc_uint8_t Length; mpc_int8_t Value; } mpc_huff_lut; /// Type used for huffman LUT decoding typedef struct mpc_lut_data_t { mpc_huffman const * const table; mpc_huff_lut lut[1 << LUT_DEPTH]; } mpc_lut_data; /// Type used for canonical huffman decoding typedef struct mpc_can_data_t { mpc_huffman const * const table; mpc_int8_t const * const sym; mpc_huff_lut lut[1 << LUT_DEPTH]; } mpc_can_data; void huff_init_lut(const int bits); #ifdef __cplusplus } #endif #endif musepack_src_r495/libmpcdec/synth_filter.c0000664000000000000000000005621611150567164017640 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file synth_filter.c /// Synthesis functions. /// \todo document me #include #include #include "decoder.h" #include "mpcdec_math.h" /* C O N S T A N T S */ #define MPC_FIXED_POINT_SYNTH_FIX 2 #undef _ #ifdef MPC_FIXED_POINT #define _(value) MPC_MAKE_FRACT_CONST((double)value/(double)(0x40000)) #else #define _(value) MAKE_MPC_SAMPLE((double)value/(double)(0x10000)) #endif static const MPC_SAMPLE_FORMAT Di_opt [32] [16] = { { _( 0), _( -29), _( 213), _( -459), _( 2037), _(-5153), _( 6574), _(-37489), _(75038), _(37489), _(6574), _( 5153), _(2037), _( 459), _(213), _(29) }, { _( -1), _( -31), _( 218), _( -519), _( 2000), _(-5517), _( 5959), _(-39336), _(74992), _(35640), _(7134), _( 4788), _(2063), _( 401), _(208), _(26) }, { _( -1), _( -35), _( 222), _( -581), _( 1952), _(-5879), _( 5288), _(-41176), _(74856), _(33791), _(7640), _( 4425), _(2080), _( 347), _(202), _(24) }, { _( -1), _( -38), _( 225), _( -645), _( 1893), _(-6237), _( 4561), _(-43006), _(74630), _(31947), _(8092), _( 4063), _(2087), _( 294), _(196), _(21) }, { _( -1), _( -41), _( 227), _( -711), _( 1822), _(-6589), _( 3776), _(-44821), _(74313), _(30112), _(8492), _( 3705), _(2085), _( 244), _(190), _(19) }, { _( -1), _( -45), _( 228), _( -779), _( 1739), _(-6935), _( 2935), _(-46617), _(73908), _(28289), _(8840), _( 3351), _(2075), _( 197), _(183), _(17) }, { _( -1), _( -49), _( 228), _( -848), _( 1644), _(-7271), _( 2037), _(-48390), _(73415), _(26482), _(9139), _( 3004), _(2057), _( 153), _(176), _(16) }, { _( -2), _( -53), _( 227), _( -919), _( 1535), _(-7597), _( 1082), _(-50137), _(72835), _(24694), _(9389), _( 2663), _(2032), _( 111), _(169), _(14) }, { _( -2), _( -58), _( 224), _( -991), _( 1414), _(-7910), _( 70), _(-51853), _(72169), _(22929), _(9592), _( 2330), _(2001), _( 72), _(161), _(13) }, { _( -2), _( -63), _( 221), _(-1064), _( 1280), _(-8209), _( -998), _(-53534), _(71420), _(21189), _(9750), _( 2006), _(1962), _( 36), _(154), _(11) }, { _( -2), _( -68), _( 215), _(-1137), _( 1131), _(-8491), _( -2122), _(-55178), _(70590), _(19478), _(9863), _( 1692), _(1919), _( 2), _(147), _(10) }, { _( -3), _( -73), _( 208), _(-1210), _( 970), _(-8755), _( -3300), _(-56778), _(69679), _(17799), _(9935), _( 1388), _(1870), _( -29), _(139), _( 9) }, { _( -3), _( -79), _( 200), _(-1283), _( 794), _(-8998), _( -4533), _(-58333), _(68692), _(16155), _(9966), _( 1095), _(1817), _( -57), _(132), _( 8) }, { _( -4), _( -85), _( 189), _(-1356), _( 605), _(-9219), _( -5818), _(-59838), _(67629), _(14548), _(9959), _( 814), _(1759), _( -83), _(125), _( 7) }, { _( -4), _( -91), _( 177), _(-1428), _( 402), _(-9416), _( -7154), _(-61289), _(66494), _(12980), _(9916), _( 545), _(1698), _(-106), _(117), _( 7) }, { _( -5), _( -97), _( 163), _(-1498), _( 185), _(-9585), _( -8540), _(-62684), _(65290), _(11455), _(9838), _( 288), _(1634), _(-127), _(111), _( 6) }, { _( -5), _(-104), _( 146), _(-1567), _( -45), _(-9727), _( -9975), _(-64019), _(64019), _( 9975), _(9727), _( 45), _(1567), _(-146), _(104), _( 5) }, { _( -6), _(-111), _( 127), _(-1634), _( -288), _(-9838), _(-11455), _(-65290), _(62684), _( 8540), _(9585), _( -185), _(1498), _(-163), _( 97), _( 5) }, { _( -7), _(-117), _( 106), _(-1698), _( -545), _(-9916), _(-12980), _(-66494), _(61289), _( 7154), _(9416), _( -402), _(1428), _(-177), _( 91), _( 4) }, { _( -7), _(-125), _( 83), _(-1759), _( -814), _(-9959), _(-14548), _(-67629), _(59838), _( 5818), _(9219), _( -605), _(1356), _(-189), _( 85), _( 4) }, { _( -8), _(-132), _( 57), _(-1817), _(-1095), _(-9966), _(-16155), _(-68692), _(58333), _( 4533), _(8998), _( -794), _(1283), _(-200), _( 79), _( 3) }, { _( -9), _(-139), _( 29), _(-1870), _(-1388), _(-9935), _(-17799), _(-69679), _(56778), _( 3300), _(8755), _( -970), _(1210), _(-208), _( 73), _( 3) }, { _(-10), _(-147), _( -2), _(-1919), _(-1692), _(-9863), _(-19478), _(-70590), _(55178), _( 2122), _(8491), _(-1131), _(1137), _(-215), _( 68), _( 2) }, { _(-11), _(-154), _( -36), _(-1962), _(-2006), _(-9750), _(-21189), _(-71420), _(53534), _( 998), _(8209), _(-1280), _(1064), _(-221), _( 63), _( 2) }, { _(-13), _(-161), _( -72), _(-2001), _(-2330), _(-9592), _(-22929), _(-72169), _(51853), _( -70), _(7910), _(-1414), _( 991), _(-224), _( 58), _( 2) }, { _(-14), _(-169), _(-111), _(-2032), _(-2663), _(-9389), _(-24694), _(-72835), _(50137), _(-1082), _(7597), _(-1535), _( 919), _(-227), _( 53), _( 2) }, { _(-16), _(-176), _(-153), _(-2057), _(-3004), _(-9139), _(-26482), _(-73415), _(48390), _(-2037), _(7271), _(-1644), _( 848), _(-228), _( 49), _( 1) }, { _(-17), _(-183), _(-197), _(-2075), _(-3351), _(-8840), _(-28289), _(-73908), _(46617), _(-2935), _(6935), _(-1739), _( 779), _(-228), _( 45), _( 1) }, { _(-19), _(-190), _(-244), _(-2085), _(-3705), _(-8492), _(-30112), _(-74313), _(44821), _(-3776), _(6589), _(-1822), _( 711), _(-227), _( 41), _( 1) }, { _(-21), _(-196), _(-294), _(-2087), _(-4063), _(-8092), _(-31947), _(-74630), _(43006), _(-4561), _(6237), _(-1893), _( 645), _(-225), _( 38), _( 1) }, { _(-24), _(-202), _(-347), _(-2080), _(-4425), _(-7640), _(-33791), _(-74856), _(41176), _(-5288), _(5879), _(-1952), _( 581), _(-222), _( 35), _( 1) }, { _(-26), _(-208), _(-401), _(-2063), _(-4788), _(-7134), _(-35640), _(-74992), _(39336), _(-5959), _(5517), _(-2000), _( 519), _(-218), _( 31), _( 1) } }; #undef _ static void mpc_compute_new_V(const MPC_SAMPLE_FORMAT* p_sample, MPC_SAMPLE_FORMAT* pV) { // Calculating new V-buffer values for left channel // calculate new V-values (ISO-11172-3, p. 39) // based upon fast-MDCT algorithm by Byeong Gi Lee MPC_SAMPLE_FORMAT A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15; MPC_SAMPLE_FORMAT B00, B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15; MPC_SAMPLE_FORMAT tmp; A00 = p_sample[ 0] + p_sample[31]; A01 = p_sample[ 1] + p_sample[30]; A02 = p_sample[ 2] + p_sample[29]; A03 = p_sample[ 3] + p_sample[28]; A04 = p_sample[ 4] + p_sample[27]; A05 = p_sample[ 5] + p_sample[26]; A06 = p_sample[ 6] + p_sample[25]; A07 = p_sample[ 7] + p_sample[24]; A08 = p_sample[ 8] + p_sample[23]; A09 = p_sample[ 9] + p_sample[22]; A10 = p_sample[10] + p_sample[21]; A11 = p_sample[11] + p_sample[20]; A12 = p_sample[12] + p_sample[19]; A13 = p_sample[13] + p_sample[18]; A14 = p_sample[14] + p_sample[17]; A15 = p_sample[15] + p_sample[16]; B00 = A00 + A15; B01 = A01 + A14; B02 = A02 + A13; B03 = A03 + A12; B04 = A04 + A11; B05 = A05 + A10; B06 = A06 + A09; B07 = A07 + A08;; B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); A00 = B00 + B07; A01 = B01 + B06; A02 = B02 + B05; A03 = B03 + B04; A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); A08 = B08 + B15; A09 = B09 + B14; A10 = B10 + B13; A11 = B11 + B12; A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); B00 = A00 + A03; B01 = A01 + A02; B02 = MPC_MULTIPLY_FRACT_CONST_FIX((A00 - A03) , 0.5411961079f , 1); B03 = MPC_MULTIPLY_FRACT_CONST_FIX((A01 - A02) , 1.3065630198f , 2); B04 = A04 + A07; B05 = A05 + A06; B06 = MPC_MULTIPLY_FRACT_CONST_FIX((A04 - A07) , 0.5411961079f , 1); B07 = MPC_MULTIPLY_FRACT_CONST_FIX((A05 - A06) , 1.3065630198f , 2); B08 = A08 + A11; B09 = A09 + A10; B10 = MPC_MULTIPLY_FRACT_CONST_FIX((A08 - A11) , 0.5411961079f , 1); B11 = MPC_MULTIPLY_FRACT_CONST_FIX((A09 - A10) , 1.3065630198f , 2); B12 = A12 + A15; B13 = A13 + A14; B14 = MPC_MULTIPLY_FRACT_CONST_FIX((A12 - A15) , 0.5411961079f , 1); B15 = MPC_MULTIPLY_FRACT_CONST_FIX((A13 - A14) , 1.3065630198f , 2); A00 = B00 + B01; A01 = MPC_MULTIPLY_FRACT_CONST_FIX((B00 - B01) , 0.7071067691f , 1); A02 = B02 + B03; A03 = MPC_MULTIPLY_FRACT_CONST_FIX((B02 - B03) , 0.7071067691f , 1); A04 = B04 + B05; A05 = MPC_MULTIPLY_FRACT_CONST_FIX((B04 - B05) , 0.7071067691f , 1); A06 = B06 + B07; A07 = MPC_MULTIPLY_FRACT_CONST_FIX((B06 - B07) , 0.7071067691f , 1); A08 = B08 + B09; A09 = MPC_MULTIPLY_FRACT_CONST_FIX((B08 - B09) , 0.7071067691f , 1); A10 = B10 + B11; A11 = MPC_MULTIPLY_FRACT_CONST_FIX((B10 - B11) , 0.7071067691f , 1); A12 = B12 + B13; A13 = MPC_MULTIPLY_FRACT_CONST_FIX((B12 - B13) , 0.7071067691f , 1); A14 = B14 + B15; A15 = MPC_MULTIPLY_FRACT_CONST_FIX((B14 - B15) , 0.7071067691f , 1); pV[48] = -A00; pV[ 0] = A01; pV[40] = -A02 - (pV[ 8] = A03); pV[36] = -((pV[ 4] = A05 + (pV[12] = A07)) + A06); pV[44] = - A04 - A06 - A07; pV[ 6] = (pV[10] = A11 + (pV[14] = A15)) + A13; pV[38] = (pV[34] = -(pV[ 2] = A09 + A13 + A15) - A14) + A09 - A10 - A11; pV[46] = (tmp = -(A12 + A14 + A15)) - A08; pV[42] = tmp - A10 - A11; A00 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 0] - p_sample[31]) , 0.5006030202f , MPC_FIXED_POINT_SYNTH_FIX); A01 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 1] - p_sample[30]) , 0.5054709315f , MPC_FIXED_POINT_SYNTH_FIX); A02 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 2] - p_sample[29]) , 0.5154473186f , MPC_FIXED_POINT_SYNTH_FIX); A03 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 3] - p_sample[28]) , 0.5310425758f , MPC_FIXED_POINT_SYNTH_FIX); A04 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 4] - p_sample[27]) , 0.5531039238f , MPC_FIXED_POINT_SYNTH_FIX); A05 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 5] - p_sample[26]) , 0.5829349756f , MPC_FIXED_POINT_SYNTH_FIX); A06 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 6] - p_sample[25]) , 0.6225041151f , MPC_FIXED_POINT_SYNTH_FIX); A07 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 7] - p_sample[24]) , 0.6748083234f , MPC_FIXED_POINT_SYNTH_FIX); A08 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 8] - p_sample[23]) , 0.7445362806f , MPC_FIXED_POINT_SYNTH_FIX); A09 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 9] - p_sample[22]) , 0.8393496275f , MPC_FIXED_POINT_SYNTH_FIX); A10 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[10] - p_sample[21]) , 0.9725682139f , MPC_FIXED_POINT_SYNTH_FIX); #if MPC_FIXED_POINT_SYNTH_FIX>=2 A11 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[11] - p_sample[20]) , 1.1694399118f , MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[12] - p_sample[19]) , 1.4841645956f , MPC_FIXED_POINT_SYNTH_FIX); #else A11 = MPC_SCALE_CONST_SHR ((p_sample[11] - p_sample[20]) , 1.1694399118f , 30, MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_SCALE_CONST_SHR ((p_sample[12] - p_sample[19]) , 1.4841645956f , 30, MPC_FIXED_POINT_SYNTH_FIX); #endif A13 = MPC_SCALE_CONST_SHR ((p_sample[13] - p_sample[18]) , 2.0577809811f , 29, MPC_FIXED_POINT_SYNTH_FIX); A14 = MPC_SCALE_CONST_SHR ((p_sample[14] - p_sample[17]) , 3.4076085091f , 29, MPC_FIXED_POINT_SYNTH_FIX); A15 = MPC_SCALE_CONST_SHR ((p_sample[15] - p_sample[16]) , 10.1900081635f, 27 ,MPC_FIXED_POINT_SYNTH_FIX); B00 = A00 + A15; B01 = A01 + A14; B02 = A02 + A13; B03 = A03 + A12; B04 = A04 + A11; B05 = A05 + A10; B06 = A06 + A09; B07 = A07 + A08; B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); A00 = B00 + B07; A01 = B01 + B06; A02 = B02 + B05; A03 = B03 + B04; A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); A08 = B08 + B15; A09 = B09 + B14; A10 = B10 + B13; A11 = B11 + B12; A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); B00 = A00 + A03; B01 = A01 + A02; B02 = MPC_SCALE_CONST((A00 - A03) , 0.5411961079f , 31); B03 = MPC_SCALE_CONST((A01 - A02) , 1.3065630198f , 30); B04 = A04 + A07; B05 = A05 + A06; B06 = MPC_SCALE_CONST((A04 - A07) , 0.5411961079f , 31); B07 = MPC_SCALE_CONST((A05 - A06) , 1.3065630198f , 30); B08 = A08 + A11; B09 = A09 + A10; B10 = MPC_SCALE_CONST((A08 - A11) , 0.5411961079f , 31); B11 = MPC_SCALE_CONST((A09 - A10) , 1.3065630198f , 30); B12 = A12 + A15; B13 = A13 + A14; B14 = MPC_SCALE_CONST((A12 - A15) , 0.5411961079f , 31); B15 = MPC_SCALE_CONST((A13 - A14) , 1.3065630198f , 30); A00 = MPC_SHL(B00 + B01, MPC_FIXED_POINT_SYNTH_FIX); A01 = MPC_SCALE_CONST_SHL((B00 - B01) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A02 = MPC_SHL(B02 + B03, MPC_FIXED_POINT_SYNTH_FIX); A03 = MPC_SCALE_CONST_SHL((B02 - B03) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A04 = MPC_SHL(B04 + B05, MPC_FIXED_POINT_SYNTH_FIX); A05 = MPC_SCALE_CONST_SHL((B04 - B05) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A06 = MPC_SHL(B06 + B07, MPC_FIXED_POINT_SYNTH_FIX); A07 = MPC_SCALE_CONST_SHL((B06 - B07) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A08 = MPC_SHL(B08 + B09, MPC_FIXED_POINT_SYNTH_FIX); A09 = MPC_SCALE_CONST_SHL((B08 - B09) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A10 = MPC_SHL(B10 + B11, MPC_FIXED_POINT_SYNTH_FIX); A11 = MPC_SCALE_CONST_SHL((B10 - B11) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_SHL(B12 + B13, MPC_FIXED_POINT_SYNTH_FIX); A13 = MPC_SCALE_CONST_SHL((B12 - B13) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A14 = MPC_SHL(B14 + B15, MPC_FIXED_POINT_SYNTH_FIX); A15 = MPC_SCALE_CONST_SHL((B14 - B15) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); // mehrfach verwendete Ausdrcke: A04+A06+A07, A09+A13+A15 pV[ 5] = (pV[11] = (pV[13] = A07 + (pV[15] = A15)) + A11) + A05 + A13; pV[ 7] = (pV[ 9] = A03 + A11 + A15) + A13; pV[33] = -(pV[ 1] = A01 + A09 + A13 + A15) - A14; pV[35] = -(pV[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14; pV[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07; pV[39] = tmp - A02 - A03; // abh�gig vom Befehl drber pV[41] = (tmp += A13 - A12) - A02 - A03; // abh�gig vom Befehl 2 drber pV[43] = tmp - A04 - A06 - A07; // abh�gig von Befehlen 1 und 3 drber pV[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00; pV[45] = tmp - A04 - A06 - A07; // abh�gig vom Befehl drber pV[32] = -pV[ 0]; pV[31] = -pV[ 1]; pV[30] = -pV[ 2]; pV[29] = -pV[ 3]; pV[28] = -pV[ 4]; pV[27] = -pV[ 5]; pV[26] = -pV[ 6]; pV[25] = -pV[ 7]; pV[24] = -pV[ 8]; pV[23] = -pV[ 9]; pV[22] = -pV[10]; pV[21] = -pV[11]; pV[20] = -pV[12]; pV[19] = -pV[13]; pV[18] = -pV[14]; pV[17] = -pV[15]; pV[63] = pV[33]; pV[62] = pV[34]; pV[61] = pV[35]; pV[60] = pV[36]; pV[59] = pV[37]; pV[58] = pV[38]; pV[57] = pV[39]; pV[56] = pV[40]; pV[55] = pV[41]; pV[54] = pV[42]; pV[53] = pV[43]; pV[52] = pV[44]; pV[51] = pV[45]; pV[50] = pV[46]; pV[49] = pV[47]; } static void mpc_synthese_filter_float_internal(MPC_SAMPLE_FORMAT* p_out, MPC_SAMPLE_FORMAT* pV, const MPC_SAMPLE_FORMAT* pY, mpc_int_t channels) { mpc_uint32_t n; for ( n = 0; n < 36; n++, pY += 32 ) { MPC_SAMPLE_FORMAT* pData = p_out; const MPC_SAMPLE_FORMAT* pD = (const MPC_SAMPLE_FORMAT*) &Di_opt; mpc_int32_t k; pV -= 64; mpc_compute_new_V( pY, pV ); for ( k = 0; k < 32; k++, pD += 16, pV++ ) { *pData = MPC_SHL( MPC_MULTIPLY_FRACT(pV[ 0], pD[ 0]) + MPC_MULTIPLY_FRACT(pV[ 96], pD[ 1]) + MPC_MULTIPLY_FRACT(pV[128], pD[ 2]) + MPC_MULTIPLY_FRACT(pV[224], pD[ 3]) + MPC_MULTIPLY_FRACT(pV[256], pD[ 4]) + MPC_MULTIPLY_FRACT(pV[352], pD[ 5]) + MPC_MULTIPLY_FRACT(pV[384], pD[ 6]) + MPC_MULTIPLY_FRACT(pV[480], pD[ 7]) + MPC_MULTIPLY_FRACT(pV[512], pD[ 8]) + MPC_MULTIPLY_FRACT(pV[608], pD[ 9]) + MPC_MULTIPLY_FRACT(pV[640], pD[10]) + MPC_MULTIPLY_FRACT(pV[736], pD[11]) + MPC_MULTIPLY_FRACT(pV[768], pD[12]) + MPC_MULTIPLY_FRACT(pV[864], pD[13]) + MPC_MULTIPLY_FRACT(pV[896], pD[14]) + MPC_MULTIPLY_FRACT(pV[992], pD[15]) , 2); pData += channels; } pV -= 32; //bleh p_out += 32 * channels; } } void mpc_decoder_synthese_filter_float(mpc_decoder* p_dec, MPC_SAMPLE_FORMAT* p_out, mpc_int_t channels) { /********* left channel ********/ memmove(&p_dec->V_L[MPC_V_MEM], p_dec->V_L, 960 * sizeof *p_dec->V_L); mpc_synthese_filter_float_internal(p_out, &p_dec->V_L[MPC_V_MEM], p_dec->Y_L[0], channels); /******** right channel ********/ if (channels > 1) { memmove(&p_dec->V_R[MPC_V_MEM], p_dec->V_R, 960 * sizeof *p_dec->V_R); mpc_synthese_filter_float_internal(p_out + 1, &p_dec->V_R[MPC_V_MEM], p_dec->Y_R[0], channels); } } /*******************************************/ /* */ /* dithered synthesis */ /* */ /*******************************************/ static const mpc_uint8_t Parity [256] = { // parity 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 }; /* * This is a simple random number generator with good quality for audio purposes. * It consists of two polycounters with opposite rotation direction and different * periods. The periods are coprime, so the total period is the product of both. * * ------------------------------------------------------------------------------------------------- * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| * | ------------------------------------------------------------------------------------------------- * | | | | | | | * | +--+--+--+-XOR-+--------+ * | | * +--------------------------------------------------------------------------------------+ * * ------------------------------------------------------------------------------------------------- * |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+ * ------------------------------------------------------------------------------------------------- | * | | | | | * +--+----XOR----+--+ | * | | * +----------------------------------------------------------------------------------------+ * * * The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481, * which gives a period of 18.410.713.077.675.721.215. The result is the * XORed values of both generators. */ mpc_uint32_t mpc_random_int(mpc_decoder* p_dec) { #if 1 mpc_uint32_t t1, t2, t3, t4; t3 = t1 = p_dec->__r1; t4 = t2 = p_dec->__r2; // Parity calculation is done via table lookup, this is also available t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable t1 = Parity[t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations. t1 <<= 31; t2 = Parity[t2]; return (p_dec->__r1 = (t3 >> 1) | t1 ) ^ (p_dec->__r2 = (t4 + t4) | t2 ); #else return (p_dec->__r1 = (p_dec->__r1 >> 1) | ((mpc_uint32_t) Parity[ p_dec->__r1 & 0xF5] << 31)) ^ (p_dec->__r2 = (p_dec->__r2 << 1) | (mpc_uint32_t) Parity[(p_dec->__r2 >> 25) & 0x63]); #endif } musepack_src_r495/mpcchap/0000775000000000000000000000000012765302354014442 5ustar rootrootmusepack_src_r495/mpcchap/Makefile.am0000664000000000000000000000066411234134160016470 0ustar rootrootEXTRA_DIST = CMakeLists.txt bin_PROGRAMS = mpcchap common_sources = ../common/tags.c ../common/crc32.c AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO mpcchap_SOURCES = dictionary.c iniparser.c mpcchap.c $(common_sources) \ dictionary.h iniparser.h mpcchap_LDADD = $(top_builddir)/libmpcdec/libmpcdec.la \ $(top_builddir)/libmpcenc/libmpcenc.a \ -lm -lcuefile musepack_src_r495/mpcchap/dictionary.h0000664000000000000000000001472711103162206016754 0ustar rootroot /*-------------------------------------------------------------------------*/ /** @file dictionary.h @author N. Devillard @date Sep 2007 @version $Revision: 1.12 $ @brief Implements a dictionary for string variables. This module implements a simple dictionary object, i.e. a list of string/string associations. This object is useful to store e.g. informations retrieved from a configuration file (ini files). */ /*--------------------------------------------------------------------------*/ /* $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ $Author: ndevilla $ $Date: 2007-11-23 21:37:00 $ $Revision: 1.12 $ */ #ifndef _DICTIONARY_H_ #define _DICTIONARY_H_ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ #include #include #include #ifndef _MSC_VER # include #endif /*--------------------------------------------------------------------------- New types ---------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ /** @brief Dictionary object This object contains a list of string/string associations. Each association is identified by a unique string key. Looking up values in the dictionary is speeded up by the use of a (hopefully collision-free) hash function. */ /*-------------------------------------------------------------------------*/ typedef struct _dictionary_ { int n ; /** Number of entries in dictionary */ int size ; /** Storage size */ char ** val ; /** List of string values */ char ** key ; /** List of string keys */ unsigned * hash ; /** List of hash values for keys */ } dictionary ; /*--------------------------------------------------------------------------- Function prototypes ---------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ /** @brief Compute the hash key for a string. @param key Character string to use for key. @return 1 unsigned int on at least 32 bits. This hash function has been taken from an Article in Dr Dobbs Journal. This is normally a collision-free function, distributing keys evenly. The key is stored anyway in the struct so that collision can be avoided by comparing the key itself in last resort. */ /*--------------------------------------------------------------------------*/ unsigned dictionary_hash(char * key); /*-------------------------------------------------------------------------*/ /** @brief Create a new dictionary object. @param size Optional initial size of the dictionary. @return 1 newly allocated dictionary objet. This function allocates a new dictionary object of given size and returns it. If you do not know in advance (roughly) the number of entries in the dictionary, give size=0. */ /*--------------------------------------------------------------------------*/ dictionary * dictionary_new(int size); /*-------------------------------------------------------------------------*/ /** @brief Delete a dictionary object @param d dictionary object to deallocate. @return void Deallocate a dictionary object and all memory associated to it. */ /*--------------------------------------------------------------------------*/ void dictionary_del(dictionary * vd); /*-------------------------------------------------------------------------*/ /** @brief Get a value from a dictionary. @param d dictionary object to search. @param key Key to look for in the dictionary. @param def Default value to return if key not found. @return 1 pointer to internally allocated character string. This function locates a key in a dictionary and returns a pointer to its value, or the passed 'def' pointer if no such key can be found in dictionary. The returned character pointer points to data internal to the dictionary object, you should not try to free it or modify it. */ /*--------------------------------------------------------------------------*/ char * dictionary_get(dictionary * d, char * key, char * def); /*-------------------------------------------------------------------------*/ /** @brief Set a value in a dictionary. @param d dictionary object to modify. @param key Key to modify or add. @param val Value to add. @return int 0 if Ok, anything else otherwise If the given key is found in the dictionary, the associated value is replaced by the provided one. If the key cannot be found in the dictionary, it is added to it. It is Ok to provide a NULL value for val, but NULL values for the dictionary or the key are considered as errors: the function will return immediately in such a case. Notice that if you dictionary_set a variable to NULL, a call to dictionary_get will return a NULL value: the variable will be found, and its value (NULL) is returned. In other words, setting the variable content to NULL is equivalent to deleting the variable from the dictionary. It is not possible (in this implementation) to have a key in the dictionary without value. This function returns non-zero in case of failure. */ /*--------------------------------------------------------------------------*/ int dictionary_set(dictionary * vd, char * key, char * val); /*-------------------------------------------------------------------------*/ /** @brief Delete a key in a dictionary @param d dictionary object to modify. @param key Key to remove. @return void This function deletes a key in a dictionary. Nothing is done if the key cannot be found. */ /*--------------------------------------------------------------------------*/ void dictionary_unset(dictionary * d, char * key); /*-------------------------------------------------------------------------*/ /** @brief Dump a dictionary to an opened file pointer. @param d Dictionary to dump @param f Opened file pointer. @return void Dumps a dictionary onto an opened file pointer. Key pairs are printed out as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as output file pointers. */ /*--------------------------------------------------------------------------*/ void dictionary_dump(dictionary * d, FILE * out); #endif musepack_src_r495/mpcchap/dictionary.c0000664000000000000000000002614511103162206016744 0ustar rootroot/*-------------------------------------------------------------------------*/ /** @file dictionary.c @author N. Devillard @date Sep 2007 @version $Revision: 1.27 $ @brief Implements a dictionary for string variables. This module implements a simple dictionary object, i.e. a list of string/string associations. This object is useful to store e.g. informations retrieved from a configuration file (ini files). */ /*--------------------------------------------------------------------------*/ /* $Id: dictionary.c,v 1.27 2007-11-23 21:39:18 ndevilla Exp $ $Revision: 1.27 $ */ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ #include "dictionary.h" /** Maximum value size for integers and doubles. */ #define MAXVALSZ 1024 /** Minimal allocated number of entries in a dictionary */ #define DICTMINSZ 128 /** Invalid key token */ #define DICT_INVALID_KEY ((char*)-1) /*--------------------------------------------------------------------------- Private functions ---------------------------------------------------------------------------*/ /* Doubles the allocated size associated to a pointer */ /* 'size' is the current allocated size. */ static void * mem_double(void * ptr, int size) { void * newptr ; newptr = calloc(2*size, 1); if (newptr==NULL) { return NULL ; } memcpy(newptr, ptr, size); free(ptr); return newptr ; } /*-------------------------------------------------------------------------*/ /** @brief Duplicate a string @param s String to duplicate @return Pointer to a newly allocated string, to be freed with free() This is a replacement for strdup(). This implementation is provided for systems that do not have it. */ /*--------------------------------------------------------------------------*/ static char * xstrdup(char * s) { char * t ; if (!s) return NULL ; t = malloc(strlen(s)+1) ; if (t) { strcpy(t,s); } return t ; } /*--------------------------------------------------------------------------- Function codes ---------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ /** @brief Compute the hash key for a string. @param key Character string to use for key. @return 1 unsigned int on at least 32 bits. This hash function has been taken from an Article in Dr Dobbs Journal. This is normally a collision-free function, distributing keys evenly. The key is stored anyway in the struct so that collision can be avoided by comparing the key itself in last resort. */ /*--------------------------------------------------------------------------*/ unsigned dictionary_hash(char * key) { int len ; unsigned hash ; int i ; len = strlen(key); for (hash=0, i=0 ; i>6) ; } hash += (hash <<3); hash ^= (hash >>11); hash += (hash <<15); return hash ; } /*-------------------------------------------------------------------------*/ /** @brief Create a new dictionary object. @param size Optional initial size of the dictionary. @return 1 newly allocated dictionary objet. This function allocates a new dictionary object of given size and returns it. If you do not know in advance (roughly) the number of entries in the dictionary, give size=0. */ /*--------------------------------------------------------------------------*/ dictionary * dictionary_new(int size) { dictionary * d ; /* If no size was specified, allocate space for DICTMINSZ */ if (sizesize = size ; d->val = (char **)calloc(size, sizeof(char*)); d->key = (char **)calloc(size, sizeof(char*)); d->hash = (unsigned int *)calloc(size, sizeof(unsigned)); return d ; } /*-------------------------------------------------------------------------*/ /** @brief Delete a dictionary object @param d dictionary object to deallocate. @return void Deallocate a dictionary object and all memory associated to it. */ /*--------------------------------------------------------------------------*/ void dictionary_del(dictionary * d) { int i ; if (d==NULL) return ; for (i=0 ; isize ; i++) { if (d->key[i]!=NULL) free(d->key[i]); if (d->val[i]!=NULL) free(d->val[i]); } free(d->val); free(d->key); free(d->hash); free(d); return ; } /*-------------------------------------------------------------------------*/ /** @brief Get a value from a dictionary. @param d dictionary object to search. @param key Key to look for in the dictionary. @param def Default value to return if key not found. @return 1 pointer to internally allocated character string. This function locates a key in a dictionary and returns a pointer to its value, or the passed 'def' pointer if no such key can be found in dictionary. The returned character pointer points to data internal to the dictionary object, you should not try to free it or modify it. */ /*--------------------------------------------------------------------------*/ char * dictionary_get(dictionary * d, char * key, char * def) { unsigned hash ; int i ; hash = dictionary_hash(key); for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; /* Compare hash */ if (hash==d->hash[i]) { /* Compare string, to avoid hash collisions */ if (!strcmp(key, d->key[i])) { return d->val[i] ; } } } return def ; } /*-------------------------------------------------------------------------*/ /** @brief Set a value in a dictionary. @param d dictionary object to modify. @param key Key to modify or add. @param val Value to add. @return int 0 if Ok, anything else otherwise If the given key is found in the dictionary, the associated value is replaced by the provided one. If the key cannot be found in the dictionary, it is added to it. It is Ok to provide a NULL value for val, but NULL values for the dictionary or the key are considered as errors: the function will return immediately in such a case. Notice that if you dictionary_set a variable to NULL, a call to dictionary_get will return a NULL value: the variable will be found, and its value (NULL) is returned. In other words, setting the variable content to NULL is equivalent to deleting the variable from the dictionary. It is not possible (in this implementation) to have a key in the dictionary without value. This function returns non-zero in case of failure. */ /*--------------------------------------------------------------------------*/ int dictionary_set(dictionary * d, char * key, char * val) { int i ; unsigned hash ; if (d==NULL || key==NULL) return -1 ; /* Compute hash for this key */ hash = dictionary_hash(key) ; /* Find if value is already in dictionary */ if (d->n>0) { for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (hash==d->hash[i]) { /* Same hash value */ if (!strcmp(key, d->key[i])) { /* Same key */ /* Found a value: modify and return */ if (d->val[i]!=NULL) free(d->val[i]); d->val[i] = val ? xstrdup(val) : NULL ; /* Value has been modified: return */ return 0 ; } } } } /* Add a new value */ /* See if dictionary needs to grow */ if (d->n==d->size) { /* Reached maximum size: reallocate dictionary */ d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ; d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ; d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ; if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) { /* Cannot grow dictionary */ return -1 ; } /* Double size */ d->size *= 2 ; } /* Insert key in the first empty slot */ for (i=0 ; isize ; i++) { if (d->key[i]==NULL) { /* Add key here */ break ; } } /* Copy key */ d->key[i] = xstrdup(key); d->val[i] = val ? xstrdup(val) : NULL ; d->hash[i] = hash; d->n ++ ; return 0 ; } /*-------------------------------------------------------------------------*/ /** @brief Delete a key in a dictionary @param d dictionary object to modify. @param key Key to remove. @return void This function deletes a key in a dictionary. Nothing is done if the key cannot be found. */ /*--------------------------------------------------------------------------*/ void dictionary_unset(dictionary * d, char * key) { unsigned hash ; int i ; if (key == NULL) { return; } hash = dictionary_hash(key); for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; /* Compare hash */ if (hash==d->hash[i]) { /* Compare string, to avoid hash collisions */ if (!strcmp(key, d->key[i])) { /* Found key */ break ; } } } if (i>=d->size) /* Key not found */ return ; free(d->key[i]); d->key[i] = NULL ; if (d->val[i]!=NULL) { free(d->val[i]); d->val[i] = NULL ; } d->hash[i] = 0 ; d->n -- ; return ; } /*-------------------------------------------------------------------------*/ /** @brief Dump a dictionary to an opened file pointer. @param d Dictionary to dump @param f Opened file pointer. @return void Dumps a dictionary onto an opened file pointer. Key pairs are printed out as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as output file pointers. */ /*--------------------------------------------------------------------------*/ void dictionary_dump(dictionary * d, FILE * out) { int i ; if (d==NULL || out==NULL) return ; if (d->n<1) { fprintf(out, "empty dictionary\n"); return ; } for (i=0 ; isize ; i++) { if (d->key[i]) { fprintf(out, "%20s\t[%s]\n", d->key[i], d->val[i] ? d->val[i] : "UNDEF"); } } return ; } /* Test code */ #ifdef TESTDIC #define NVALS 20000 int main(int argc, char *argv[]) { dictionary * d ; char * val ; int i ; char cval[90] ; /* Allocate dictionary */ printf("allocating...\n"); d = dictionary_new(0); /* Set values in dictionary */ printf("setting %d values...\n", NVALS); for (i=0 ; in != 0) { printf("error deleting values\n"); } printf("deallocating...\n"); dictionary_del(d); return 0 ; } #endif /* vim: set ts=4 et sw=4 tw=75 */ musepack_src_r495/mpcchap/CMakeLists.txt0000664000000000000000000000144211433773325017204 0ustar rootrootFIND_PATH(CUEFILE_INCLUDE_DIR cuetools/cuefile.h ${libmpc_SOURCE_DIR}/../libcuefile/include ) FIND_LIBRARY(CUEFILE_LIBRARY NAMES cuefile PATHS ${CUEFILE_INCLUDE_DIR}/../src ) include_directories(${libmpc_SOURCE_DIR}/include) include_directories(${CUEFILE_INCLUDE_DIR}) link_directories(${libmpc_BINARY_DIR}/libmpcdec) link_directories(${libmpc_BINARY_DIR}/libmpcenc) add_executable(mpcchap mpcchap.c dictionary.c iniparser.c ${libmpc_SOURCE_DIR}/common/tags.c) if(SHARED) target_link_libraries(mpcchap mpcdec) else(SHARED) target_link_libraries(mpcchap mpcdec_static) endif(SHARED) target_link_libraries(mpcchap mpcenc_static) target_link_libraries(mpcchap ${CUEFILE_LIBRARY}) if(NOT MSVC) target_link_libraries(mpcchap m) endif(NOT MSVC) install(TARGETS mpcchap RUNTIME DESTINATION bin) musepack_src_r495/mpcchap/mpcchap.c0000664000000000000000000002412512644540266016227 0ustar rootroot/* Copyright (c) 2008-2009, The Musepack Development Team 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 along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "../libmpcdec/internal.h" #include "../libmpcenc/libmpcenc.h" #include "iniparser.h" #include #include #include // tags.c void Init_Tags ( void ); int FinalizeTags ( FILE* fp, unsigned int Version, unsigned int flags ); int addtag ( const char* key, size_t keylen, const char* value, size_t valuelen, int converttoutf8, int flags ); #define TAG_NO_HEADER 1 #define TAG_NO_FOOTER 2 #define TAG_NO_PREAMBLE 4 #define TAG_VERSION 2000 #ifdef _MSC_VER # include # define atoll _atoi64 # define ftruncate chsize # define strcasecmp stricmp #endif #define MPCCHAP_MAJOR 0 #define MPCCHAP_MINOR 9 #define MPCCHAP_BUILD 0 #define _cat(a,b,c) #a"."#b"."#c #define cat(a,b,c) _cat(a,b,c) #define MPCCHAP_VERSION cat(MPCCHAP_MAJOR,MPCCHAP_MINOR,MPCCHAP_BUILD) const char About[] = "%s - Musepack (MPC) sv8 chapter editor v" MPCCHAP_VERSION " (C) 2008-2009 MDT\nBuilt " __DATE__ " " __TIME__ "\n"; static const int Ptis[] = { PTI_TITLE, PTI_PERFORMER, PTI_SONGWRITER, PTI_COMPOSER, PTI_ARRANGER, PTI_MESSAGE, PTI_GENRE}; static char const * const APE_keys[] = {"Title", "Artist", "Songwriter", "Composer", "Arranger", "Comment", "Genre"}; static void usage(const char *exename) { fprintf(stderr, "Usage: %s \n" " if chapterfile.ini exists, chapter tags in infile.mpc will be\n" " replaced by those from chapterfile.ini, else chapters will be\n" " dumped to chapterfile.ini\n" " chapterfile.ini is something like :\n" " [chapter_start_sample]\n" " SomeKey=Some Value\n" " SomeOtherKey=Some Other Value\n" " [other_chapter_start]\n" " YouKnowWhatKey=I think you start to understand ...\n" , exename); } mpc_status add_chaps_ini(char * mpc_file, char * chap_file, mpc_demux * demux, mpc_streaminfo * si) { struct stat stbuf; FILE * in_file; int chap_pos, end_pos, chap_size, i, nchap; char * tmp_buff; dictionary * dict; mpc_status ret = MPC_STATUS_OK; chap_pos = (demux->chap_pos >> 3) + si->header_position; end_pos = mpc_demux_pos(demux) >> 3; chap_size = end_pos - chap_pos; stat(mpc_file, &stbuf); tmp_buff = malloc(stbuf.st_size - chap_pos - chap_size); in_file = fopen( mpc_file, "r+b" ); fseek(in_file, chap_pos + chap_size, SEEK_SET); if (1 != fread(tmp_buff, stbuf.st_size - chap_pos - chap_size, 1, in_file)) { ret = MPC_STATUS_FAIL; goto error_read_in_file; } fseek(in_file, chap_pos, SEEK_SET); dict = iniparser_load(chap_file); nchap = iniparser_getnsec(dict); for (i = 0; i < nchap; i++) { int j, nitem, ntags = 0, tag_len = 0, offset_size; mpc_uint16_t gain = 0, peak = 0; char * chap_sec = iniparser_getsecname(dict, i), block_header[12] = "CT", sample_offset[10]; mpc_int64_t chap_pos = atoll(chap_sec); if (chap_pos > si->samples - si->beg_silence) fprintf(stderr, "warning : chapter %i starts @ %" PRId64 " samples after the end of the stream (%" PRId64 ")\n", i + 1, chap_pos, si->samples - si->beg_silence); Init_Tags(); nitem = iniparser_getnkey(dict, i); for (j = 0; j < nitem; j++) { char * item_key, * item_value; int key_len, item_len; item_key = iniparser_getkeyname(dict, i, j, & item_value); if (strcmp(item_key, "gain") == 0) gain = atoi(item_value); else if (strcmp(item_key, "peak") == 0) peak = atoi(item_value); else { key_len = strlen(item_key); item_len = strlen(item_value); addtag(item_key, key_len, item_value, item_len, 0, 0); tag_len += key_len + item_len; ntags++; } } if (ntags > 0) tag_len += 24 + ntags * 9; offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE); tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE); fwrite(block_header, 1, tag_len + 2, in_file); fwrite(sample_offset, 1, offset_size, in_file); sample_offset[0] = gain >> 8; sample_offset[1] = gain & 0xFF; sample_offset[2] = peak >> 8; sample_offset[3] = peak & 0xFF; fwrite(sample_offset, 1, 4, in_file); FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE); } fwrite(tmp_buff, 1, stbuf.st_size - chap_pos - chap_size, in_file); if (0 != ftruncate(fileno(in_file), ftell(in_file))) ret = MPC_STATUS_FAIL; iniparser_freedict(dict); error_read_in_file: fclose(in_file); free(tmp_buff); return ret; } mpc_status add_chaps_cue(char * mpc_file, char * chap_file, mpc_demux * demux, mpc_streaminfo * si) { Cd *cd = 0; int nchap, format = UNKNOWN; struct stat stbuf; FILE * in_file; int chap_pos, end_pos, chap_size, i; char * tmp_buff; mpc_status ret = MPC_STATUS_OK; if (0 == (cd = cf_parse(chap_file, &format))) { fprintf(stderr, "%s: input file error\n", chap_file); return !MPC_STATUS_OK; } chap_pos = (demux->chap_pos >> 3) + si->header_position; end_pos = mpc_demux_pos(demux) >> 3; chap_size = end_pos - chap_pos; stat(mpc_file, &stbuf); tmp_buff = malloc(stbuf.st_size - chap_pos - chap_size); in_file = fopen( mpc_file, "r+b" ); fseek(in_file, chap_pos + chap_size, SEEK_SET); if (1 != fread(tmp_buff, stbuf.st_size - chap_pos - chap_size, 1, in_file)) { ret = MPC_STATUS_FAIL; goto error_read_in_file; } fseek(in_file, chap_pos, SEEK_SET); nchap = cd_get_ntrack(cd); for (i = 1; i <= nchap; i++) { char track_buf[16], block_header[12] = "CT", sample_offset[10]; int j, nitem = 0, tag_len = 0, key_len, item_len, offset_size; Track * track; Cdtext *cdtext; mpc_int64_t chap_pos; track = cd_get_track (cd, i); cdtext = track_get_cdtext(track); // position du chapitre chap_pos = (mpc_int64_t) si->sample_freq * track_get_start (track) / 75; if (chap_pos > si->samples - si->beg_silence) fprintf(stderr, "warning : chapter %i starts @ %" PRId64 " samples after the end of the stream (%" PRId64 ")\n", i, chap_pos, si->samples - si->beg_silence); Init_Tags(); sprintf(track_buf, "%i/%i", i, nchap); key_len = 5; item_len = strlen(track_buf); addtag("Track", key_len, track_buf, item_len, 0, 0); tag_len += key_len + item_len; nitem++; for (j = 0; j < (sizeof(Ptis) / sizeof(*Ptis)); j++) { char const * item_key = APE_keys[j], * item_value; item_value = cdtext_get (Ptis[j], cdtext); if (item_value != 0) { key_len = strlen(item_key); item_len = strlen(item_value); addtag(item_key, key_len, item_value, item_len, 0, 0); tag_len += key_len + item_len; nitem++; } } tag_len += 24 + nitem * 9; offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE); tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE); fwrite(block_header, 1, tag_len + 2, in_file); fwrite(sample_offset, 1, offset_size, in_file); fwrite("\0\0\0\0", 1, 4, in_file); // put unknow chapter gain / peak FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE); } fwrite(tmp_buff, 1, stbuf.st_size - chap_pos - chap_size, in_file); if (0 != ftruncate(fileno(in_file), ftell(in_file))) ret = MPC_STATUS_FAIL; error_read_in_file: fclose(in_file); free(tmp_buff); return ret; } mpc_status dump_chaps(mpc_demux * demux, char * chap_file, int chap_nb) { int i; FILE * out_file; mpc_chap_info const * chap; if (chap_nb <= 0) return MPC_STATUS_OK; out_file = fopen(chap_file, "wb"); if (out_file == 0) return !MPC_STATUS_OK; for (i = 0; i < chap_nb; i++) { chap = mpc_demux_chap(demux, i); fprintf(out_file, "[%" PRId64 "]\ngain=%i\npeak=%i\n", chap->sample, chap->gain, chap->peak); if (chap->tag_size > 0) { int item_count, j; char const * tag = chap->tag; item_count = tag[8] | (tag[9] << 8) | (tag[10] << 16) | (tag[11] << 24); tag += 24; for( j = 0; j < item_count; j++){ int key_len = strlen(tag + 8); int value_len = tag[0] | (tag[1] << 8) | (tag[2] << 16) | (tag[3] << 24); fprintf(out_file, "%s=\"%.*s\"\n", tag + 8, value_len, tag + 9 + key_len); tag += 9 + key_len + value_len; } } fprintf(out_file, "\n"); } fclose(out_file); return MPC_STATUS_OK; } int main(int argc, char **argv) { mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; char * mpc_file, * chap_file; mpc_status err; FILE * test_file; int chap_nb; fprintf(stderr, About, argv[0]); if (argc != 3) usage(argv[0]); mpc_file = argv[1]; chap_file = argv[2]; err = mpc_reader_init_stdio(&reader, mpc_file); if(err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if(!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); if (si.stream_version < 8) { fprintf(stderr, "this file cannot be edited, please convert it first to sv8 using mpc2sv8\n"); exit(!MPC_STATUS_OK); } chap_nb = mpc_demux_chap_nb(demux); test_file = fopen(chap_file, "rb" ); if (test_file == 0) { err = dump_chaps(demux, chap_file, chap_nb); } else { int len; fclose(test_file); len = strlen(chap_file); if (strcasecmp(chap_file + len - 4, ".cue") == 0 || strcasecmp(chap_file + len - 4, ".toc") == 0) err = add_chaps_cue(mpc_file, chap_file, demux, &si); else if (strcasecmp(chap_file + len - 4, ".ini") == 0) err = add_chaps_ini(mpc_file, chap_file, demux, &si); else err = !MPC_STATUS_OK; } mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); return err; } musepack_src_r495/mpcchap/iniparser.c0000664000000000000000000005275711700102077016606 0ustar rootroot /*-------------------------------------------------------------------------*/ /** @file iniparser.c @author N. Devillard @date Sep 2007 @version 3.0 @brief Parser for ini files. */ /*--------------------------------------------------------------------------*/ /* $Id: iniparser.c,v 2.18 2008-01-03 18:35:39 ndevilla Exp $ $Revision: 2.18 $ $Date: 2008-01-03 18:35:39 $ */ /*---------------------------- Includes ------------------------------------*/ #include #include "iniparser.h" /*---------------------------- Defines -------------------------------------*/ #define ASCIILINESZ (1024) #define INI_INVALID_KEY ((char*)-1) /*--------------------------------------------------------------------------- Private to this module ---------------------------------------------------------------------------*/ /** * This enum stores the status for each parsed line (internal use only). */ typedef enum _line_status_ { LINE_UNPROCESSED, LINE_ERROR, LINE_EMPTY, LINE_COMMENT, LINE_SECTION, LINE_VALUE } line_status ; /*-------------------------------------------------------------------------*/ /** @brief Convert a string to lowercase. @param s String to convert. @return ptr to statically allocated string. This function returns a pointer to a statically allocated string containing a lowercased version of the input string. Do not free or modify the returned string! Since the returned string is statically allocated, it will be modified at each function call (not re-entrant). */ /*--------------------------------------------------------------------------*/ static char * strlwc(const char * s) { static char l[ASCIILINESZ+1]; int i ; if (s==NULL) return NULL ; memset(l, 0, ASCIILINESZ+1); i=0 ; while (s[i] && i l) { if (!isspace((int)*(last-1))) break ; last -- ; } *last = (char)0; return (char*)l ; } /*-------------------------------------------------------------------------*/ /** @brief Get number of sections in a dictionary @param d Dictionary to examine @return int Number of sections found in dictionary This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon. This clearly fails in the case a section name contains a colon, but this should simply be avoided. This function returns -1 in case of error. */ /*--------------------------------------------------------------------------*/ int iniparser_getnsec(dictionary * d) { int i ; int nsec ; if (d==NULL) return -1 ; nsec=0 ; for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (strchr(d->key[i], ':')==NULL) { nsec ++ ; } } return nsec ; } /*-------------------------------------------------------------------------*/ /** @brief Get name for section n in a dictionary. @param d Dictionary to examine @param n Section number (from 0 to nsec-1). @return Pointer to char string This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string! This function returns NULL in case of error. */ /*--------------------------------------------------------------------------*/ char * iniparser_getsecname(dictionary * d, int n) { int i ; int foundsec ; if (d==NULL || n<0) return NULL ; foundsec=0 ; for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (strchr(d->key[i], ':')==NULL) { foundsec++ ; if (foundsec>n) break ; } } if (foundsec<=n) { return NULL ; } return d->key[i] ; } /*-------------------------------------------------------------------------*/ /** @brief Get number of keys for section n in a dictionary. @param d Dictionary to examine @param n Section number (from 0 to nsec-1). @return Number of keys in section This function locates the n-th section in a dictionary and returns the number of keys in this section. This function returns -1 in case of error. */ /*--------------------------------------------------------------------------*/ int iniparser_getnkey(dictionary * d, int n) { int i, cnt = 0 ; if (d==NULL) return -1 ; for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (strchr(d->key[i], ':')==NULL) { if (n == -1) break; n -- ; } if (n == -1) cnt ++; } return (cnt - 1); } /*-------------------------------------------------------------------------*/ /** @brief Get key and string for key nkey in section nsec in a dictionary. @param d Dictionary to examine @param nsec Section number. @param nkey Key number. @param string Pointer where the string will be returned. @return Pointer to char string This function locates the nkey-th key in the nsec-th section in a dictionary and returns the key name and the key string as a pointer to strings statically allocated inside the dictionary. Do not free or modify the returned strings! This function returns NULL in case of error. */ /*--------------------------------------------------------------------------*/ char * iniparser_getkeyname(dictionary * d, int nsec, int nkey, char ** string) { int i, keylen; if (d==NULL) return 0 ; for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (strchr(d->key[i], ':')==NULL) { if (nsec == 0) break; nsec -- ; } } keylen = strlen(d->key[i]) + 1; i++; for (; isize ; i++) { if (d->key[i]==NULL) continue ; if (nkey == 0) break; nkey--; } *string = d->val[i]; return d->key[i] + keylen; } /*-------------------------------------------------------------------------*/ /** @brief Dump a dictionary to an opened file pointer. @param d Dictionary to dump. @param f Opened file pointer to dump to. @return void This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify @c stderr or @c stdout as output files. This function is meant for debugging purposes mostly. */ /*--------------------------------------------------------------------------*/ void iniparser_dump(dictionary * d, FILE * f) { int i ; if (d==NULL || f==NULL) return ; for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (d->val[i]!=NULL) { fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); } else { fprintf(f, "[%s]=UNDEF\n", d->key[i]); } } return ; } /*-------------------------------------------------------------------------*/ /** @brief Save a dictionary to a loadable ini file @param d Dictionary to dump @param f Opened file pointer to dump to @return void This function dumps a given dictionary into a loadable ini file. It is Ok to specify @c stderr or @c stdout as output files. */ /*--------------------------------------------------------------------------*/ void iniparser_dump_ini(dictionary * d, FILE * f) { int i, j ; char keym[ASCIILINESZ+1]; int nsec ; char * secname ; int seclen ; if (d==NULL || f==NULL) return ; nsec = iniparser_getnsec(d); if (nsec<1) { /* No section in file: dump all keys as they are */ for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; fprintf(f, "%s = %s\n", d->key[i], d->val[i]); } return ; } for (i=0 ; isize ; j++) { if (d->key[j]==NULL) continue ; if (!strncmp(d->key[j], keym, seclen+1)) { fprintf(f, "%-30s = %s\n", d->key[j]+seclen+1, d->val[j] ? d->val[j] : ""); } } } fprintf(f, "\n"); return ; } /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key @param d Dictionary to search @param key Key string to look for @param def Default value to return if key not found. @return pointer to statically allocated character string This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it. */ /*--------------------------------------------------------------------------*/ char * iniparser_getstring(dictionary * d, const char * key, char * def) { char * lc_key ; char * sval ; if (d==NULL || key==NULL) return def ; lc_key = strlwc(key); sval = dictionary_get(d, lc_key, def); return sval ; } /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to an int @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return integer This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples: "42" -> 42 "042" -> 34 (octal -> decimal) "0x42" -> 66 (hexa -> decimal) Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling. Credits: Thanks to A. Becker for suggesting strtol() */ /*--------------------------------------------------------------------------*/ int iniparser_getint(dictionary * d, const char * key, int notfound) { char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); if (str==INI_INVALID_KEY) return notfound ; return (int)strtol(str, NULL, 0); } /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a double @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return double This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. */ /*--------------------------------------------------------------------------*/ double iniparser_getdouble(dictionary * d, char * key, double notfound) { char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); if (str==INI_INVALID_KEY) return notfound ; return atof(str); } /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a boolean @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return integer This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. A true boolean is found if one of the following is matched: - A string starting with 'y' - A string starting with 'Y' - A string starting with 't' - A string starting with 'T' - A string starting with '1' A false boolean is found if one of the following is matched: - A string starting with 'n' - A string starting with 'N' - A string starting with 'f' - A string starting with 'F' - A string starting with '0' The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1. */ /*--------------------------------------------------------------------------*/ int iniparser_getboolean(dictionary * d, const char * key, int notfound) { char * c ; int ret ; c = iniparser_getstring(d, key, INI_INVALID_KEY); if (c==INI_INVALID_KEY) return notfound ; if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { ret = 1 ; } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { ret = 0 ; } else { ret = notfound ; } return ret; } /*-------------------------------------------------------------------------*/ /** @brief Finds out if a given entry exists in a dictionary @param ini Dictionary to search @param entry Name of the entry to look for @return integer 1 if entry exists, 0 otherwise Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary. */ /*--------------------------------------------------------------------------*/ int iniparser_find_entry( dictionary * ini, char * entry ) { int found=0 ; if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { found = 1 ; } return found ; } /*-------------------------------------------------------------------------*/ /** @brief Set an entry in a dictionary. @param ini Dictionary to modify. @param entry Entry to modify (entry name) @param val New value to associate to the entry. @return int 0 if Ok, -1 otherwise. If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL. */ /*--------------------------------------------------------------------------*/ int iniparser_set(dictionary * ini, char * entry, char * val) { return dictionary_set(ini, strlwc(entry), val) ; } /*-------------------------------------------------------------------------*/ /** @brief Delete an entry in a dictionary @param ini Dictionary to modify @param entry Entry to delete (entry name) @return void If the given entry can be found, it is deleted from the dictionary. */ /*--------------------------------------------------------------------------*/ void iniparser_unset(dictionary * ini, char * entry) { dictionary_unset(ini, strlwc(entry)); } /*-------------------------------------------------------------------------*/ /** @brief Load a single line from an INI file @param input_line Input line, may be concatenated multi-line input @param section Output space to store section @param key Output space to store key @param value Output space to store value @return line_status value */ /*--------------------------------------------------------------------------*/ static line_status iniparser_line( char * input_line, char * section, char * key, char * value) { line_status sta ; char line[ASCIILINESZ+1]; int len ; strcpy(line, strstrip(input_line)); len = (int)strlen(line); sta = LINE_UNPROCESSED ; if (len<1) { /* Empty line */ sta = LINE_EMPTY ; } else if (line[0]=='#' || line[0]==';') { /* Comment line */ sta = LINE_COMMENT ; } else if (line[0]=='[' && line[len-1]==']') { /* Section name */ sscanf(line, "[%[^]]", section); strcpy(section, strstrip(section)); strcpy(section, section); sta = LINE_SECTION ; } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { /* Usual key=value, with or without comments */ strcpy(key, strstrip(key)); strcpy(key, key); strcpy(value, strstrip(value)); /* * sscanf cannot handle '' or "" as empty values * this is done here */ if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { value[0]=0 ; } sta = LINE_VALUE ; } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 || sscanf(line, "%[^=] %[=]", key, value) == 2) { /* * Special cases: * key= * key=; * key=# */ strcpy(key, strstrip(key)); strcpy(key, key); value[0]=0 ; sta = LINE_VALUE ; } else { /* Generate syntax error */ sta = LINE_ERROR ; } return sta ; } /*-------------------------------------------------------------------------*/ /** @brief Parse an ini file and return an allocated dictionary object @param ininame Name of the ini file to read. @return Pointer to newly allocated dictionary This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead. The returned dictionary must be freed using iniparser_freedict(). */ /*--------------------------------------------------------------------------*/ dictionary * iniparser_load(const char * ininame) { FILE * in ; char line [ASCIILINESZ+1] ; char section [ASCIILINESZ+1] ; char key [ASCIILINESZ+1] ; char tmp [ASCIILINESZ+1] ; char val [ASCIILINESZ+1] ; int last=0 ; int len ; int lineno=0 ; int errs=0; dictionary * dict ; if ((in=fopen(ininame, "r"))==NULL) { fprintf(stderr, "iniparser: cannot open %s\n", ininame); return NULL ; } dict = dictionary_new(0) ; if (!dict) { fclose(in); return NULL ; } memset(line, 0, ASCIILINESZ); memset(section, 0, ASCIILINESZ); memset(key, 0, ASCIILINESZ); memset(val, 0, ASCIILINESZ); last=0 ; while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { lineno++ ; len = (int)strlen(line)-1; /* Safety check against buffer overflows */ if (line[len]!='\n') { fprintf(stderr, "iniparser: input line too long in %s (%d)\n", ininame, lineno); dictionary_del(dict); fclose(in); return NULL ; } /* Get rid of \n and spaces at end of line */ while ((len>=0) && ((line[len]=='\n') || (isspace(line[len])))) { line[len]=0 ; len-- ; } /* Detect multi-line */ if (line[len]=='\\') { /* Multi-line value */ last=len ; continue ; } else { last=0 ; } switch (iniparser_line(line, section, key, val)) { case LINE_EMPTY: case LINE_COMMENT: break ; case LINE_SECTION: errs = dictionary_set(dict, section, NULL); break ; case LINE_VALUE: sprintf(tmp, "%s:%s", section, key); errs = dictionary_set(dict, tmp, val) ; break ; case LINE_ERROR: fprintf(stderr, "iniparser: syntax error in %s (%d):\n", ininame, lineno); fprintf(stderr, "-> %s\n", line); errs++ ; break; default: break ; } memset(line, 0, ASCIILINESZ); last=0; if (errs<0) { fprintf(stderr, "iniparser: memory allocation failure\n"); break ; } } if (errs) { dictionary_del(dict); dict = NULL ; } fclose(in); return dict ; } /*-------------------------------------------------------------------------*/ /** @brief Free all memory associated to an ini dictionary @param d Dictionary to free @return void Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context. */ /*--------------------------------------------------------------------------*/ void iniparser_freedict(dictionary * d) { dictionary_del(d); } /* vim: set ts=4 et sw=4 tw=75 */ musepack_src_r495/mpcchap/iniparser.h0000664000000000000000000002655310775761747016640 0ustar rootroot /*-------------------------------------------------------------------------*/ /** @file iniparser.h @author N. Devillard @date Sep 2007 @version 3.0 @brief Parser for ini files. */ /*--------------------------------------------------------------------------*/ /* $Id: iniparser.h,v 1.24 2007-11-23 21:38:19 ndevilla Exp $ $Revision: 1.24 $ */ #ifndef _INIPARSER_H_ #define _INIPARSER_H_ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ #include #include #include /* * The following #include is necessary on many Unixes but not Linux. * It is not needed for Windows platforms. * Uncomment it if needed. */ /* #include */ #include "dictionary.h" /*--------------------------------------------------------------------------- Macros ---------------------------------------------------------------------------*/ /** For backwards compatibility only */ #define iniparser_getstr(d, k) iniparser_getstring(d, k, NULL) #define iniparser_setstr iniparser_setstring /*-------------------------------------------------------------------------*/ /** @brief Get number of sections in a dictionary @param d Dictionary to examine @return int Number of sections found in dictionary This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon. This clearly fails in the case a section name contains a colon, but this should simply be avoided. This function returns -1 in case of error. */ /*--------------------------------------------------------------------------*/ int iniparser_getnsec(dictionary * d); /*-------------------------------------------------------------------------*/ /** @brief Get name for section n in a dictionary. @param d Dictionary to examine @param n Section number (from 0 to nsec-1). @return Pointer to char string This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string! This function returns NULL in case of error. */ /*--------------------------------------------------------------------------*/ char * iniparser_getsecname(dictionary * d, int n); /*-------------------------------------------------------------------------*/ /** @brief Get number of keys for section n in a dictionary. @param d Dictionary to examine @param n Section number (from 0 to nsec-1). @return Number of keys in section This function locates the n-th section in a dictionary and returns the number of keys in this section. This function returns -1 in case of error. */ /*--------------------------------------------------------------------------*/ int iniparser_getnkey(dictionary * d, int nsec); /*-------------------------------------------------------------------------*/ /** @brief Get key and string for key nkey in section nsec in a dictionary. @param d Dictionary to examine @param nsec Section number. @param nkey Key number. @param string Pointer where the string will be returned. @return Pointer to char string This function locates the nkey-th key in the nsec-th section in a dictionary and returns the key name and the key string as a pointer to strings statically allocated inside the dictionary. Do not free or modify the returned strings! This function returns NULL in case of error. */ /*--------------------------------------------------------------------------*/ char * iniparser_getkeyname(dictionary * d, int nsec, int nkey, char ** string); /*-------------------------------------------------------------------------*/ /** @brief Save a dictionary to a loadable ini file @param d Dictionary to dump @param f Opened file pointer to dump to @return void This function dumps a given dictionary into a loadable ini file. It is Ok to specify @c stderr or @c stdout as output files. */ /*--------------------------------------------------------------------------*/ void iniparser_dump_ini(dictionary * d, FILE * f); /*-------------------------------------------------------------------------*/ /** @brief Dump a dictionary to an opened file pointer. @param d Dictionary to dump. @param f Opened file pointer to dump to. @return void This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify @c stderr or @c stdout as output files. This function is meant for debugging purposes mostly. */ /*--------------------------------------------------------------------------*/ void iniparser_dump(dictionary * d, FILE * f); /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key @param d Dictionary to search @param key Key string to look for @param def Default value to return if key not found. @return pointer to statically allocated character string This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it. */ /*--------------------------------------------------------------------------*/ char * iniparser_getstring(dictionary * d, const char * key, char * def); /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to an int @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return integer This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples: - "42" -> 42 - "042" -> 34 (octal -> decimal) - "0x42" -> 66 (hexa -> decimal) Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling. Credits: Thanks to A. Becker for suggesting strtol() */ /*--------------------------------------------------------------------------*/ int iniparser_getint(dictionary * d, const char * key, int notfound); /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a double @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return double This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. */ /*--------------------------------------------------------------------------*/ double iniparser_getdouble(dictionary * d, char * key, double notfound); /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a boolean @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error @return integer This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. A true boolean is found if one of the following is matched: - A string starting with 'y' - A string starting with 'Y' - A string starting with 't' - A string starting with 'T' - A string starting with '1' A false boolean is found if one of the following is matched: - A string starting with 'n' - A string starting with 'N' - A string starting with 'f' - A string starting with 'F' - A string starting with '0' The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1. */ /*--------------------------------------------------------------------------*/ int iniparser_getboolean(dictionary * d, const char * key, int notfound); /*-------------------------------------------------------------------------*/ /** @brief Set an entry in a dictionary. @param ini Dictionary to modify. @param entry Entry to modify (entry name) @param val New value to associate to the entry. @return int 0 if Ok, -1 otherwise. If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL. */ /*--------------------------------------------------------------------------*/ int iniparser_setstring(dictionary * ini, char * entry, char * val); /*-------------------------------------------------------------------------*/ /** @brief Delete an entry in a dictionary @param ini Dictionary to modify @param entry Entry to delete (entry name) @return void If the given entry can be found, it is deleted from the dictionary. */ /*--------------------------------------------------------------------------*/ void iniparser_unset(dictionary * ini, char * entry); /*-------------------------------------------------------------------------*/ /** @brief Finds out if a given entry exists in a dictionary @param ini Dictionary to search @param entry Name of the entry to look for @return integer 1 if entry exists, 0 otherwise Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary. */ /*--------------------------------------------------------------------------*/ int iniparser_find_entry(dictionary * ini, char * entry) ; /*-------------------------------------------------------------------------*/ /** @brief Parse an ini file and return an allocated dictionary object @param ininame Name of the ini file to read. @return Pointer to newly allocated dictionary This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead. The returned dictionary must be freed using iniparser_freedict(). */ /*--------------------------------------------------------------------------*/ dictionary * iniparser_load(const char * ininame); /*-------------------------------------------------------------------------*/ /** @brief Free all memory associated to an ini dictionary @param d Dictionary to free @return void Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context. */ /*--------------------------------------------------------------------------*/ void iniparser_freedict(dictionary * d); #endif musepack_src_r495/mpccut/0000775000000000000000000000000012765302354014322 5ustar rootrootmusepack_src_r495/mpccut/Makefile.am0000664000000000000000000000053411234134160016344 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif common_sources = ../common/crc32.c METASOURCES = AUTO bin_PROGRAMS = mpccut mpccut_SOURCES = mpccut.c $(common_sources) mpccut_LDADD = $(top_builddir)/libmpcenc/libmpcenc.a \ $(top_builddir)/libmpcdec/libmpcdec.la -lm musepack_src_r495/mpccut/mpccut.c0000664000000000000000000001540511614327662015767 0ustar rootroot/* Copyright (c) 2007-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "../libmpcenc/libmpcenc.h" #include "../libmpcdec/internal.h" #include "../libmpcdec/huffman.h" #include "../libmpcdec/mpc_bits_reader.h" #ifdef _MSC_VER #define atoll _atoi64 #endif #define MPCCUT_MAJOR 0 #define MPCCUT_MINOR 9 #define MPCCUT_BUILD 0 #define _cat(a,b,c) #a"."#b"."#c #define cat(a,b,c) _cat(a,b,c) #define MPCCUT_VERSION cat(MPCCUT_MAJOR,MPCCUT_MINOR,MPCCUT_BUILD) const char About [] = "mpccut - Musepack (MPC) stream cutter v" MPCCUT_VERSION " (C) 2007-2009 MDT\nBuilt " __DATE__ " " __TIME__ "\n"; static void copy_data(FILE * in_file, int in_file_pos, FILE * out_file, int data_size) { char * buff[512]; fseek(in_file, in_file_pos, SEEK_SET); while (data_size != 0) { int read_size = data_size < 512 ? data_size : 512; read_size = fread(buff, 1, read_size, in_file); data_size -= read_size; fwrite(buff, 1, read_size, out_file); } } static void usage(const char *exename) { printf("Usage: %s [-s start_sample] [-e end_sample] \n", exename); } int main(int argc, char **argv) { mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_encoder_t e; unsigned char buffer[16]; mpc_bits_reader r; mpc_block b; mpc_uint64_t size; mpc_status err; mpc_int64_t start_sample = 0, end_sample = 0; mpc_uint32_t beg_silence, start_block, block_num, i; int c; FILE * in_file; printf(About); while ((c = getopt(argc , argv, "s:e:")) != -1) { switch (c) { case 's': start_sample = atoll(optarg); break; case 'e': end_sample = atoll(optarg); break; } } if(argc - optind != 2) { usage(argv[0]); return 0; } err = mpc_reader_init_stdio(&reader, argv[optind]); if(err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if(!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); if (si.stream_version < 8) { fprintf(stderr, "this file cannot be edited, please convert it first to sv8 using mpc2sv8\n"); exit(!MPC_STATUS_OK); } if (end_sample == 0) end_sample = si.samples; else end_sample += si.beg_silence; start_sample += si.beg_silence; if (start_sample < 0 || end_sample > si.samples || end_sample <= start_sample) { fprintf(stderr, "specified samples bounds out of stream bounds\n"); exit(!MPC_STATUS_OK); } beg_silence = start_sample % (MPC_FRAME_LENGTH << si.block_pwr); start_block = start_sample / (MPC_FRAME_LENGTH << si.block_pwr); block_num = (end_sample + (MPC_FRAME_LENGTH << si.block_pwr) - 1) / (MPC_FRAME_LENGTH << si.block_pwr) - start_block; end_sample -= start_block * (MPC_FRAME_LENGTH << si.block_pwr); mpc_encoder_init(&e, end_sample, si.block_pwr, 1); e.outputFile = fopen( argv[optind + 1], "rb" ); if ( e.outputFile != 0 ) { fprintf(stderr, "Error : output file \"%s\" already exists\n", argv[optind + 1]); exit(MPC_STATUS_FAIL); } e.outputFile = fopen( argv[optind + 1], "w+b" ); e.seek_ref = 0; writeMagic(&e); writeStreamInfo( &e, si.max_band, si.ms > 0, end_sample, beg_silence, si.sample_freq, si.channels); writeBlock(&e, "SH", MPC_TRUE, 0); writeGainInfo(&e, 0, 0, 0, 0); writeBlock(&e, "RG", MPC_FALSE, 0); in_file = fopen(argv[optind], "rb"); i = si.header_position + 4; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); while( memcmp(b.key, "AP", 2) != 0 ) { if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "EI", 2) == 0) copy_data(in_file, i, e.outputFile, b.size + size); i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } e.seek_ptr = ftell(e.outputFile); writeBits (&e, 0, 16); writeBits (&e, 0, 24); // jump 40 bits for seek table pointer writeBlock(&e, "SO", MPC_FALSE, 0); // reserve space for seek offset while( start_block != 0 ){ if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "AP", 2) == 0) start_block--; i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } while( block_num != 0 ){ if ((err = mpc_check_key(b.key)) != MPC_STATUS_OK) { fprintf(stderr, "Error : invalid input stream\n"); goto error; } if (memcmp(b.key, "AP", 2) == 0) { if ((e.block_cnt & ((1 << e.seek_pwr) - 1)) == 0) { e.seek_table[e.seek_pos] = ftell(e.outputFile); e.seek_pos++; } e.block_cnt++; copy_data(in_file, i, e.outputFile, b.size + size); block_num--; } i += b.size + size; fseek(in_file, i, SEEK_SET); fread(buffer, 1, 16, in_file); r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); } writeSeekTable(&e); writeBlock(&e, "ST", MPC_FALSE, 0); // write seek table block writeBlock(&e, "SE", MPC_FALSE, 0); // write end of stream block error: fclose ( e.outputFile ); fclose ( in_file ); mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); mpc_encoder_exit(&e); if (err != MPC_STATUS_OK) remove(argv[optind + 1]); return err; } musepack_src_r495/mpccut/CMakeLists.txt0000664000000000000000000000127711433773325017072 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/include) include_directories(${libmpc_SOURCE_DIR}/libmpcdec) link_directories(${libmpc_BINARY_DIR}/libmpcdec) include_directories(${libmpc_SOURCE_DIR}/libmpcenc) link_directories(${libmpc_BINARY_DIR}/libmpcenc) if(MSVC) include_directories(${libmpc_SOURCE_DIR}/win32) add_executable(mpccut mpccut ${libmpc_SOURCE_DIR}/win32/attgetopt) endif(MSVC) add_executable(mpccut mpccut.c) if(SHARED) target_link_libraries(mpccut mpcdec) else(SHARED) target_link_libraries(mpccut mpcdec_static) endif(SHARED) target_link_libraries(mpccut mpcenc_static) if(NOT MSVC) target_link_libraries(mpccut m) endif(NOT MSVC) install(TARGETS mpccut RUNTIME DESTINATION bin) musepack_src_r495/Makefile.am0000664000000000000000000000053211234134160015047 0ustar rootrootAUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = CMakeLists.txt libmpc.kdevelop docs win32 if MPC_CHAP MPCCHAP_DIR = mpcchap endif if MPC_GAIN MPCGAIN_DIR = mpcgain endif SUBDIRS = \ include \ libmpcdec \ libmpcenc \ libmpcpsy \ libwavformat \ mpcenc \ mpc2sv8 \ mpccut \ mpcdec \ wavcmp \ $(MPCCHAP_DIR) \ $(MPCGAIN_DIR) musepack_src_r495/mpcenc/0000775000000000000000000000000012765302353014273 5ustar rootrootmusepack_src_r495/mpcenc/keyboard.c0000664000000000000000000000450310542037726016241 0ustar rootroot/* * Keyboard input functions * * (C) Frank Klemm 2002. All rights reserved. * * Principles: * * History: * ca. 1998 created * 2002 * * Global functions: * - * * TODO: * - */ #include "mpcenc.h" #if defined _WIN32 || defined __TURBOC__ # include int WaitKey ( void ) { return getch (); } int CheckKeyKeep ( void ) { int ch; if ( !kbhit () ) return -1; ch = getch (); ungetch (ch); return ch; } int CheckKey ( void ) { if ( !kbhit () ) return -1; return getch (); } #else # ifdef USE_TERMIOS # include static struct termios stored_settings; static void echo_on ( void ) { tcsetattr ( 0, TCSANOW, &stored_settings ); } static void echo_off ( void ) { struct termios new_settings; tcgetattr ( 0, &stored_settings ); new_settings = stored_settings; new_settings.c_lflag &= ~ECHO; new_settings.c_lflag &= ~ICANON; // Disable canonical mode, and set buffer size to 1 byte new_settings.c_cc[VTIME] = 0; new_settings.c_cc[VMIN] = 1; tcsetattr ( 0, TCSANOW, &new_settings ); } # else # define echo_off() (void)0 # define echo_on() (void)0 # endif int WaitKey ( void ) { unsigned char buff [1]; int ret; echo_off (); ret = read ( 0, buff, 1 ); echo_on (); return ret == 1 ? buff[0] : -1; } int CheckKeyKeep ( void ) { struct timeval tv = { 0, 0 }; // Do not wait at all, not even a microsecond fd_set read_fd; FD_ZERO ( &read_fd ); // Must be done first to initialize read_fd FD_SET ( 0, &read_fd ); // Makes select() ask if input is ready; 0 is file descriptor for stdin if ( -1 == select ( 1, // number of the largest fd to check + 1 &read_fd, NULL, // No writes NULL, // No exceptions &tv ) ) return -1; // an error occured return FD_ISSET (0, &read_fd) ? 0xFF : -1; // read_fd now holds a bit map of files that are readable. We test the entry for the standard input (file 0). } int CheckKey ( void ) { if ( CheckKeyKeep () < 0 ) return -1; return WaitKey (); } #endif /* end of keyboard.c */ musepack_src_r495/mpcenc/config.h0000664000000000000000000000223712231315357015711 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ /* Test the fast float-to-int rounding trick works */ #define HAVE_IEEE754_FLOAT #define HAVE_IEEE754_DOUBLE /* Test the presence of a 80-bit floating point type for writing AIFF headers */ #define HAVE_IEEE854_LONGDOUBLE /* parsed values from file "version" */ #define MPCENC_MAJOR 1 #define MPCENC_MINOR 30 #define MPCENC_BUILD 1 /* end of config.h */ musepack_src_r495/mpcenc/Makefile.am0000664000000000000000000000130111234134160016307 0ustar rootrootEXTRA_DIST = CMakeLists.txt if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif bin_PROGRAMS = mpcenc common_sources = ../common/crc32.c \ ../common/huffman-bcl.c \ ../common/fastmath.c \ ../common/tags.c # set the include path found by configure AM_CPPFLAGS = -I$(top_srcdir)/libmpcenc -I$(top_srcdir)/libmpcpsy \ -I$(top_srcdir)/include/ $(all_includes) \ -DTRUE=1 -DFALSE=0 # the library search path. mpcenc_LDFLAGS = $(all_libraries) mpcenc_SOURCES = keyboard.c mpcenc.c pipeopen.c stderr.c wave_in.c winmsg.c \ $(common_sources) \ mpcenc.h predict.h config.h mpcenc_LDADD = -lm \ $(EXTRALIBS) \ $(top_builddir)/libmpcpsy/libmpcpsy.a \ $(top_builddir)/libmpcenc/libmpcenc.a musepack_src_r495/mpcenc/mpcenc.c0000664000000000000000000022757012645265541015725 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ /* overflow of subband-samples */ #include #include #include #include "mpcenc.h" #include /* G L O B A L V A R I A B L E S */ float Power_L [32] [3]; float Power_R [32] [3]; /* MS-Coding */ int PredictionBands = 0; int DisplayUpdateTime = 1; int APE_Version = 2000; int LowDelay = 0; mpc_bool_t IsEndBeep = MPC_FALSE; #define MODE_OVERWRITE 0 #define MODE_NEVER_OVERWRITE 1 #define MODE_ASK_FOR_OVERWRITE 2 /* other general global variables */ unsigned int DelInput = 0; // deleting the input file after encoding unsigned int WriteMode = MODE_ASK_FOR_OVERWRITE; // overwriting a possibly existing MPC file unsigned int verbose = 0; // more information during output unsigned int NoUnicode = 1; // console is unicode or not (tag translation) unsigned int NoEncoderInfo = 0; // write encoder info block or not unsigned int NoSeekTable = 0; // write seek table block or not unsigned int FramesBlockPwr = 6; // must be even : frames_per_block = 1 << FramesBlockPwr unsigned int SeekDistance = 1; // keep a seek table entry every 2^SeekDistance block mpc_uint64_t SamplesInWAVE = 0; // number of samples per channel in the WAV file float MaxOverFlow = 0.f; // maximum overflow float ScalingFactorl = 1.f; // Scaling the input signal float ScalingFactorr = 1.f; // Scaling the input signal float FadeShape = 1.f; // Shape of the fade float FadeInTime = 0.f; // Duration of FadeIn in secs float FadeOutTime = 0.f; // Duration of FadeOut in secs float SkipTime = 0.f; // Skip the beginning of the file (sec) double Duration = 1.e+99; // Maximum encoded audio length mpc_bool_t FrontendPresent = 0; // Flag for frontend-detection #if MPCENC_MINOR % 2 == 0 #define _cat(a,b,c) #a"."#b"."#c" --stable--" #else #define _cat(a,b,c) #a"."#b"."#c" --unstable--" #endif #define cat(a,b,c) _cat(a,b,c) #define MPCENC_VERSION cat(MPCENC_MAJOR,MPCENC_MINOR,MPCENC_BUILD) const char About [] = "MPC Encoder " MPCENC_VERSION " (C) 1999-2009 Buschmann/Klemm/Piecha/MDT\nBuilt " __DATE__ " " __TIME__; #if defined _WIN32 || defined __TURBOC__ # include #else # ifdef USE_TERMIOS # include static struct termios stored_settings; static void echo_on ( void ) { tcsetattr ( 0, TCSANOW, &stored_settings ); } static void echo_off ( void ) { struct termios new_settings; tcgetattr ( 0, &stored_settings ); new_settings = stored_settings; new_settings.c_lflag &= ~ECHO; new_settings.c_lflag &= ~ICANON; /* Disable canonical mode, and set buffer size to 1 byte */ new_settings.c_cc[VTIME] = 0; new_settings.c_cc[VMIN] = 1; tcsetattr ( 0, TCSANOW, &new_settings ); } # else # define echo_off() (void)0 # define echo_on() (void)0 # endif static int getch ( void ) { unsigned char buff [1]; int ret; echo_off (); ret = READ1 ( stdin, buff ); echo_on (); return ret == 1 ? buff[0] : -1; } #endif static int waitkey ( void ) { int c; fflush (stdout); while ( (c = getch() ) <= ' ' ) ; return c; } static void longhelp ( PsyModel * m ) { stderr_printf ( "\n" "\033[1m\rUsage:\033[0m\n" " mpcenc [--options] \n" " mpcenc [--options] \n" "\n" ); stderr_printf ( "\033[1m\rInput_File must be of the following:\033[0m\n" " - stdin (only RIFF WAVE files)\n" " *.wav RIFF WAVE file\n" " *.raw/cdr Raw PCM (2ch, 16bit, 44.1kHz)\n" " *.pac/lpac LPAC file (Windows Only)\n" " *.fla/flac FLAC file\n" " *.ape Monkey's Audio file (APE extension only)\n" " *.rka/rkau RK Audio file (Windows Only)\n" " *.sz SZIP file\n" " *.shn Shorten file\n" " *.wv Wavpack File\n" " *.ofr OptimFROG file (Windows Only)\n" "\n" " Currently only 32, 37.8, 44.1 and 48 kHz, 1-8 channels, 8-32 bit linear PCM\n" " is supported. When using one of the lossless compressed formats, a proper\n" " binary must be installed within the system's $PATH.\n" "\n" "\033[1m\rOutput_File must be of the following: (or generated from Input_File)\033[0m\n" " *.mpc Musepack file\n" " *.mp+/mpp MPEGplus file (Deprecated)\n" " - stdout\n" " /dev/null trash can\n" "\n" ); stderr_printf ( "\033[1m\rProfiles and Quality Scale:\033[0m\n" " Option of using a profile (--radio) or mapped quality scale (--quality 4.0).\n" " In addition, quality scale is effective centesimally. (i.e. --quality 4.25)\n" " Available options are as follows:\n" "\n" " below telephone (--quality 0.00) poor quality (~ 20 kbps)\n" " below telephone (--quality 1.00) poor quality (~ 30 kbps)\n" " --telephone (--quality 2.00) low quality (~ 60 kbps)\n" " --thumb (--quality 3.00) low/medium quality (~ 90 kbps)\n" " --radio (--quality 4.00) medium quality (~ 130 kbps)\n" " --standard (--quality 5.00) high quality (dflt) (~ 180 kbps)\n" " (or --normal)\n" " --extreme (--quality 6.00) excellent quality (~ 210 kbps)\n" " (or --xtreme)\n" " --insane (--quality 7.00) excellent quality (~ 240 kbps)\n" " --braindead (--quality 8.00) excellent quality (~ 270 kbps)\n" " above braindead (--quality 9.00) excellent quality (~ 300 kbps)\n" " above braindead (--quality 10.00) excellent quality (~ 350 kbps)\n" "\n" ); stderr_printf ( "\033[1m\rBitstream formating:\033[0m\n" " --no_ei do not write encoder information packet (dflt: off)\n" " --no_st do not write the seek table (dflt: off)\n" " --num_frames x x = 0..7 number of frames in packet = 4^x (dflt: 3)\n" " --seek_distance x x = 0..15 keep a seek table entry every 2^x audio packet (dflt: 1)\n" "\n" ); stderr_printf ( "\033[1m\rFile/Message handling:\033[0m\n" " --silent repress console messages (dflt: off)\n" " --verbose increase verbosity (dflt: off)\n" " --longhelp print this help text\n" " --stderr foo append messages to file 'foo'\n" " --neveroverwrite never overwrite existing Output_File (dflt: off)\n" " --interactive ask to overwrite an existing Output_File (dflt: on)\n" " --overwrite overwrite existing Output_File (dflt: off)\n" " --deleteinput delete Input_File after encoding (dflt: off)\n" " --beep beep when encoding is finished (dflt: off)\n" "\n" ); stderr_printf ( "\033[1m\rTagging (uses APE 2.0 tags):\033[0m\n" " --tag key=value Add tag \"key\" with \"value\" as contents\n" " --tagfile key=f dto., take value from a file 'f'\n" " --tagfile key dto., take value from console\n" " --artist 'value' shortcut for --tag 'Artist=value'\n" " --album 'value' shortcut for --tag 'Album=value'\n" " other possible keys are: debutalbum, publisher, conductor,\n" " title, subtitle, track, comment, composer, copyright,\n" " publicationright, filename, recordlocation, recorddate,\n" " ean/upc, year, releasedate, genre, media, index, isrc,\n" " abstract, bibliography, introplay, media, language, ...\n" " --unicode Toggle unicode input from console on/off if autodetection\n" " doesn't work. This switch MUST be before any tag switch.\n" "\n" ); stderr_printf ( "\033[1m\rAudio processing:\033[0m\n" ); stderr_printf ( " --skip x skip the first x seconds (dflt: %3.1f)\n", SkipTime ); stderr_printf ( " --dur x stop encoding after at most x seconds of encoded audio\n" ); stderr_printf ( " --fade x fadein+out in seconds\n" ); stderr_printf ( " --fadein x fadein in seconds (dflt: %3.1f)\n", FadeInTime ); stderr_printf ( " --fadeout x fadeout in seconds (dflt: %3.1f)\n", FadeOutTime ); stderr_printf ( " --fadeshape x fade shape (dflt: %3.1f),\n" " see http://www.uni-jena.de/~pfk/mpc/img/fade.png\n", FadeShape ); stderr_printf ( " --scale x scale input signal by x (dflt: %7.5f)\n", ScalingFactorl ); stderr_printf ( " --scale x,y scale input signal, separate for each channel\n" ); stderr_printf ( "\n" ); stderr_printf ( "\033[1m\rExpert settings:\033[0m\n" ); stderr_printf ( "==Masking thresholds======\n" ); stderr_printf ( " --quality x set Quality to x (dflt: 5)\n" ); stderr_printf ( " --nmt x set NMT value to x dB (dflt: %4.1f)\n", m->NMT ); stderr_printf ( " --tmn x set TMN value to x dB (dflt: %4.1f)\n", m->TMN ); stderr_printf ( " --pns x set PNS value to x dB (dflt: %4.1f)\n", m->PNS ); stderr_printf ( "==ATH/Bandwidth settings==\n" ); stderr_printf ( " --bw x maximum bandwidth in Hz (dflt: %4.1f kHz)\n", (m->Max_Band+1)*(m->SampleFreq/32000.) ); stderr_printf ( " --minSMR x minimum SMR of x dB over encoded bandwidth (dflt: %2.1f)\n", m->minSMR ); stderr_printf ( " --ltq xyy x=0: ISO threshold in quiet (not recommended)\n" " x=1: more sensitive threshold in quiet (Buschmann)\n" " x=2: even more sensitive threshold in quiet (Filburt)\n" " x=3: Klemm\n" " x=4: Buschmann-Klemm Mix\n" " x=5: minimum of Klemm and Buschmann (dflt)\n" " y=00...99: HF roll-off (00:+30 dB, 99:-30 dB @20 kHz\n" ); stderr_printf ( " --ltq_gain x add offset of x dB to chosen ltq (dflt: %+4.1f)\n", m->Ltq_offset ); stderr_printf ( " --ltq_max x maximum level for ltq (dflt: %4.1f dB)\n", m->Ltq_max ); stderr_printf ( " --ltq_var x adaptive threshold in quiet: 0: off, >0: on (dflt: %g)\n", m->varLtq ); stderr_printf ( " --tmpMask x exploit postmasking: 0: off, 1: on (dflt: %i)\n", m->tmpMask_used ); stderr_printf ( "==Other settings==========\n" ); stderr_printf ( " --ms x Mid/Side Stereo, 0: off, 1: reduced, 2: on, 3: decoupled,\n" " 10: enhanced 1.5/3 dB, 11: 2/6 dB, 12: 2.5/9 dB,\n" " 13: 3/12 dB, 15: 3/oo dB (dflt: %i)\n", m->MS_Channelmode ); stderr_printf ( " --ans x Adaptive Noise Shaping Order: 0: off, 1...6: on (dflt: %i)\n", m->NS_Order ); stderr_printf ( " --cvd x ClearVoiceDetection, 0: off, 1: on, 2: dual (dflt: %i)\n", m->CVD_used ); stderr_printf ( " --shortthr x short FFT threshold (dflt: %4.1f)\n", m->ShortThr ); stderr_printf ( " --transdet x slewrate for transient detection (dflt: %3.1f)\n", m->TransDetect ); stderr_printf ( " --minval x calculation of MinVal (1:Buschmann, 2,3:Klemm)\n" ); stderr_printf ( "\n" ); stderr_printf ( "\033[1m\rExamples:\033[0m\n" " mpcenc inputfile.wav\n" " mpcenc inputfile.wav outputfile.mpc\n" " mpcenc --radio inputfile.wav outputfile.mpc\n" " mpcenc --silent --radio --pns 0.25 inputfile.wav outputfile.mpc\n" " mpcenc --nmt 12 --tmn 28 inputfile.wav outputfile.mpc\n" "\n"); } static void shorthelp ( void ) { stderr_printf ( "\n" "\033[1m\rUsage:\033[0m\n" " mpcenc [--options] \n" " mpcenc [--options] \n" "\n" "\033[1m\rStandard options:\033[0m\n" " --silent repress console messages (dflt: off)\n" " --verbose increase verbosity (dflt: off)\n" " --deleteinput delete Input_File after encoding (dflt: off)\n" " --overwrite overwrite existing Output_File (dflt: off)\n" " --fade sec fade in and out with 'sec' duration (dflt: 0.0)\n" "\n" "\033[1m\rProfiles and Quality Scale:\033[0m\n" " --thumb (--quality 3.00) low/medium quality (~ 90 kbps)\n" " --radio (--quality 4.00) medium quality (~ 130 kbps)\n" " --standard (--quality 5.00) high quality (dflt) (~ 180 kbps)\n" " --extreme (--quality 6.00) excellent quality (~ 210 kbps)\n" " --insane (--quality 7.00) excellent quality (~ 240 kbps)\n" "\n" "\033[1m\rExamples:\033[0m\n" " mpcenc inputfile.wav\n" " mpcenc inputfile.wav outputfile.mpc\n" " mpcenc --insane inputfile.wav outputfile.mpc\n" " mpcenc --silent --radio inputfile.wav outputfile.mpc\n" "\n" "For further information use the --longhelp option.\n" ); } /* * Wishes for fading: * * _____________________ * /| |\ * / | | \ * / | | \ * ____/ | | \______________ * | | | | | | * |t1| t2 | | t4 |t5| * | t3 | * |<-------------- M P C ------------->| * |<-------------------- W A V E ------------------>| * * t1: StartTime (Standard: 0, positive: from beginning of file, negative: from end of file) * t2: FadeInTime (Standard: 0, positive: Fadetime) * t3: EndTime (Standard: 0, non-positive: from end of file, positive: from beginning of file) * t4: FadeOutTime (Standard: 0, positive: Fadetime) * t5: PostGapTime (Standard: 0, positive: additional silence) * * The beginning of phase t4 can also be triggered by the signal SIGINT. * With SIGTERM, the current frame is fully decoded and then terminated. * * Another question is if you can't put t1 before the zero, same with t3 and t5 * (track-spanning cutting). */ float bump_exp = 1.f; float bump_start = 0.040790618517f; static void setbump ( double e ) { bump_exp = e; bump_start = 1 - sqrt (1 - 1 / (1 - log(1.e-5) / e)); } static double bump ( double x ) { x = bump_start + x * (1. - bump_start); if ( x <= 0.) return 0.; if ( x >= 1.) return 1.; x *= (2. - x); x = (x - 1.) / x; return exp (x * bump_exp); } static void Fading_In ( PCMDataTyp* data, unsigned int N, const float fs ) { float inv_fs = 1.f / fs; float fadein_pos; float scale; int n; int idx; for ( n = 0; n < BLOCK; n++, N++ ) { idx = n + CENTER; fadein_pos = N * inv_fs; scale = fadein_pos / FadeInTime; scale = bump (scale); data->L[idx] *= scale; data->R[idx] *= scale; data->M[idx] *= scale; data->S[idx] *= scale; } } static void Fading_Out ( PCMDataTyp* data, unsigned int N, const float fs ) { float inv_fs = 1.f / fs; float fadeout_pos; float scale; int n; int idx; for ( n = 0; n < BLOCK; n++, N++ ) { idx = n + CENTER; fadeout_pos = (long double)(SamplesInWAVE - N) * inv_fs; scale = fadeout_pos / FadeOutTime; scale = bump (scale); data->L[idx] *= scale; data->R[idx] *= scale; data->M[idx] *= scale; data->S[idx] *= scale; } } static const unsigned char Penalty [256] = { 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 2, 5, 9, 15, 23, 36, 54, 79,116,169,246,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, }; #define P(new,old) Penalty [128 + (old) - (new)] static void SCF_Extraktion ( PsyModel*m, mpc_encoder_t* e, const int MaxBand, SubbandFloatTyp* x ) { int Band; int n; int d01; int d12; int d02; int warnL; int warnR; int* scfL; int* scfR; int comp_L [3]; int comp_R [3]; float tmp_L [3]; float tmp_R [3]; float facL; float facR; float L; float R; float SL; float SR; for ( Band = 0; Band <= MaxBand; Band++ ) { // Suche nach Maxima L = FABS (x[Band].L[ 0]); R = FABS (x[Band].R[ 0]); SL = x[Band].L[ 0] * x[Band].L[ 0]; SR = x[Band].R[ 0] * x[Band].R[ 0]; for ( n = 1; n < 12; n++ ) { if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]); if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]); SL += x[Band].L[n] * x[Band].L[n]; SR += x[Band].R[n] * x[Band].R[n]; } Power_L [Band][0] = SL; Power_R [Band][0] = SR; tmp_L [0] = L; tmp_R [0] = R; L = FABS (x[Band].L[12]); R = FABS (x[Band].R[12]); SL = x[Band].L[12] * x[Band].L[12]; SR = x[Band].R[12] * x[Band].R[12]; for ( n = 13; n < 24; n++ ) { if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]); if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]); SL += x[Band].L[n] * x[Band].L[n]; SR += x[Band].R[n] * x[Band].R[n]; } Power_L [Band][1] = SL; Power_R [Band][1] = SR; tmp_L [1] = L; tmp_R [1] = R; L = FABS (x[Band].L[24]); R = FABS (x[Band].R[24]); SL = x[Band].L[24] * x[Band].L[24]; SR = x[Band].R[24] * x[Band].R[24]; for ( n = 25; n < 36; n++ ) { if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]); if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]); SL += x[Band].L[n] * x[Band].L[n]; SR += x[Band].R[n] * x[Band].R[n]; } Power_L [Band][2] = SL; Power_R [Band][2] = SR; tmp_L [2] = L; tmp_R [2] = R; // calculation of the scalefactor-indexes // -12.6f*log10(x)+57.8945021823f = -10*log10(x/32767)*1.26+1 // normalize maximum of +/- 32767 to prevent quantizer overflow // It can stand a maximum of +/- 32768 ... // Where is scf{R,L} [0...2] initialized ??? scfL = e->SCF_Index_L [Band]; scfR = e->SCF_Index_R [Band]; if (tmp_L [0] > 0.) scfL [0] = IFLOORF (-12.6f * LOG10 (tmp_L [0]) + 57.8945021823f ); if (tmp_L [1] > 0.) scfL [1] = IFLOORF (-12.6f * LOG10 (tmp_L [1]) + 57.8945021823f ); if (tmp_L [2] > 0.) scfL [2] = IFLOORF (-12.6f * LOG10 (tmp_L [2]) + 57.8945021823f ); if (tmp_R [0] > 0.) scfR [0] = IFLOORF (-12.6f * LOG10 (tmp_R [0]) + 57.8945021823f ); if (tmp_R [1] > 0.) scfR [1] = IFLOORF (-12.6f * LOG10 (tmp_R [1]) + 57.8945021823f ); if (tmp_R [2] > 0.) scfR [2] = IFLOORF (-12.6f * LOG10 (tmp_R [2]) + 57.8945021823f ); // restriction to SCF_Index = -6...121, make note of the internal overflow warnL = warnR = 0; for( n = 0; n < 3; n++){ if (scfL[n] < -6) scfL[n] = -6, warnL = 1; if (scfL[n] > 121) scfL[n] = 121, warnL = 1; if (scfR[n] < -6) scfR[n] = -6, warnR = 1; if (scfR[n] > 121) scfR[n] = 121, warnR = 1; } // save old values for compensation calculation comp_L[0] = scfL[0]; comp_L[1] = scfL[1]; comp_L[2] = scfL[2]; comp_R[0] = scfR[0]; comp_R[1] = scfR[1]; comp_R[2] = scfR[2]; // determination and replacement of scalefactors of minor differences with the smaller one??? // a smaller one is quantized more roughly, i.e. the noise gets amplified??? if ( m->CombPenalities >= 0 ) { if ( P(scfL[0],scfL[1]) + P(scfL[0],scfL[2]) <= m->CombPenalities ) scfL[2] = scfL[1] = scfL[0]; else if ( P(scfL[1],scfL[0]) + P(scfL[1],scfL[2]) <= m->CombPenalities ) scfL[0] = scfL[2] = scfL[1]; else if ( P(scfL[2],scfL[0]) + P(scfL[2],scfL[1]) <= m->CombPenalities ) scfL[0] = scfL[1] = scfL[2]; else if ( P(scfL[0],scfL[1]) <= m->CombPenalities ) scfL[1] = scfL[0]; else if ( P(scfL[1],scfL[0]) <= m->CombPenalities ) scfL[0] = scfL[1]; else if ( P(scfL[1],scfL[2]) <= m->CombPenalities ) scfL[2] = scfL[1]; else if ( P(scfL[2],scfL[1]) <= m->CombPenalities ) scfL[1] = scfL[2]; if ( P(scfR[0],scfR[1]) + P(scfR[0],scfR[2]) <= m->CombPenalities ) scfR[2] = scfR[1] = scfR[0]; else if ( P(scfR[1],scfR[0]) + P(scfR[1],scfR[2]) <= m->CombPenalities ) scfR[0] = scfR[2] = scfR[1]; else if ( P(scfR[2],scfR[0]) + P(scfR[2],scfR[1]) <= m->CombPenalities ) scfR[0] = scfR[1] = scfR[2]; else if ( P(scfR[0],scfR[1]) <= m->CombPenalities ) scfR[1] = scfR[0]; else if ( P(scfR[1],scfR[0]) <= m->CombPenalities ) scfR[0] = scfR[1]; else if ( P(scfR[1],scfR[2]) <= m->CombPenalities ) scfR[2] = scfR[1]; else if ( P(scfR[2],scfR[1]) <= m->CombPenalities ) scfR[1] = scfR[2]; } else { d12 = scfL [2] - scfL [1]; d01 = scfL [1] - scfL [0]; d02 = scfL [2] - scfL [0]; if ( 0 < d12 && d12 < 5 ) scfL [2] = scfL [1]; else if (-3 < d12 && d12 < 0 ) scfL [1] = scfL [2]; else if ( 0 < d01 && d01 < 5 ) scfL [1] = scfL [0]; else if (-3 < d01 && d01 < 0 ) scfL [0] = scfL [1]; else if ( 0 < d02 && d02 < 4 ) scfL [2] = scfL [0]; else if (-2 < d02 && d02 < 0 ) scfL [0] = scfL [2]; d12 = scfR [2] - scfR [1]; d01 = scfR [1] - scfR [0]; d02 = scfR [2] - scfR [0]; if ( 0 < d12 && d12 < 5 ) scfR [2] = scfR [1]; else if (-3 < d12 && d12 < 0 ) scfR [1] = scfR [2]; else if ( 0 < d01 && d01 < 5 ) scfR [1] = scfR [0]; else if (-3 < d01 && d01 < 0 ) scfR [0] = scfR [1]; else if ( 0 < d02 && d02 < 4 ) scfR [2] = scfR [0]; else if (-2 < d02 && d02 < 0 ) scfR [0] = scfR [2]; } // calculate SNR-compensation tmp_L [0] = invSCF [comp_L[0] - scfL[0]]; tmp_L [1] = invSCF [comp_L[1] - scfL[1]]; tmp_L [2] = invSCF [comp_L[2] - scfL[2]]; tmp_R [0] = invSCF [comp_R[0] - scfR[0]]; tmp_R [1] = invSCF [comp_R[1] - scfR[1]]; tmp_R [2] = invSCF [comp_R[2] - scfR[2]]; m->SNR_comp_L [Band] = (tmp_L[0]*tmp_L[0] + tmp_L[1]*tmp_L[1] + tmp_L[2]*tmp_L[2]) * 0.3333333333f; m->SNR_comp_R [Band] = (tmp_R[0]*tmp_R[0] + tmp_R[1]*tmp_R[1] + tmp_R[2]*tmp_R[2]) * 0.3333333333f; // normalize the subband samples facL = invSCF[scfL[0]]; facR = invSCF[scfR[0]]; for ( n = 0; n < 12; n++ ) { x[Band].L[n] *= facL; x[Band].R[n] *= facR; } facL = invSCF[scfL[1]]; facR = invSCF[scfR[1]]; for ( n = 12; n < 24; n++ ) { x[Band].L[n] *= facL; x[Band].R[n] *= facR; } facL = invSCF[scfL[2]]; facR = invSCF[scfR[2]]; for ( n = 24; n < 36; n++ ) { x[Band].L[n] *= facL; x[Band].R[n] *= facR; } // limit to +/-32767 if internal clipping if ( warnL ) for ( n = 0; n < 36; n++ ) { if (x[Band].L[n] > +32767.f) { e->Overflows++; MaxOverFlow = maxf (MaxOverFlow, x[Band].L[n]); x[Band].L[n] = 32767.f; } else if (x[Band].L[n] < -32767.f) { e->Overflows++; MaxOverFlow = maxf (MaxOverFlow, -x[Band].L[n]); x[Band].L[n] = -32767.f; } } if ( warnR ) for ( n = 0; n < 36; n++ ) { if (x[Band].R[n] > +32767.f) { e->Overflows++; MaxOverFlow = maxf (MaxOverFlow, x[Band].R[n]); x[Band].R[n] = 32767.f; } else if (x[Band].R[n] < -32767.f) { e->Overflows++; MaxOverFlow = maxf (MaxOverFlow, -x[Band].R[n]); x[Band].R[n] = -32767.f; } } } return; } static void Quantisierung ( PsyModel * m, const int MaxBand, const int* resL, const int* resR, const SubbandFloatTyp* subx, mpc_quantizer* subq ) { static float errorL [32] [36 + MAX_NS_ORDER]; static float errorR [32] [36 + MAX_NS_ORDER]; int Band; // quantize Subband- and Subframe-samples for ( Band = 0; Band <= MaxBand; Band++, resL++, resR++ ) { if ( *resL > 0 ) { if ( m->NS_Order_L [Band] > 0 ) { QuantizeSubbandWithNoiseShaping ( subq[Band].L, subx[Band].L, *resL, errorL [Band], m->FIR_L [Band] ); memcpy ( errorL [Band], errorL[Band] + 36, MAX_NS_ORDER * sizeof (**errorL) ); } else { QuantizeSubband ( subq[Band].L, subx[Band].L, *resL, errorL [Band], MAX_NS_ORDER ); memcpy ( errorL [Band], errorL[Band] + 36, MAX_NS_ORDER * sizeof (**errorL) ); } } if ( *resR > 0 ) { if ( m->NS_Order_R [Band] > 0 ) { QuantizeSubbandWithNoiseShaping ( subq[Band].R, subx[Band].R, *resR, errorR [Band], m->FIR_R [Band] ); memcpy ( errorR [Band], errorR [Band] + 36, MAX_NS_ORDER * sizeof (**errorL) ); } else { QuantizeSubband ( subq[Band].R, subx[Band].R, *resR, errorL [Band], MAX_NS_ORDER); memcpy ( errorR [Band], errorR [Band] + 36, MAX_NS_ORDER * sizeof (**errorL) ); } } } return; } static int PNS_SCF ( int* scf, float S0, float S1, float S2 ) { // printf ("%7.1f %7.1f %7.1f ", sqrt(S0/12), sqrt(S1/12), sqrt(S2/12) ); #if 1 if ( S0 < 0.5 * S1 || S1 < 0.5 * S2 || S0 < 0.5 * S2 ) return 0; if ( S1 < 0.25 * S0 || S2 < 0.25 * S1 || S2 < 0.25 * S0 ) return 0; #endif if ( S0 >= 0.8 * S1 ) { if ( S0 >= 0.8 * S2 && S1 > 0.8 * S2 ) S0 = S1 = S2 = 0.33333333333f * (S0 + S1 + S2); else S0 = S1 = 0.5f * (S0 + S1); } else { if ( S1 >= 0.8 * S2 ) S1 = S2 = 0.5f * (S1 + S2); } scf [0] = scf [1] = scf [2] = 63; S0 = sqrt (S0/12 * 4/1.2005080577484075047860806747022); S1 = sqrt (S1/12 * 4/1.2005080577484075047860806747022); S2 = sqrt (S2/12 * 4/1.2005080577484075047860806747022); if (S0 > 0.) scf [0] = IFLOORF (-12.6f * LOG10 (S0) + 57.8945021823f ); if (S1 > 0.) scf [1] = IFLOORF (-12.6f * LOG10 (S1) + 57.8945021823f ); if (S2 > 0.) scf [2] = IFLOORF (-12.6f * LOG10 (S2) + 57.8945021823f ); if ( scf[0] & ~63 ) scf[0] = scf[0] > 63 ? 63 : 0; if ( scf[1] & ~63 ) scf[1] = scf[1] > 63 ? 63 : 0; if ( scf[2] & ~63 ) scf[2] = scf[2] > 63 ? 63 : 0; return 1; } static void Allocate ( const int MaxBand, int* res, float* x, int* scf, const float* comp, const float* smr, const SCFTriple* Pow, const int* Transient, const float PNS ) { int Band; int k; float tmpMNR; // to adjust the scalefactors float save [36]; // to adjust the scalefactors float MNR; // Mask-to-Noise ratio for ( Band = 0; Band <= MaxBand; Band++, res++, comp++, smr++, scf += 3, x += 72 ) { // printf ( "%2u: %u\n", Band, Transient[Band] ); // Find out needed quantization resolution Res to fulfill the calculated MNR // This is done by exactly measuring the quantization residuals against the signal itself // Starting with Res=1 Res in increased until MNR becomes less than 1. if ( Band > 0 && res[-1] < 3 && *smr >= 1. && *smr < Band * PNS && PNS_SCF ( scf, Pow [Band][0], Pow [Band][1], Pow [Band][2] ) ) { *res = -1; } else { for ( MNR = *smr * 1.; MNR > 1. && *res != 15; ) MNR = *smr * (Transient[Band] ? ISNR_Schaetzer_Trans : ISNR_Schaetzer) ( x, *comp, ++*res ); } // Fine adapt SCF's (MNR > 0 prevents adaption of zero samples, which is nonsense) // only apply to Huffman-coded samples (otherwise no savings in bitrate) if ( *res > 0 && *res <= LAST_HUFFMAN && MNR < 1. && MNR > 0. && !Transient[Band] ) { while ( scf[0] > 0 && scf[1] > 0 && scf[2] > 0 ) { --scf[2]; --scf[1]; --scf[0]; // adapt scalefactors and samples memcpy ( save, x, sizeof save ); for (k = 0; k < 36; k++ ) x[k] *= SCFfac; tmpMNR = *smr * (Transient[Band] ? ISNR_Schaetzer_Trans : ISNR_Schaetzer) ( x, *comp, *res );// recalculate MNR // FK: if ( tmpMNR > MNR && tmpMNR <= 1 ) { // check for MNR if ( tmpMNR <= 1 ) { // check for MNR MNR = tmpMNR; } else { ++scf[0]; ++scf[1]; ++scf[2]; // restore scalefactors and samples memcpy ( x, save, sizeof save ); break; } } } } return; } /* Planned: return the evaluated options, without InputFile and OutputFile, argc implicit instead of explicit */ static int EvalParameters (PsyModel * m, int argc, char** argv, char** InputFile, char** OutputFile, int onlyfilenames ) { int k; size_t len; static char output [2048]; static char errmsg [] = "\n\033[33;41;1mERROR\033[0m: Missing argument for option '--%s'\n\n"; FILE* fp; char* p; char buff [32768]; /********************************* In / Out Files *********************************/ *InputFile = argv [argc-1]; *OutputFile = NULL; // search for output file if ( argc >= 3 ) { len = strlen (argv[argc-1]); if ( strcmp (argv[argc-1], "/dev/null") == 0 || strcmp (argv[argc-1], "-") == 0 || (len >= 4 && (0 == strcasecmp (argv [argc-1] + len - 4, ".MPC") || 0 == strcasecmp (argv [argc-1] + len - 4, ".MPP") || 0 == strcasecmp (argv [argc-1] + len - 4, ".MP+"))) ) { *OutputFile = argv[argc-1]; *InputFile = argv[argc-2]; argc -= 2; } } // if no Output-File is stated, set OutFile to InFile.mpc if ( *OutputFile == NULL ) { char * ext = strrchr(*InputFile, '.'); // search for extension delimiter strcpy ( *OutputFile = output, *InputFile ); len = strlen ( output ); if (ext != 0 && (len - (ext - *InputFile)) < 7) // extension max size (5 chars) len = ext - *InputFile; strcpy (output+len, ".mpc"); argc -= 1; } if ( onlyfilenames ) return 0; /********************************* In / Out Files *********************************/ // search for options for ( k = 1; k < argc; k++ ) { const char* arg = argv [k]; if ( arg[0] != '-' || arg[1] != '-' ) continue; arg += 2; if ( 0 == strcmp ( arg, "verbose" ) ) { // verbose verbose++; } else if ( 0 == strcmp ( arg, "telephone" ) ) { // MainQual SetQualityParams (m, 2.0); } else if ( 0 == strcmp ( arg, "thumb" ) ) { // MainQual SetQualityParams (m, 3.0); } else if ( 0 == strcmp ( arg, "radio" ) ) { SetQualityParams (m, 4.0); } else if ( 0 == strcmp ( arg, "standard") || 0 == strcmp ( arg, "normal") ) { SetQualityParams (m, 5.0); } else if ( 0 == strcmp ( arg, "xtreme") || 0 == strcmp ( arg, "extreme") ) { SetQualityParams (m, 6.0); } else if ( 0 == strcmp ( arg, "insane") ) { SetQualityParams (m, 7.0); } else if ( 0 == strcmp ( arg, "braindead") ) { SetQualityParams (m, 8.0); } else if ( 0 == strcmp ( arg, "quality") ) { // Quality if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } SetQualityParams (m, atof (argv[k]) ); } else if ( 0 == strcmp ( arg, "neveroverwrite") ) { // NeverOverWrite WriteMode = MODE_NEVER_OVERWRITE; } else if ( 0 == strcmp ( arg, "forcewrite") || 0 == strcmp ( arg, "overwrite") ) { // ForceWrite WriteMode = MODE_OVERWRITE; } else if ( 0 == strcmp ( arg, "interactive") ) { // Interactive WriteMode = MODE_ASK_FOR_OVERWRITE; } else if ( 0 == strcmp ( arg, "delinput") || 0 == strcmp ( arg, "delete") || 0 == strcmp ( arg, "deleteinput" ) ) { // DelInput DelInput = 0xAFFEDEAD; } else if ( 0 == strcmp ( arg, "beep") ) { IsEndBeep = MPC_TRUE; } else if ( 0 == strcmp ( arg, "scale") ) { // ScalingFactor if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } ScalingFactorl = ScalingFactorr = (float) atof (argv[k]); if (strchr (argv[k], ',')) ScalingFactorr = (float) atof (strchr (argv[k], ',') + 1); if ( ScalingFactorl == 0.97f || ScalingFactorl == 0.98f ) stderr_printf ("--scale 0.97 or --scale 0.98 is nearly useless to prevent clipping. Use replaygain tool\nto determine EXACT attenuation to avoid clipping. Factor can be between 0.696 and 1.000.\nSee \"http://www.uni-jena.de/~pfk/mpp/clipexample.html\".\n\n" ); } else if ( 0 == strcmp ( arg, "kbd") ) { // ScalingFactor if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } if ( 2 != sscanf ( argv[k], "%f,%f", &(m->KBD1), &(m->KBD2) )) { stderr_printf ( "%s: missing two arguments", arg ); return -1; } Init_FFT (m); } else if ( 0 == strcmp ( arg, "fadein") ) { // FadeInTime if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } FadeInTime = (float) atof (argv[k]); if ( FadeInTime < 0.f ) FadeInTime = 0.f; } else if ( 0 == strcmp ( arg, "fadeout") ) { // FadeOutTime if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } FadeOutTime = (float) atof (argv[k]); if ( FadeOutTime < 0.f ) FadeOutTime = 0.f; } else if ( 0 == strcmp ( arg, "fade") ) { // FadeInTime + FadeOutTime if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } FadeOutTime = (float) atof (argv[k]); if ( FadeOutTime < 0.f ) FadeOutTime = 0.f; FadeInTime = FadeOutTime; } else if ( 0 == strcmp ( arg, "fadeshape") ) { // FadeOutTime if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } FadeShape = (float) atof (argv[k]); if ( FadeShape < 0.001f || FadeShape > 1000.f ) FadeShape = 1.f; setbump ( FadeShape ); } else if ( 0 == strcmp ( arg, "skip") || 0 == strcmp ( arg, "start") ) { // SkipTime if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } SkipTime = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "dur") || 0 == strcmp ( arg, "duration") ) { // maximum Duration if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } Duration = atof (argv[k]); } else if ( 0 == strcmp ( arg, "ans") ) { // AdaptiveNoiseShaping if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->NS_Order = atoi (argv[k]); m->NS_Order = mini ( m->NS_Order, MAX_NS_ORDER ); } else if ( 0 == strcmp ( arg, "predict") ) { // AdaptiveNoiseShaping if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } PredictionBands = atoi (argv[k]); PredictionBands = mini ( PredictionBands, 32 ); } else if ( 0 == strcmp ( arg, "ltq_var") || 0 == strcmp ( arg, "ath_var") ) { // ltq_var if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->varLtq = atof (argv[k]); } else if ( 0 == strcmp ( arg, "pns") ) { // pns if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->PNS = atof (argv[k]); } else if ( 0 == strcmp ( arg, "minval") ) { // MinValChoice if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->MinValChoice = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "transdet") ) { // TransDetect if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->TransDetect = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "shortthr") ) { // ShortThr if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->ShortThr = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "xlevel") || 0 == strcmp ( arg, "noxlevel") ) { stderr_printf ( "\nXlevel coding not needed anymore, --%s ignored.\n", arg ); } else if ( 0 == strcmp ( arg, "nmt") ) { // NMT if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->NMT = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "tmn") ) { // TMN if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->TMN = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "cvd") ) { // ClearVoiceDetection if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->CVD_used = atoi (argv[k]); if ( m->CVD_used == 0 ) stderr_printf ( "\nDisabling CVD always reduces quality!\a\n" ); } else if ( 0 == strcmp ( arg, "ms") ) { // Mid/Side Stereo if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->MS_Channelmode = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "minSMR") ) { // minimum SMR if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } if ( m->minSMR > (float) atof (argv[k]) ) stderr_printf ( "This option usage may reduces quality!\a\n" ); m->minSMR = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "tmpMask") ) { // temporal post-masking if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->tmpMask_used = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "ltq_max") || 0 == strcmp ( arg, "ath_max") ) { // Maximum for threshold in quiet if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->Ltq_max = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "ltq_gain") || 0 == strcmp ( arg, "ath_gain") ) {// Offset for threshold in quiet if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->Ltq_offset = (float) atof (argv[k]); } else if ( 0 == strcmp ( arg, "silent") || 0 == strcmp ( arg, "quiet") ) { SetStderrSilent (1); } else if ( 0 == strcmp ( arg, "stderr") ) { // Offset for threshold in quiet if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } if ( 0 == freopen ( argv[k], "a", stderr ) ) { stderr_printf ("invalid stderr filename"); return -1; } } else if ( 0 == strcmp ( arg, "ltq") || 0 == strcmp ( arg, "ath") ) { // threshold in quiet if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->EarModelFlag = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "noco") ) { NoiseInjectionComp (); } else if ( 0 == strcmp ( arg, "newcomb") ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->CombPenalities = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "ape1") ) { // Mark APE as APE 1.000 APE_Version = 1000; } else if ( 0 == strcmp ( arg, "ape2") ) { // Mark APE as APE 2.000 APE_Version = 2000; } else if ( 0 == strcmp ( arg, "unicode") ) { // no tag conversion NoUnicode = 1 - NoUnicode; } else if ( 0 == strcmp ( arg, "no_ei") ) { // no encoder info block NoEncoderInfo = 1; } else if ( 0 == strcmp ( arg, "no_st") ) { // no seek table NoSeekTable = 1; } else if ( 0 == strcmp ( arg, "num_frames") ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } FramesBlockPwr = atoi (argv[k]) * 2; } else if ( 0 == strcmp ( arg, "seek_distance") ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } SeekDistance = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "lowdelay") ) { LowDelay = 1; } else if ( 0 == strcmp ( arg, "bw") || 0 == strcmp ( arg, "lowpass") ) { // bandwidth if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } m->BandWidth = atof (argv[k]); } else if ( 0 == strcmp ( arg, "displayupdatetime") ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } DisplayUpdateTime = atoi (argv[k]); } else if ( 0 == strcmp ( arg, "artist" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Artist", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "album" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Album", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "debutalbum" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Debut Album", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "publisher" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Publisher", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "conductor" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Conductor", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "title" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Title", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "subtitle" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Subtitle", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "track" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Track", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "comment" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Comment", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "composer" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Composer", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "copyright" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Copyright", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "publicationright" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Publicationright", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "filename" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "File", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "recordlocation" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Record Location", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "recorddate" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Record Date", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "ean/upc" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "EAN/UPC", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "year" ) || 0 == strcmp ( arg, "releasedate") ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Year", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "genre" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Genre", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "media" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Media", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "index" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Index", 0, p, strlen(p), NoUnicode*3, 0 ); } else if ( 0 == strcmp ( arg, "isrc" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "ISRC", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "abstract" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Abstract", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "bibliography" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Bibliography", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "introplay" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Introplay", 0, p, strlen(p), NoUnicode*3, 0 ); } else if ( 0 == strcmp ( arg, "media" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = argv[k]; addtag ( "Media", 0, p, strlen(p), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "tag" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = strchr ( argv[k], '=' ); if ( p == NULL ) addtag ( argv[k], strlen(argv[k]), "", 0, NoUnicode, 0 ); else addtag ( argv[k], p-argv[k], p+1, strlen(p+1), NoUnicode, 0 ); } else if ( 0 == strcmp ( arg, "tagfile" ) ) { if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; } p = strchr ( argv[k], '=' ); if ( p == NULL ) { stderr_printf (" Enter value for tag key '%s': ", argv[k] ); if (0 != fgets ( buff, sizeof buff, stdin )) { len = strlen (buff); while ( len > 0 && (buff [len-1] == '\r' || buff [len-1] == '\n') ) len--; addtag ( arg, strlen(arg), buff, len, NoUnicode*6, 0 ); } } else { fp = fopen ( p+1, "rb" ); if ( fp == NULL ) { fprintf ( stderr, "Can't open file '%s'.\n", p+1 ); } else { addtag ( argv[k], p-argv[k], buff, fread (buff,1,sizeof buff,fp), NoUnicode*2, 3 ); fclose (fp); } } } else { stderr_printf ( "\n\033[33;41;1mERROR\033[0m: unknown option '--%s' !\n", arg ); shorthelp(); return -1; } } TestProfileParams (m); return 0; } static void ShowParameters (PsyModel * m, char* inDatei, char* outDatei ) { static const char unk [] = "???"; static const char* EarModel [] = { "ISO (bad!!!)", "Busch", "Filburt", "Klemm", "Klemm/Busch mix", "min(Klemm,Busch)" }; static const char th [ 7] [4] = { "no", "1st", "2nd", "3rd", "4th", "5th", "6th" }; static const char able [ 3] [9] = { "Disabled", "Enabled", "Dual" }; static const char* stereo [16] = { "Simple uncoupled Stereo", "Mid/Side Stereo + Intensity Stereo 2 bit", "Mid/Side Stereo + Intensity Stereo 4 bit", "Mid/Side Stereo, destroyed imaging (unusable)", "Mid/Side Stereo, much reduced imaging", "Mid/Side Stereo, reduced imaging (-3 dB)", "Mid/Side Stereo when superior", unk, unk, unk, "Mid/Side Stereo when superior + enhanced (1.5/3 dB)", "Mid/Side Stereo when superior + enhanced (2/6 dB)", "Mid/Side Stereo when superior + enhanced (2.5/9 dB)", "Mid/Side Stereo when superior + enhanced (3/12 dB)", unk, "Mid/Side Stereo when superior + enhanced (3/oo dB)" }; static const char* const Profiles [16] = { "n.a", "Unstable/Experimental", unk, unk, unk, "below Telephone", "below Telephone", "Telephone", "Thumb", "Radio", "Standard", "Xtreme", "Insane", "BrainDead", "above BrainDead", "above BrainDead" }; stderr_printf ( "\n" " encoding file '%s'\n" " to file '%s'\n" "\n" " SV %u, Profile '%s'\n", inDatei, outDatei, 8, Profiles [m->MainQual] ); if ( verbose > 0 ) { stderr_printf ( "\n" ); if ( FadeInTime != 0. || FadeOutTime != 0. || verbose > 1 ) stderr_printf ( " PCM fader : fade-in: %.2f s, fade-out: %.2f s, shape: %g\n", FadeInTime, FadeOutTime, FadeShape ); if ( ScalingFactorr != 1. || ScalingFactorl != 1. || verbose > 1 ) stderr_printf ( " Scaling input by : left %.5f, right: %.5f\n", ScalingFactorl, ScalingFactorr ); stderr_printf ( " Maximum encoded bandwidth: %4.1f kHz\n", (m->Max_Band+1) * (m->SampleFreq/32./2000.) ); stderr_printf ( " Adaptive Noise Shaping : max. %s order\n", th [m->NS_Order] ); stderr_printf ( " Clear Voice Detection : %s\n", able [m->CVD_used] ); stderr_printf ( " Mid/Side Stereo : %s\n", stereo [m->MS_Channelmode] ); stderr_printf ( " Threshold of Hearing : Model %3u: %s, Max ATH: %2.0f dB, Offset: %+1.0f dB, +Offset@20 kHz:%3.0f dB\n", m->EarModelFlag, m->EarModelFlag/100 < sizeof(EarModel)/sizeof(*EarModel) ? EarModel [m->EarModelFlag/100] : unk, m->Ltq_max, m->Ltq_offset, -0.6 * (int) (m->EarModelFlag % 100 - 50) ); if ( m->NMT != 6.5 || verbose > 1 ) stderr_printf ( " Noise masks Tone Ratio : %4.1f dB\n", m->NMT ); if ( m->TMN != 18.0 || verbose > 1 ) stderr_printf ( " Tone masks Noise Ratio : %4.1f dB\n", m->TMN ); if ( m->PNS > 0 ) stderr_printf ( " PNS Threshold : %4.2f\n", m->PNS ); if ( !m->tmpMask_used ) stderr_printf ( " No exploitation of temporal post masking\n" ); else if ( verbose > 1 ) stderr_printf ( " Exploitation of temporal post masking\n" ); if ( m->minSMR > 0. ) stderr_printf ( " Minimum Signal-to-Mask : %4.1f dB\n", m->minSMR ); else if ( verbose > 1 ) stderr_printf ( " No minimum SMR (psycho model controlled filtering)\n" ); if ( DelInput == 0xAFFEDEAD ) stderr_printf ( " Deleting input file after (successful) encoding\n" ); else if ( verbose > 1 ) stderr_printf ( " No deleting of input file after encoding\n" ); } stderr_printf ( "\n" ); } /* * Print out the time to stderr with a precision of 10 ms always using * 12 characters. Time is represented by the sample count. An additional * prefix character (normally ' ' or '-') is prepended before the first * digit. */ static const char* PrintTime ( PsyModel* m, mpc_uint64_t samples, int sign ) { static char ret [32]; mpc_uint32_t tmp = (mpc_uint32_t) ( (long double)(samples) * 100. / m->SampleFreq ); mpc_uint_t hour = (mpc_uint_t) ( tmp / 360000 ); mpc_uint_t min = (mpc_uint_t) ( tmp / 6000 % 60 ); mpc_uint_t sec = (mpc_uint_t) ( tmp / 100 % 60 ); mpc_uint_t csec = (mpc_uint_t) ( tmp % 100 ); if ( (long double)(samples) >= m->SampleFreq * 360000. ) return " "; else if ( hour > 9 ) sprintf ( ret, "%c%2u:%02u", sign, hour, min ); else if ( hour > 0 ) sprintf ( ret, " %c%1u:%02u", sign, hour, min ); else if ( min > 9 ) sprintf ( ret, " %c%2u", sign, min ); else sprintf ( ret, " %c%1u", sign, min ); sprintf ( ret + 6, ":%02u.%02u", sec, csec ); return ret; } static void ShowProgress ( PsyModel* m, mpc_uint64_t samples, mpc_uint64_t total_samples, mpc_uint64_t databits ) { static clock_t start; clock_t curr; float percent; float kbps; float speed; float total_estim; if ( samples == 0 ) { if ( DisplayUpdateTime >= 0 ) { stderr_printf (" %%|avg.bitrate| speed|play time (proc/tot)| CPU time (proc/tot)| ETA\n" " -.- -.- kbps -.--x -:--.- -:--.- -:--.- -:--.- -:--.-\r" ); } start = clock (); return; } curr = clock (); if ( curr == start ) return; percent = 100.f * (long double)(samples) / (long double)(total_samples); kbps = 1.e-3f * (long double)(databits) * m->SampleFreq / (long double)(samples); speed = 1.f * (long double)(samples) * (CLOCKS_PER_SEC / m->SampleFreq) / (unsigned long)(curr - start) ; total_estim = 1.f * (long double)(total_samples) / (long double)(samples) * (unsigned long)(curr - start); // progress percent if ( total_samples < mpc_int64_max ) stderr_printf ("\r%5.1f ", percent ); else stderr_printf ("\r " ); // average data rate stderr_printf ( "%6.1f kbps ", kbps ); // encoder speed stderr_printf ( "%5.2fx ", speed ); // 2x duration in WAVE file time (encoded/total) stderr_printf ("%10.10s" , PrintTime ( m, samples , (char)' ')+1 ); stderr_printf ("%10.10s ", PrintTime ( m, total_samples, (char)' ')+1 ); // 2x coding time (encoded/total) stderr_printf ("%10.10s" , PrintTime ( m, (curr - start) * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1 ); stderr_printf ("%10.10s ", PrintTime ( m, total_estim * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1 ); // ETA stderr_printf ( "%10.10s\r", samples < total_samples ? PrintTime (m, (total_estim - curr + start) * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1 : "" ); fflush ( stderr ); if ( WIN32_MESSAGES && FrontendPresent ) SendProgressMessage ( kbps, speed, percent ); } static int myfeof ( FILE* fp ) { int ch; if ( fp != (FILE*)-1 ) return feof (fp); ch = CheckKeyKeep (); if ( ch == 'q' || ch == 'Q' ) return 1; return 0; } static void fill_float(float * buffer,float val,unsigned count) { unsigned n; for(n=0;nOverflows > 0 ) { // report internal clippings stderr_printf ( "\n" "\033[1m\rWARNING:\n" "\033[0m\r There still occured %u SCF clippings.\n" " Use the '--scale' method to avoid additional distortions. Note that this\n" " file already has annoying distortions due to slovenly CD mastering.\a\n\n", e->Overflows ); } } // FIXME : not sure if it's a good idea static void Init_FPU ( void ) { mpc_uint16_t cw; #if defined __i386__ && defined _FPU_GETCW && defined _FPU_SETCW _FPU_GETCW ( cw ); cw &= ~0x300; _FPU_SETCW ( cw ); #elif defined __i386__ && defined FPU_GETCW && defined FPU_SETCW FPU_GETCW ( cw ); cw &= ~0x300; FPU_SETCW ( cw ); #elif defined __MINGW32__ __asm__ ("fnstcw %0" : "=m" (*&cw)); cw &= ~0x300; __asm__ ("fldcw %0" : : "m" (*&cw)); #elif defined(_WIN32) && !defined(_WIN64) _asm { fstcw cw }; cw &= ~0x300; _asm { fldcw cw }; #else (void)cw; // remove unused variable warning #endif } static FILE * OpenStream(char * OutputName) { FILE * OutputFile = NULL; /* open bitstream file */ if ( 0 == strcmp ( OutputName, "/dev/null") ) OutputFile = fopen (DEV_NULL, "wb"); else if ( 0 == strcmp ( OutputName, "-") || 0 == strcmp ( OutputName, "/dev/stdout") ) OutputFile = SETBINARY_OUT (stdout); else switch ( WriteMode ) { default: stderr_printf ( "\033[33;41;1mERROR\033[0m: Invalid Write mode, internal error\n" ); exit(1); case MODE_NEVER_OVERWRITE: OutputFile = fopen ( OutputName, "rb" ); if ( OutputFile != NULL ) { fclose ( OutputFile ); stderr_printf ( "\033[33;41;1mERROR\033[0m: Output file '%s' already exists\n", OutputName ); exit(1); } OutputFile = fopen ( OutputName, "w+b" ); break; case MODE_OVERWRITE: OutputFile = fopen ( OutputName, "w+b" ); break; case MODE_ASK_FOR_OVERWRITE: OutputFile = fopen ( OutputName, "rb" ); if ( OutputFile != NULL ) { char c; fclose ( OutputFile ); stderr_printf ( "\nmpcenc: Output file '%s' already exists, overwrite (Y/n)? ", OutputName ); c = waitkey (); if ( c != 'Y' && c != 'y' ) { stderr_printf ( "No!!!\n\n*** Canceled overwrite ***\n" ); exit(1); } stderr_printf ( " YES\n" ); } OutputFile = fopen ( OutputName, "w+b" ); break; } if ( OutputFile == NULL ) { stderr_printf ( "\033[33;41;1mERROR\033[0m: Could not create output file '%s'\n", OutputName ); exit(1); } return OutputFile; } static int mainloop ( int argc, char** argv ) { SMRTyp SMR; // contains SMRs for the given frame PCMDataTyp Main; // contains PCM data for 1600 samples SubbandFloatTyp X [32]; // Subbandsamples as float() wave_t Wave; // contains WAV-files arguments mpc_uint64_t AllSamplesRead = 0; // overall read Samples per channel unsigned int CurrentRead = 0; // current read Samples per channel unsigned int N; // counter for processed frames char* InputName = NULL; // Name of WAVE file char* OutputName = NULL; // Name of bitstream file int Silence = 0; int OldSilence = 0; time_t T; int TransientL [PART_SHORT]; // Flag of transient detection int TransientR [PART_SHORT]; // Flag of transient detection int Transient [32]; // Flag of transient detection PsyModel m; mpc_encoder_t e; mpc_uint_t si_size; // initialize tables which must be initialized once and only once m.SCF_Index_L = (int*) e.SCF_Index_L; m.SCF_Index_R = (int*) e.SCF_Index_R; Init_Psychoakustik (&m); Init_FPU (); // initialize PCM-data memset ( &Main, 0, sizeof Main ); // open WAV file if ( EvalParameters (&m, argc, argv, &InputName, &OutputName, 1 ) < 0 ) return 1; if ( Open_WAV_Header ( &Wave, InputName ) < 0 ) { stderr_printf ( "\033[33;41;1mERROR\033[0m: Unable to read or decode: '%s'\n", InputName ); return 1; } TitleBar ( InputName ); CopyTags ( InputName ); // read WAV-Header if ( 0 != Read_WAV_Header (&Wave) ) { stderr_printf ( "\033[33;41;1mERROR\033[0m: Invalid file header, not a WAVE file '%s'\n", InputName ); return 1; } m.SampleFreq = Wave.SampleFreq; SamplesInWAVE = Wave.PCMSamples; if ( Wave.SampleFreq != 44100. && Wave.SampleFreq != 48000. && Wave.SampleFreq != 37800. && Wave.SampleFreq != 32000. ) { stderr_printf ( "\033[33;41;1mERROR\033[0m: Sampling frequency of %g kHz is not supported!\n\n", (double)(Wave.SampleFreq * 1.e-3) ); return 1; } if ( Wave.BitsPerSample < 8 || Wave.BitsPerSample > 32 ) { stderr_printf ( "\033[33;41;1mERROR\033[0m: %i bits per sample are not supported!\n\n", Wave.BitsPerSample ); return 1; } switch ( Wave.Channels ) { case 0: stderr_printf ( "\033[33;41;1mERROR\033[0m: 0 channels file, this is nonsense\n\n" ); return 1; case 1: case 2: break; case 3: case 4: case 5: case 6: case 7: case 8: stderr_printf ( "WARNING: %i channel(s) file, only first 2 channels are encoded.\n\n", Wave.Channels ); break; default: stderr_printf ( "\033[33;41;1mERROR\033[0m: %i channel(s) file, not supported\n\n", Wave.Channels ); return 1; } SetQualityParams (&m, 5.0); if ( EvalParameters (&m, argc, argv, &InputName, &OutputName, 0 ) < 0 ) return 1; if ( (long double)(SamplesInWAVE) >= Wave.SampleFreq * (SkipTime + Duration) ) { SamplesInWAVE = Wave.SampleFreq * (SkipTime + Duration); } mpc_encoder_init (&e, SamplesInWAVE, FramesBlockPwr, SeekDistance); Init_Psychoakustiktabellen (&m); // must be done AFTER decoding command line parameters // check fade-length if ( FadeInTime + FadeOutTime > (long double)(SamplesInWAVE) / Wave.SampleFreq ) { stderr_printf ( "WARNING: Duration of fade in + out exceeds file length!\n"); FadeInTime = FadeOutTime = 0.5 * (long double)(SamplesInWAVE) / Wave.SampleFreq; } e.outputFile = OpenStream(OutputName); ShowParameters (&m, InputName, OutputName ); if ( WIN32_MESSAGES && FrontendPresent ) SendModeMessage (m.MainQual); if ( SkipTime > 0. ) { unsigned long SkipSamples = m.SampleFreq * SkipTime; signed long read; while ( SkipSamples > 0 ) { read = Read_WAV_Samples ( &Wave, mini(BLOCK, SkipSamples), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence ); if ( read <= 0 ) break; SkipSamples -= read; SamplesInWAVE -= read; } } e.MS_Channelmode = m.MS_Channelmode; e.seek_ref = ftell(e.outputFile); writeMagic(&e); writeStreamInfo ( &e, m.Max_Band, m.MS_Channelmode > 0, SamplesInWAVE, 0, m.SampleFreq, Wave.Channels > 2 ? 2 : Wave.Channels); si_size = writeBlock(&e, "SH", MPC_TRUE, 0); writeGainInfo ( &e, 0, 0, 0, 0); writeBlock(&e, "RG", MPC_FALSE, 0); if (NoEncoderInfo == 0) { writeEncoderInfo(&e, m.FullQual, m.PNS > 0, MPCENC_MAJOR, MPCENC_MINOR, MPCENC_BUILD); writeBlock(&e, "EI", MPC_FALSE, 0); } if (NoSeekTable == 0) { e.seek_ptr = ftell(e.outputFile); writeBits (&e, 0, 16); writeBits (&e, 0, 24); // jump 40 bits for seek table pointer writeBlock(&e, "SO", MPC_FALSE, 0); // reserve space for seek offset } // initialize timer ShowProgress (&m, 0, SamplesInWAVE, e.outputBits ); T = time ( NULL ); // read samples CurrentRead = Read_WAV_Samples ( &Wave, (int)minf(BLOCK, SamplesInWAVE - AllSamplesRead), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence ); AllSamplesRead += CurrentRead; if (CurrentRead > 0) { fill_float( Main.L, Main.L[CENTER], CENTER ); fill_float( Main.R, Main.R[CENTER], CENTER ); fill_float( Main.M, Main.M[CENTER], CENTER ); fill_float( Main.S, Main.S[CENTER], CENTER ); } Analyse_Init ( Main.L[CENTER], Main.R[CENTER], X, m.Max_Band ); // adapt SamplesInWAVE to the real number of contained samples if ( myfeof (Wave.fp) ) { stderr_printf ( "WAVE file has incorrect header: header: %.3f s, contents: %.3f s \n", (long double)(SamplesInWAVE) / m.SampleFreq, (long double)(AllSamplesRead) / m.SampleFreq); } for ( N = 0; (mpc_uint64_t)N * BLOCK < SamplesInWAVE + DECODER_DELAY; N++ ) { // setting residual data-fields to zero if ( CurrentRead < BLOCK && N > 0 ) { fill_float( Main.L + (CENTER + CurrentRead), Main.L[CENTER + CurrentRead - 1], BLOCK - CurrentRead ); fill_float( Main.R + (CENTER + CurrentRead), Main.R[CENTER + CurrentRead - 1], BLOCK - CurrentRead ); fill_float( Main.M + (CENTER + CurrentRead), Main.M[CENTER + CurrentRead - 1], BLOCK - CurrentRead ); fill_float( Main.S + (CENTER + CurrentRead), Main.S[CENTER + CurrentRead - 1], BLOCK - CurrentRead ); } /*********************************************************************************/ /* Fade In and Fade Out */ /*********************************************************************************/ if ( FadeInTime > 0. ) if ( FadeInTime > (long double)(BLOCK + (mpc_uint64_t)N*BLOCK) / Wave.SampleFreq ) Fading_In ( &Main, N*BLOCK, Wave.SampleFreq ); if ( FadeOutTime > 0. ) if ( FadeOutTime > (long double)(SamplesInWAVE - (mpc_uint64_t)N*BLOCK) / Wave.SampleFreq ) Fading_Out ( &Main, N*BLOCK, Wave.SampleFreq ); /********************************************************************/ /* Encoder-Core */ /********************************************************************/ // you only get null samples at the output of the filterbank when the last frame contains zeroes memset ( e.Res_L, 0, sizeof e.Res_L ); memset ( e.Res_R, 0, sizeof e.Res_R ); if ( !Silence || !OldSilence ) { Analyse_Filter ( &Main, X, m.Max_Band ); // Analysis-Filterbank (Main -> X) SMR = Psychoakustisches_Modell (&m, m.Max_Band*0+31, &Main, TransientL, TransientR ); // Psychoacoustics return SMRs for input data 'Main' if ( m.minSMR > 0 ) RaiseSMR (&m, m.Max_Band, &SMR ); // Minimum-operation on SBRs (full bandwidth) if ( m.MS_Channelmode > 0 ) MS_LR_Entscheidung ( m.Max_Band, e.MS_Flag, &SMR, X ); // Selection of M/S- or L/R-Coding SCF_Extraktion (&m, &e, m.Max_Band, X ); // Extraction of the scalefactors and normalization of the subband samples TransientenCalc ( Transient, TransientL, TransientR ); if ( m.NS_Order > 0 ) { NS_Analyse (&m, m.Max_Band, e.MS_Flag, SMR, Transient ); // calculate possible ANS-Filter and the expected gain } Allocate ( m.Max_Band, e.Res_L, X[0].L, e.SCF_Index_L[0], m.SNR_comp_L, SMR.L, Power_L, Transient , m.PNS ); // allocate bits for left + right channel Allocate ( m.Max_Band, e.Res_R, X[0].R, e.SCF_Index_R[0], m.SNR_comp_R, SMR.R, Power_R, Transient , m.PNS ); Quantisierung (&m, m.Max_Band, e.Res_L, e.Res_R, X, e.Q ); // quantize samples } OldSilence = Silence; writeBitstream_SV8 ( &e, m.Max_Band); // write SV8-Bitstream if ( (int)(time (NULL) - T) >= 0 ) { // output T += labs (DisplayUpdateTime); ShowProgress (&m, (mpc_uint64_t)(N+1) * BLOCK, SamplesInWAVE, e.outputBits ); } memmove ( Main.L, Main.L + BLOCK, CENTER * sizeof(float) ); memmove ( Main.R, Main.R + BLOCK, CENTER * sizeof(float) ); memmove ( Main.M, Main.M + BLOCK, CENTER * sizeof(float) ); memmove ( Main.S, Main.S + BLOCK, CENTER * sizeof(float) ); // read samples CurrentRead = Read_WAV_Samples ( &Wave, (int)minf(BLOCK, SamplesInWAVE - AllSamplesRead), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence ); AllSamplesRead += CurrentRead; // adapt SamplesInWAV to the real number of contained samples if ( myfeof (Wave.fp) ) { stderr_printf ( "WAVE file has incorrect header: header: %.3f s, contents: %.3f s \n", (long double)(SamplesInWAVE) / m.SampleFreq, (long double)(AllSamplesRead) / m.SampleFreq); SamplesInWAVE = AllSamplesRead; } } // write the last incomplete block if (e.framesInBlock != 0) { if ((e.block_cnt & ((1 << e.seek_pwr) - 1)) == 0) { e.seek_table[e.seek_pos] = ftell(e.outputFile); e.seek_pos++; } e.block_cnt++; writeBlock(&e, "AP", MPC_FALSE, 0); } if (NoSeekTable == 0) { writeSeekTable(&e); writeBlock(&e, "ST", MPC_FALSE, 0); // write seek table block } writeBlock(&e, "SE", MPC_FALSE, 0); // write end of stream block if (Wave.PCMSamples != AllSamplesRead) { fseek(e.outputFile, e.seek_ref + 4, SEEK_SET); writeStreamInfo ( &e, m.Max_Band, m.MS_Channelmode > 0, SamplesInWAVE, 0, m.SampleFreq, Wave.Channels > 2 ? 2 : Wave.Channels); writeBlock(&e, "SH", MPC_TRUE, si_size); fseek(e.outputFile, 0, SEEK_END); } ShowProgress (&m, SamplesInWAVE, SamplesInWAVE, e.outputBits ); FinalizeTags ( e.outputFile, APE_Version, 0 ); fclose ( e.outputFile ); fclose ( Wave.fp ); mpc_encoder_exit(&e); if ( DelInput == 0xAFFEDEAD && remove (InputName) == -1 ) // delete input file if DelInput is active stderr_printf ( "\n\n\033[33;41;1mERROR\033[0m: Could not delete input file '%s'\n", InputName ); if ( WIN32_MESSAGES && FrontendPresent ) SendQuitMessage (); stderr_printf ( "\n" ); OverdriveReport (&e); // output a report if clipping was necessary return 0; } /************ The main() function *****************************/ int mpc_cdecl main ( int argc, char** argv ) { int ret; #ifdef _OS2 _wildcard ( &argc, &argv ); #endif #ifdef LC_CTYPE setlocale(LC_CTYPE, ""); NoUnicode = (strcmp(nl_langinfo(CODESET), "UTF-8") != 0); #endif if ( WIN32_MESSAGES ) { FrontendPresent = SearchForFrontend (); // search for presence of Windows Frontend if ( FrontendPresent ) SendStartupMessage ( MPCENC_VERSION, 8); } // Welcome message if ( argc < 2 || ( 0 != strcmp (argv[1], "--silent") && 0 != strcmp (argv[1], "--quiet")) ) (void) stderr_printf ("\r\x1B[1m\r%s\n\x1B[0m\r \r", About ); #ifdef FAST_MATH Init_FastMath (); #endif // no arguments or call for help if ( argc < 2 || 0==strcmp (argv[1],"-h") || 0==strcmp (argv[1],"-?") || 0==strcmp (argv[1],"--help") ) { PsyModel m; SetQualityParams (&m, 5.0); dup2 ( 1, 2 ); shorthelp (); return 1; } if ( 0==strcmp (argv[1],"--longhelp") || 0==strcmp (argv[1],"-??") ) { PsyModel m; SetQualityParams (&m, 5.0); dup2 ( 1, 2 ); longhelp (&m); return 1; } ret = mainloop ( argc, argv ); // analyze command line and do the requested work if(IsEndBeep) stderr_printf("\a\a\a"); #ifdef BUGBUG reppr (); #endif return ret; } /* end of mpcenc.c */ musepack_src_r495/mpcenc/mpcenc.h0000664000000000000000000002707712710723372015724 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #ifndef MPCENC_MPCENC_H #define MPCENC_MPCENC_H #include "libmpcenc.h" #include "libmpcpsy.h" #include #include //// optimization/feature defines ////////////////////////////////// #ifndef NOT_INCLUDE_CONFIG_H # include "config.h" #endif //// portable system includes ////////////////////////////////////// #include #include //// system dependent system includes ////////////////////////////// // low level I/O, where are prototypes and constants? #if defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER # include # include # include #elif defined __unix__ || defined __linux__ || defined __APPLE__ # include # include # include # include #else // .... add Includes for new Operating System here (with prefix: #elif defined) # include #endif #if defined __GLIBC__ # include #elif defined __FreeBSD__ # include #elif defined _MSC_VER # include #endif // Use termios for reading values from keyboard without echo and ENTER #define USE_TERMIOS // make debug output in tags.c stfu #define STFU #ifndef O_BINARY # ifdef _O_BINARY # define O_BINARY _O_BINARY # else # define O_BINARY 0 # endif #endif #if defined _WIN32 || defined __TURBOC__ # define strncasecmp(__s1,__s2,__n) strnicmp ((__s1), (__s2), (__n)) # define strcasecmp(__s1,__s2) stricmp ((__s1), (__s2)) #endif #if defined _WIN32 # include # define snprintf _snprintf # define getcwd(__buff,__len) _getcwd ((__buff), (__len)) #endif //// Binary/Low-Level-IO /////////////////////////////////////////// // #if defined __BORLANDC__ || defined _WIN32 # define FILENO(__fp) _fileno ((__fp)) #elif defined __CYGWIN__ || defined __TURBOC__ || defined __unix__ || defined __EMX__ || defined _MSC_VER # define FILENO(__fp) fileno ((__fp)) #else # define FILENO(__fp) fileno ((__fp)) #endif // // If we have access to a file via file name, we can open the file with an // additional "b" or a O_BINARY within the (f)open function to get a // transparent untranslated data stream which is necessary for audio bitstream // data and also for PCM data. If we are working with // stdin/stdout/FILENO_STDIN/FILENO_STDOUT we can't open the file with these // attributes, because the files are already open. So we need a non // standardized sequence to switch to this mode (not necessary for Unix). // Mostly the sequence is the same for incoming and outgoing streams, but only // mostly so we need one for IN and one for OUT. // Macros are called with the file pointer and you get back the untransalted file // pointer which can be equal or different from the original. // #if defined __EMX__ # define SETBINARY_IN(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) # define SETBINARY_OUT(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) #elif defined __TURBOC__ || defined __BORLANDC__ # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) #elif defined __CYGWIN__ # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) #elif defined _WIN32 # define SETBINARY_IN(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) # define SETBINARY_OUT(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) #elif defined _MSC_VER # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) #elif defined __unix__ # define SETBINARY_IN(__fp) (__fp) # define SETBINARY_OUT(__fp) (__fp) #elif 0 # define SETBINARY_IN(__fp) (freopen ( NULL, "rb", (__fp) ), (__fp)) # define SETBINARY_OUT(__fp) (freopen ( NULL, "wb", (__fp) ), (__fp)) #else # define SETBINARY_IN(__fp) (__fp) # define SETBINARY_OUT(__fp) (__fp) #endif // file I/O using ANSI buffered file I/O via file pointer FILE* (fopen, fread, fwrite, fclose) #define READ(fp,ptr,len) fread (ptr, 1, len, fp) // READ returns -1 or 0 on error/EOF, otherwise > 0 #define READ1(fp,ptr) fread (ptr, 1, 1, fp) // READ returns -1 or 0 on error/EOF, otherwise > 0 #ifdef _WIN32 # define POPEN_READ_BINARY_OPEN(cmd) _popen ((cmd), "rb") #else # define POPEN_READ_BINARY_OPEN(cmd) popen ((cmd), "r") #endif // Path separator #if defined __unix__ || defined __bsdi__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __APPLE__ # define PATH_SEP '/' # define DRIVE_SEP '\0' # define EXE_EXT "" # define DEV_NULL "/dev/null" # define ENVPATH_SEP ':' #elif defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER # define PATH_SEP '\\' # define DRIVE_SEP ':' # define EXE_EXT ".exe" # define DEV_NULL "\\nul" # define ENVPATH_SEP ';' #else # define PATH_SEP '/' // Amiga: C:/ # define DRIVE_SEP ':' # define EXE_EXT "" # define DEV_NULL "nul" # define ENVPATH_SEP ';' #endif #ifdef _WIN32 # define TitleBar(text) SetConsoleTitle (text) #else # define TitleBar(text) (void) (text) #endif //// constants ///////////////////////////////////////////////////// #define DECODER_DELAY (512 - 32 + 1) #define BLK_SIZE (36 * 32) //// procedures/functions ////////////////////////////////////////// // pipeopen.c FILE* pipeopen ( const char* command, const char* filename ); // stderr.c void SetStderrSilent ( mpc_bool_t state ); mpc_bool_t GetStderrSilent ( void ); int mpc_cdecl stderr_printf ( const char* format, ... ); // quant.h #define SCFfac 0.832980664785f // = SCF[n-1]/SCF[n] // wave_in.h typedef struct { FILE* fp; // File pointer to read data mpc_size_t PCMOffset; // File offset of PCM data long double SampleFreq; // Sample frequency in Hz mpc_uint_t BitsPerSample; // used bits per sample, 8*BytesPerSample-7 <= BitsPerSample <= BytesPerSample mpc_uint_t BytesPerSample; // allocated bytes per sample mpc_uint_t Channels; // Number of channels, 1...8 mpc_size_t PCMBytes; // PCM Samples (in 8 bit units) mpc_size_t PCMSamples; // PCM Samples per Channel mpc_bool_t raw; // raw: headerless format } wave_t; typedef float SCFTriple [3]; // FIXME : put in lib header void Init_FFT ( PsyModel* ); // FIXME : put in lib header void Init_Psychoakustik ( PsyModel* ); SMRTyp Psychoakustisches_Modell ( PsyModel *, const int, const PCMDataTyp*, int* TransientL, int* TransientR ); void TransientenCalc ( int* Transient, const int* TransientL, const int* TransientR ); void RaiseSMR ( PsyModel*, const int, SMRTyp* ); void MS_LR_Entscheidung ( const int, unsigned char* MS, SMRTyp*, SubbandFloatTyp* ); void Init_Psychoakustiktabellen ( PsyModel* ); void NS_Analyse (PsyModel*, const int, const unsigned char* MS, const SMRTyp, const int* Transient ); void Analyse_Filter(const PCMDataTyp*, SubbandFloatTyp*, const int); void Analyse_Init ( float Left, float Right, SubbandFloatTyp* out, const int MaxBand ); void SetQualityParams (PsyModel *, float ); int TestProfileParams ( PsyModel* ); extern const float Butfly [7]; // Antialiasing to calculate the subband powers extern const float InvButfly [7]; // Antialiasing to calculate the masking thresholds extern const float iw [PART_LONG]; // inverse partition-width for long extern const float iw_short [PART_SHORT]; // inverse partition-width for short extern const int wl [PART_LONG]; // w_low for long extern const int wl_short [PART_SHORT]; // w_low for short extern const int wh [PART_LONG]; // w_high for long extern const int wh_short [PART_SHORT]; // w_high for short // quant.c extern float __invSCF [128 + 6]; // tabulated scalefactors (inverted) #define invSCF (__invSCF + 6) float ISNR_Schaetzer ( const float* samples, const float comp, const int res); float ISNR_Schaetzer_Trans ( const float* samples, const float comp, const int res); void QuantizeSubband ( unsigned int* qu_output, const float* input, const int res, float* errors, const int maxNsOrder ); void QuantizeSubbandWithNoiseShaping ( unsigned int* qu_output, const float* input, const int res, float* errors, const float* FIR ); void NoiseInjectionComp ( void ); // keyboard.c int WaitKey ( void ); int CheckKeyKeep ( void ); int CheckKey ( void ); // regress.c void Regression ( float* const _r, float* const _b, const float* p, const float* q ); // tags.c void Init_Tags ( void ); int FinalizeTags ( FILE* fp, unsigned int Version, unsigned int flags ); int addtag ( const char* key, size_t keylen, const char* value, size_t valuelen, int converttoutf8, int flags ); int gettag ( const char* key, char* dst, size_t len ); int CopyTags ( const char* filename ); // wave_in.c int Open_WAV_Header ( wave_t* type, const char* name ); size_t Read_WAV_Samples ( wave_t* t, const size_t RequestedSamples, PCMDataTyp* data, const ptrdiff_t offset, const float scalel, const float scaler, int* Silence ); int Read_WAV_Header ( wave_t* type ); // winmsg.c #ifdef _WIN32 #define WIN32_MESSAGES 1 // support Windows-Messaging to Frontend int SearchForFrontend ( void ); void SendQuitMessage ( void ); void SendModeMessage ( const int ); void SendStartupMessage ( const char*, const int); void SendProgressMessage ( const int, const float, const float ); #else # define WIN32_MESSAGES 0 # define SearchForFrontend() (0) # define SendQuitMessage() (void)0 # define SendModeMessage(x) (void)0 # define SendStartupMessage(x,y) (void)0 # define SendProgressMessage(x,y,z) (void)0 #endif /* _WIN32 */ #define MPPENC_DENORMAL_FIX_BASE ( 32. * 1024. /* normalized sample value range */ / ( (float) (1 << 24 /* first bit below 32-bit PCM range */ ) ) ) #define MPPENC_DENORMAL_FIX_LEFT ( MPPENC_DENORMAL_FIX_BASE ) #define MPPENC_DENORMAL_FIX_RIGHT ( MPPENC_DENORMAL_FIX_BASE * 0.5f ) #ifndef LAST_HUFFMAN # define LAST_HUFFMAN 7 #endif #endif /* MPCENC_MPCENC_H */ /* end of mpcenc.h */ musepack_src_r495/mpcenc/CMakeLists.txt0000664000000000000000000000147411417031041017023 0ustar rootrootif(MPC_ENDIANNESS) add_definitions(-DMPC_BIG_ENDIAN) endif(MPC_ENDIANNESS) include_directories(${libmpc_SOURCE_DIR}/include) include_directories(${libmpc_SOURCE_DIR}/libmpcpsy) include_directories(${libmpc_SOURCE_DIR}/libmpcenc) link_directories(${libmpc_BINARY_DIR}/libmpcpsy) link_directories(${libmpc_BINARY_DIR}/libmpcenc) add_executable(mpcenc keyboard.c mpcenc.c pipeopen.c stderr.c ${libmpc_SOURCE_DIR}/common/tags.c wave_in.c winmsg.c) target_link_libraries(mpcenc mpcpsy_static) target_link_libraries(mpcenc mpcenc_static) if(WIN32) target_link_libraries(mpcenc winmm) endif(WIN32) if(NOT MSVC) target_link_libraries(mpcenc m) endif(NOT MSVC) if(CMAKE_SYSTEM_NAME STREQUAL OpenBSD) target_link_libraries(mpcenc ossaudio) endif(CMAKE_SYSTEM_NAME STREQUAL OpenBSD) install(TARGETS mpcenc RUNTIME DESTINATION bin) musepack_src_r495/mpcenc/winmsg.c0000664000000000000000000000417712231315357015750 0ustar rootroot/* * Musepack audio compression * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "mpcenc.h" #ifdef _WIN32 #include static HWND FrontEndHandle; int SearchForFrontend ( void ) { FrontEndHandle = FindWindow ( NULL, "mpcdispatcher" ); // check for dispatcher window and (send startup-message???) return FrontEndHandle != 0; } static void SendMsg ( const char* s ) { COPYDATASTRUCT MsgData; MsgData.dwData = 3; // build message MsgData.lpData = (char*)s; MsgData.cbData = strlen(s) + 1; SendMessage ( FrontEndHandle, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &MsgData ); // send message } void SendStartupMessage ( const char* Version, const int SV) { char startup [120]; sprintf ( startup, "#START#MP+ v%s SV%i", Version, SV); // fill startup-message SendMsg ( startup ); } void SendQuitMessage ( void ) { SendMsg ("#EOF#"); } void SendModeMessage ( const int Profile ) { char message [32]; sprintf ( message, "#PARAM#%d#", Profile-8 ); // fill message SendMsg ( message ); } void /* sends progress information to the frontend */ SendProgressMessage ( const int bitrate, const float speed, const float percent ) { char message [64]; sprintf ( message, "#STAT#%4ik %5.2fx %5.1f%%#", bitrate, speed, percent ); SendMsg ( message ); } #endif /* _WIN32 */ musepack_src_r495/mpcenc/stderr.c0000664000000000000000000001650111614330361015735 0ustar rootroot/* * stderr - Message output system * * (C) Frank Klemm, Janne Hyv�inen 2002. All rights reserved. * * Principles: * * History: * 2001 created * 2002 Spring added functionality to switch on and off printing to easily allow silent modes * 2002-10-10 Escape sequence handling for Windows added. * * Global functions: * - SetStderrSilent() * - GetStderrSilent() * - stderr_printf() * * TODO: * - */ #include #ifdef _WIN32 # include #endif #include #include // #include "mpcenc.h" #define WRITE(fp,ptr,len) fwrite (ptr, 1, len, fp) // WRITE returns -1 or 0 on error/EOF, otherwise > 0 static mpc_bool_t stderr_silent = 0; void SetStderrSilent ( mpc_bool_t state ) { stderr_silent = state; } mpc_bool_t GetStderrSilent ( void ) { return stderr_silent; } int mpc_cdecl stderr_printf ( const char* format, ... ) { char buff [2 * 1024 + 3072]; char* p = buff; int ret; va_list v; /* print to a buffer */ va_start ( v, format ); ret = vsprintf ( p, format, v ); va_end ( v ); if ( !stderr_silent ) { #if defined __unix__ || defined __UNIX__ WRITE ( stderr, buff, ret ); #elif defined _WIN32 # define FOREGROUND_ALL ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) # define BACKGROUND_ALL ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED ) // for Windows systems we must merge carriage returns into the stream to avoid staircases // Also escape sequences must be detected and replaced (incomplete now) char buff [128], *q; static int init = 0; CONSOLE_SCREEN_BUFFER_INFO con_info; static HANDLE hSTDERR; static WORD attr; static WORD attr_initial; DWORD written; if ( init == 0 ) { hSTDERR = GetStdHandle ( STD_ERROR_HANDLE ); attr = hSTDERR == INVALID_HANDLE_VALUE || GetConsoleScreenBufferInfo ( hSTDERR, &con_info ) == 0 ? FOREGROUND_ALL : con_info.wAttributes; attr_initial = attr; init = 1; } if ( hSTDERR == INVALID_HANDLE_VALUE ) { while ( ( q = strchr (p, '\n')) != NULL ) { WRITE ( stderr, p, q-p ); WRITE ( stderr, "\r\n", 2 ); p = q+1; } WRITE ( stderr, p, strlen (p) ); } else { for ( ; *p; p++ ) { switch ( *p ) { case '\n': SetConsoleTextAttribute ( hSTDERR, attr_initial ); fprintf ( stderr, "\r\n" ); SetConsoleTextAttribute ( hSTDERR, attr ); break; case '\x1B': if ( p[1] == '[' ) { unsigned int tmp; p++; cont: p++; for ( tmp = 0; (unsigned int)( *p - '0' ) < 10u; p++ ) tmp = 10 * tmp + ( *p - '0' ); switch ( *p ) { case ';': case 'm': switch ( tmp ) { case 0: attr = FOREGROUND_ALL; break; // reset defaults case 1: attr |= FOREGROUND_INTENSITY; break; // high intensity on case 2: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_INTENSITY; break; // (very) low intensity case 3: break; // italic on case 4: break; // underline on case 5: break; // blinking on case 7: break; // reverse case 8: attr = 0; break; // invisible case 30: attr &= ~FOREGROUND_ALL; break; case 31: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED; break; case 32: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN; break; case 33: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_GREEN; break; case 34: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_BLUE; break; case 35: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_BLUE; break; case 36: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN | FOREGROUND_BLUE; break; case 37: case 39: attr |= FOREGROUND_ALL; break; case 40: case 49: attr &= ~BACKGROUND_ALL; break; case 41: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED; break; case 42: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN; break; case 43: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_GREEN; break; case 44: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_BLUE; break; case 45: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_BLUE; break; case 46: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN | BACKGROUND_BLUE; break; case 47: attr |= BACKGROUND_ALL; break; } SetConsoleTextAttribute ( hSTDERR, attr ); if ( *p == ';' ) goto cont; break; default: WriteFile ( hSTDERR, buff, sprintf ( buff, "Unknown escape sequence ending with '%c'\n", *p ), &written, NULL ); break; } break; } default: fputc ( *p, stderr ); break; } } /* end for */ } #else char * q; // for non-Unix systems we must merge carriage returns into the stream to avoid staircases while ( ( q = strchr (p, '\n')) != NULL ) { WRITE ( stderr, p, q-p ); WRITE ( stderr, "\r\n", 2 ); p = q+1; } WRITE ( stderr, p, strlen (p) ); #endif } return ret; } /* end of stderr.c */ musepack_src_r495/mpcenc/predict.h0000664000000000000000000001435112231315357016076 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "mpcenc.h" #define MAX_LPC_ORDER 35 #define log2(x) ( log (x) * (1./M_LN2) ) #define ORDER_PENALTY 0 static int // best prediction order model CalculateLPCCoeffs ( Int32_t* buf, // Samples size_t nbuf, // Number of samples Int32_t offset, // double* lpcout, // quantized prediction coefficients int nlpc, // max. prediction order float* psigbit, // expected number of bits per original signal sample float* presbit ) // expected number of bits per residual signal sample { static double* fbuf = NULL; static int nflpc = 0; static int nfbuf = 0; int nbit; int i; int j; int bestnbit; int bestnlpc; double e; double bestesize; double ci; double esize; double acf [MAX_LPC_ORDER + 1]; double ref [MAX_LPC_ORDER + 1]; double lpc [MAX_LPC_ORDER + 1]; double tmp [MAX_LPC_ORDER + 1]; double escale = 0.5 * M_LN2 * M_LN2 / nbuf; double sum; if ( nlpc >= nbuf ) // if necessary, limit the LPC order to the number of samples available nlpc = nbuf - 1; if ( nlpc > nflpc || nbuf > nfbuf ) { // grab some space for a 'zero mean' buffer of floats if needed if ( fbuf != NULL ) free ( fbuf - nflpc ); fbuf = nlpc + ((double*) calloc ( nlpc+nbuf, sizeof (*fbuf) )); nfbuf = nbuf; nflpc = nlpc; } e = 0.; for ( j = 0; j < nbuf; j++ ) { // zero mean signal and compute energy sum = fbuf [j] = buf[j] - (double)offset; e += sum * sum; } esize = e > 0. ? 0.5 * log2 (escale * e) : 0.; *psigbit = esize; // return the expected number of bits per original signal sample acf [0] = e; // store the best values so far (the zeroth order predictor) bestnlpc = 0; bestnbit = nbuf * esize; bestesize = esize; for ( i = 1; i <= nlpc && e > 0. && i < bestnlpc + 4; i++ ) { // just check two more than bestnlpc sum = 0.; for ( j = i; j < nbuf; j++ ) // compute the jth autocorrelation coefficient sum += fbuf [j] * fbuf [j-i]; acf [i] = sum; ci = 0.; // compute the reflection and LP coeffients for order j predictor for ( j = 1; j < i; j++ ) ci += lpc [j] * acf [i-j]; lpc [i] = ref [i] = ci = (acf [i] - ci) / e; for ( j = 1; j < i; j++ ) tmp [j] = lpc [j] - ci * lpc [i-j]; for ( j = 1; j < i; j++ ) lpc [j] = tmp [j]; e *= 1 - ci*ci; // compute the new energy in the prediction residual esize = e > 0. ? 0.5 * log2 (escale * e) : 0.; nbit = nbuf * esize + i * ORDER_PENALTY; if ( nbit < bestnbit ) { // store this model if it is the best so far bestnlpc = i; // store best model order bestnbit = nbit; bestesize = esize; for ( j = 0; j < bestnlpc; j++ ) // store the quantized LP coefficients lpcout [j] = lpc [j+1]; } } *presbit = bestesize; // return the expected number of bits per residual signal sample return bestnlpc; // return the best model order } static void Pred ( const unsigned int* new, unsigned int* old ) { static Double DOUBLE [36]; Float org; Float pred; int i; int j; int sum = 18; int order; double oldeff = 0.; double neweff = 0.; for ( i = 0; i < 36; i++ ) sum += old [i]; sum = (int) floor (sum / 36.); order = CalculateLPCCoeffs ( old, 36, sum*0, DOUBLE, 35, &org, &pred ); printf ("avg: %4u [%2u] %.2f %.2f\n\n", sum, order, org, pred ); if ( order < 1 ) return; for ( i = 0; i < order; i++ ) printf ("%f ", DOUBLE[i] ); printf ("\n"); for ( i = 0; i < 36; i++ ) { double sum = 0.; for ( j = 1; j <= order; j++ ) { sum += (i-j < 0 ? old[i-j+36] : new [i-j]) * DOUBLE [j-1]; } printf ("%2u: %6.2f %3d\n", i, sum, new [i] ); oldeff += new[i] * new[i]; neweff += (sum-new[i]) * (sum-new[i]); } printf ("%6.2f %6.2f\n", sqrt(oldeff), sqrt(neweff) ); } void Predicate ( int Channel, int Band, unsigned int* x, int* scf ) { static Int32_t OLD [2] [32] [36]; int i; printf ("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"); for ( i = 0; i < 36; i++ ) printf ("%2d ", OLD [Channel][Band][i] ); printf ("\n"); for ( i = 0; i < 36; i++ ) printf ("%2d ", x[i] ); printf ("\n"); printf ("%2u-%2u-%2u ", scf[0], scf[1], scf[2] ); Pred ( x, OLD [Channel][Band] ); for ( i = 0; i < 36; i++ ) OLD [Channel][Band][i] = x[i]; } /* end of predict.c */ musepack_src_r495/mpcenc/wave_in.c0000664000000000000000000005015412231315357016070 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ # include #include "mpcenc.h" #ifdef _WIN32 static int init_in ( const int SampleCount, const int SampleFreq, const int Channels, const int BitsPerSample ); static size_t get_in ( void* DataPtr ); #endif #define EXT(x) (0 == strcasecmp (ext, #x)) int Open_WAV_Header ( wave_t* type, const char* filename ) { const char* ext = strrchr ( filename, '.'); FILE* fp; type -> raw = 0; if ( 0 == strcmp ( filename, "-") || 0 == strcmp ( filename, "/dev/stdin") ) { fp = SETBINARY_IN ( stdin ); } else if ( ext == NULL ) { fp = NULL; } else if ( EXT(.wav) ) { fp = fopen ( filename, "rb" ); } else if ( EXT(.wv) ) { // wavpack (www.wavpack.com) fp = pipeopen ( "wvunpack # -", filename ); } else if ( EXT(.la) ) { // lossless-audio (www.lossless-audio.com) fp = pipeopen ( "la -console #", filename ); } else if ( EXT(.raw) || EXT(.cdr) || EXT(.pcm) ) { fp = fopen ( filename, "rb" ); type->Channels = 2; type->BitsPerSample = 16; type->BytesPerSample = 2; type->SampleFreq = 44100.; type->raw = 1; type->PCMOffset = 0; type->PCMBytes = 0xFFFFFFFF; type->PCMSamples = 86400 * type->SampleFreq; } else if ( EXT(.pac) || EXT(.lpac) || EXT(.lpa) ) { fp = pipeopen ( "lpac -o -x #", filename ); } else if ( EXT(.fla) || EXT(.flac) ) { #ifdef _WIN32 stderr_printf ( "*** Install at least version 1.03 of FLAC.EXE. Thanks! ***\n\n" ); #endif fp = pipeopen ( "flac -d -s -c - < #", filename ); } else if ( EXT(.rka) || EXT(.rkau) ) { fp = pipeopen ( "rkau # -", filename ); } else if ( EXT(.sz) ) { fp = pipeopen ( "szip -d < #", filename ); } else if ( EXT(.sz2) ) { fp = pipeopen ( "szip2 -d < #", filename ); } else if ( EXT(.ofr) ) { fp = pipeopen ( "optimfrog d # -", filename ); } else if ( EXT(.ape) ) { fp = pipeopen ( "mac # - -d", filename ); } else if ( EXT(.shn) || EXT(.shorten) ) { #ifdef _WIN32 stderr_printf ( "*** Install at least version 3.4 of Shorten.exe. Thanks! ***\n\n" ); #endif fp = pipeopen ( "shorten -x # -", filename ); // Test if it's okay !!!! if ( fp == NULL ) fp = pipeopen ( "shortn32 -x # -", filename ); } else if ( EXT(.mod) ) { fp = pipeopen ( "xmp -b16 -c -f44100 --stereo -o- #", filename ); type->Channels = 2; type->BitsPerSample = 16; type->BytesPerSample = 2; type->SampleFreq = 44100.; type->raw = 1; type->PCMOffset = 0; type->PCMBytes = 0xFFFFFFFF; type->PCMSamples = 86400 * type->SampleFreq; } else { fp = NULL; } type -> fp = fp; return fp == NULL ? -1 : 0; } #undef EXT static float f0 ( const void* p ) { return (void)p, 0.; } static float f8 ( const void* p ) { return (((unsigned char*)p)[0] - 128) * 256.; } static float f16 ( const void* p ) { return ((unsigned char*)p)[0] + 256. * ((signed char*)p)[1]; } static float f24 ( const void* p ) { return ((unsigned char*)p)[0]*(1./256) + ((unsigned char*)p)[1] + 256 * ((signed char*)p)[2]; } static float f32 ( const void* p ) { return ((unsigned char*)p)[0]*(1./65536) + ((unsigned char*)p)[1]*(1./256) + ((unsigned char*)p)[2] + 256 * ((signed char*)p)[3]; } typedef float (*rf_t) (const void*); static int DigitalSilence ( void* buffer, size_t len ) { unsigned long* pl; unsigned char* pc; size_t loops; for ( pl = buffer, loops = len >> 3; loops--; pl += 2 ) if ( pl[0] | pl[1] ) return 0; for ( pc = (unsigned char*)pl, loops = len & 7; loops--; pc++ ) if ( pc[0] ) return 0; return 1; } size_t Read_WAV_Samples ( wave_t* t, const size_t RequestedSamples, PCMDataTyp* data, const ptrdiff_t offset, const float scalel, const float scaler, int* Silence ) { static const rf_t rf [5] = { f0, f8, f16, f24, f32 }; short Buffer [8 * 32/16 * BLOCK]; // read buffer, up to 8 channels, up to 32 bit size_t ReadSamples; // returns number of read samples size_t i; short* b = (short*) Buffer; char* c = (char*) Buffer; float* l = data -> L + offset; float* r = data -> R + offset; float* m = data -> M + offset; float* s = data -> S + offset; // Read PCM data #ifdef _WIN32 if ( t->fp != (FILE*)-1 ) { ReadSamples = fread ( b, t->BytesPerSample * t->Channels, RequestedSamples, t->fp ); } else { while (1) { ReadSamples = get_in (b) / ( t->Channels * t->BytesPerSample ); if ( ReadSamples != 0 ) break; Sleep (10); } } #else ReadSamples = fread ( b, t->BytesPerSample * t->Channels, RequestedSamples, t->fp ); #endif *Silence = DigitalSilence ( b, ReadSamples * t->BytesPerSample * t->Channels ); // Add Null Samples if EOF is reached if ( ReadSamples != RequestedSamples ) //memset ( b + ReadSamples * t->Channels, 0, (RequestedSamples - ReadSamples) * (sizeof(short) * t->Channels) ); memset ( c + ReadSamples * t->Channels * t->BytesPerSample, t->BytesPerSample == 1 ? 0x80 : 0, (RequestedSamples - ReadSamples) * (t->BytesPerSample * t->Channels) ); // Convert to float and calculate M=(L+R)/2 and S=(L-R)/2 signals #ifndef MPC_BIG_ENDIAN if ( t->BytesPerSample == 2 ) { switch ( t->Channels ) { case 1: for ( i = 0; i < RequestedSamples; i++, b++ ) { float temp = b[0] * scalel; l[i] = temp + MPPENC_DENORMAL_FIX_LEFT; r[i] = temp + MPPENC_DENORMAL_FIX_RIGHT; m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; case 2: for ( i = 0; i < RequestedSamples; i++, b += 2 ) { l[i] = b[0] * scalel + MPPENC_DENORMAL_FIX_LEFT; // left r[i] = b[1] * scaler + MPPENC_DENORMAL_FIX_RIGHT; // right m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; case 5: case 6: case 7: case 8: for ( i = 0; i < RequestedSamples; i++, b += t->Channels ) { l[i] = (0.4142 * b[0] + 0.2928 * b[1] + 0.2928 * b[3] - 0.1464 * b[4]) * scalel + MPPENC_DENORMAL_FIX_LEFT; // left r[i] = (0.4142 * b[2] + 0.2928 * b[1] + 0.2928 * b[4] - 0.1464 * b[3]) * scaler + MPPENC_DENORMAL_FIX_RIGHT; // right m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; default: for ( i = 0; i < RequestedSamples; i++, b += t->Channels ) { l[i] = b[0] * scalel + MPPENC_DENORMAL_FIX_LEFT; // left r[i] = b[1] * scaler + MPPENC_DENORMAL_FIX_RIGHT; // right m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; } } else #endif { unsigned int bytes = t->BytesPerSample; rf_t f = rf [bytes]; c = (char*)b; switch ( t->Channels ) { case 1: for ( i = 0; i < RequestedSamples; i++, c += bytes ) { float temp = f(c) * scalel; l[i] = temp + MPPENC_DENORMAL_FIX_LEFT; r[i] = temp + MPPENC_DENORMAL_FIX_RIGHT; m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; case 2: for ( i = 0; i < RequestedSamples; i++, c += 2*bytes ) { l[i] = f(c) * scalel + MPPENC_DENORMAL_FIX_LEFT; // left r[i] = f(c+bytes) * scaler + MPPENC_DENORMAL_FIX_RIGHT; // right m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; default: for ( i = 0; i < RequestedSamples; i++, c += bytes * t->Channels ) { l[i] = f(c) * scalel + MPPENC_DENORMAL_FIX_LEFT; // left r[i] = f(c+bytes) * scaler + MPPENC_DENORMAL_FIX_RIGHT; // right m[i] = (l[i] + r[i]) * 0.5f; s[i] = (l[i] - r[i]) * 0.5f; } break; } } return ReadSamples; } // read WAVE header static unsigned short Read16 ( FILE* fp ) { unsigned char buff [2]; if (fread ( buff, 1, 2, fp ) != 2 ) return -1; return buff[0] | (buff[1] << 8); } static unsigned long Read32 ( FILE* fp ) { unsigned char buff [4]; if ( fread ( buff, 1, 4, fp ) != 4 ) return -1; return (buff[0] | (buff[1] << 8)) | ((unsigned long)(buff[2] | (buff[3] << 8)) << 16); } int Read_WAV_Header ( wave_t* type ) { int bytealign; FILE* fp = type->fp; if ( type->raw ) return 0; fseek ( fp, 0, SEEK_SET ); if ( Read32 (fp) != 0x46464952 ) { // 4 Byte: check for "RIFF" stderr_printf ( Read32(fp) == -1 ? " ERROR: Empty file or no data from coprocess!\n\n" : " ERROR: 'RIFF' not found in WAVE header!\n\n"); return -1; } Read32 (fp); // 4 Byte: chunk size (ignored) if ( Read32 (fp) != 0x45564157 ) { // 4 Byte: check for "WAVE" stderr_printf ( " ERROR: 'WAVE' not found in WAVE header!\n\n"); return -1; } if ( Read32 (fp) != 0x20746D66 ) { // 4 Byte: check for "fmt " stderr_printf ( " ERROR: 'fmt ' not found in WAVE header!\n\n"); return -1; } Read32 (fp); // 4 Byte: read chunk-size (ignored) if ( Read16 (fp) != 0x0001 ) { // 2 Byte: check for linear PCM stderr_printf ( " ERROR: WAVE file has no linear PCM format!\n\n"); return -1; } type -> Channels = Read16 (fp); // 2 Byte: read no. of channels type -> SampleFreq = Read32 (fp); // 4 Byte: read sampling frequency Read32 (fp); // 4 Byte: read avg. blocksize (fs*channels*bytepersample) bytealign = Read16 (fp); // 2 Byte: read byte-alignment (channels*bytepersample) type->BitsPerSample = Read16 (fp); // 2 Byte: read bits per sample type->BytesPerSample= (type->BitsPerSample + 7) / 8; while ( 1 ) { // search for "data" if ( feof (fp) ) return -1; if ( Read16 (fp) != 0x6164 ) continue; if ( Read16 (fp) == 0x6174 ) break; } type->PCMBytes = Read32 (fp); // 4 Byte: no. of byte in file if ( feof (fp) ) return -1; // finally calculate number of samples if (type->PCMBytes >= 0xFFFFFF00 || type->PCMBytes == 0 || (mpc_uint32_t)type->PCMBytes % (type -> Channels * type->BytesPerSample) != 0) { type->PCMSamples = 36000000 * type->SampleFreq; } else { type->PCMSamples = type->PCMBytes / bytealign; } type->PCMOffset = ftell (fp); return 0; } #ifdef _WIN32 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #ifndef __MINGW32__ #include #endif #include #include #define NBLK 383 // 10 sec of audio typedef struct { int active; char* data; size_t datalen; WAVEHDR hdr; } oblk_t; static HWAVEIN Input_WAVHandle; static HWAVEOUT Output_WAVHandle; static size_t BufferBytes; static WAVEHDR whi [NBLK]; static char* data [NBLK]; static oblk_t array [NBLK]; static unsigned int NextInputIndex; static unsigned int NextOutputIndex; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// int init_in ( const int SampleCount, const int SampleFreq, const int Channels, const int BitsPerSample ) { WAVEFORMATEX pwf; MMRESULT r; int i; pwf.wFormatTag = WAVE_FORMAT_PCM; pwf.nChannels = Channels; pwf.nSamplesPerSec = SampleFreq; pwf.nAvgBytesPerSec = SampleFreq * Channels * ((BitsPerSample + 7) / 8); pwf.nBlockAlign = Channels * ((BitsPerSample + 7) / 8); pwf.wBitsPerSample = BitsPerSample; pwf.cbSize = 0; r = waveInOpen ( &Input_WAVHandle, WAVE_MAPPER, &pwf, 0, 0, CALLBACK_EVENT ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInOpen failed: "); switch (r) { case MMSYSERR_ALLOCATED: fprintf ( stderr, "resource already allocated\n" ); break; case MMSYSERR_INVALPARAM: fprintf ( stderr, "invalid Params\n" ); break; case MMSYSERR_BADDEVICEID: fprintf ( stderr, "device identifier out of range\n" ); break; case MMSYSERR_NODRIVER: fprintf ( stderr, "no device driver present\n" ); break; case MMSYSERR_NOMEM: fprintf ( stderr, "unable to allocate or lock memory\n" ); break; case WAVERR_BADFORMAT: fprintf ( stderr, "attempted to open with an unsupported waveform-audio format\n" ); break; case WAVERR_SYNC: fprintf ( stderr, "device is synchronous but waveOutOpen was\n" ); break; default: fprintf ( stderr, "unknown error code: %#X\n", r ); break; } return -1; } BufferBytes = SampleCount * Channels * ((BitsPerSample + 7) / 8); for ( i = 0; i < NBLK; i++ ) { whi [i].lpData = data [i] = malloc (BufferBytes); whi [i].dwBufferLength = BufferBytes; whi [i].dwFlags = 0; whi [i].dwLoops = 0; r = waveInPrepareHeader ( Input_WAVHandle, whi + i, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInPrepareHeader (%u) failed\n", i ); return -1; } r = waveInAddBuffer ( Input_WAVHandle, whi + i, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInAddBuffer (%u) failed\n", i ); return -1; } } NextInputIndex = 0; waveInStart (Input_WAVHandle); return 0; } size_t get_in ( void* DataPtr ) { MMRESULT r; size_t Bytes; if ( whi [NextInputIndex].dwFlags & WHDR_DONE ) { Bytes = whi [NextInputIndex].dwBytesRecorded; memcpy ( DataPtr, data [NextInputIndex], Bytes ); r = waveInUnprepareHeader ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInUnprepareHeader (%d) failed\n", NextInputIndex ); return -1; } whi [NextInputIndex].lpData = data [NextInputIndex]; whi [NextInputIndex].dwBufferLength = BufferBytes; whi [NextInputIndex].dwFlags = 0; whi [NextInputIndex].dwLoops = 0; r = waveInPrepareHeader ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInPrepareHeader (%d) failed\n", NextInputIndex ); return -1; } r = waveInAddBuffer ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInAddBuffer (%d) failed\n", NextInputIndex ); return -1; } NextInputIndex = (NextInputIndex + 1) % NBLK; return Bytes; } return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// int init_out ( const int SampleCount, const int SampleFreq, const int Channels, const int BitsPerSample ) { WAVEFORMATEX pwf; MMRESULT r; int i; pwf.wFormatTag = WAVE_FORMAT_PCM; pwf.nChannels = Channels; pwf.nSamplesPerSec = SampleFreq; pwf.nAvgBytesPerSec = SampleFreq * Channels * ((BitsPerSample + 7) / 8); pwf.nBlockAlign = Channels * ((BitsPerSample + 7) / 8); pwf.wBitsPerSample = BitsPerSample; pwf.cbSize = 0; r = waveOutOpen ( &Output_WAVHandle, WAVE_MAPPER, &pwf, 0, 0, CALLBACK_EVENT ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutOpen failed\n" ); switch (r) { case MMSYSERR_ALLOCATED: fprintf ( stderr, "resource already allocated\n" ); break; case MMSYSERR_INVALPARAM: fprintf ( stderr, "invalid Params\n" ); break; case MMSYSERR_BADDEVICEID: fprintf ( stderr, "device identifier out of range\n" ); break; case MMSYSERR_NODRIVER: fprintf ( stderr, "no device driver present\n" ); break; case MMSYSERR_NOMEM: fprintf ( stderr, "unable to allocate or lock memory\n" ); break; case WAVERR_BADFORMAT: fprintf ( stderr, "attempted to open with an unsupported waveform-audio format\n" ); break; case WAVERR_SYNC: fprintf ( stderr, "device is synchronous but waveOutOpen was\n" ); break; default: fprintf ( stderr, "unknown error code: %#X\n", r ); break; } return -1; } BufferBytes = SampleCount * Channels * ((BitsPerSample + 7) / 8); for ( i = 0; i < NBLK; i++ ) { array [i].active = 0; array [i].data = malloc (BufferBytes); } NextOutputIndex = 0; return 0; } int put_out ( const void* DataPtr, const size_t Bytes ) { MMRESULT r; int i = NextOutputIndex; if ( array [i].active ) while ( ! (array [i].hdr.dwFlags & WHDR_DONE) ) Sleep (26); r = waveOutUnprepareHeader ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutUnprepareHeader (%d) failed\n", i ); return -1; } array [i].active = 1; array [i].hdr.lpData = array [i].data; array [i].hdr.dwBufferLength = Bytes; array [i].hdr.dwFlags = 0; array [i].hdr.dwLoops = 0; memcpy ( array [i].data, DataPtr, Bytes ); r = waveOutPrepareHeader ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutPrepareHeader (%d) failed\n", i ); return -1; } r = waveOutWrite ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutAddBuffer (%d) failed\n", i ); return -1; } NextInputIndex = (NextInputIndex + 1) % NBLK; return Bytes; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endif /* end of wave_in.c */ musepack_src_r495/mpcenc/pipeopen.c0000664000000000000000000001161010545213137016250 0ustar rootroot/* * Opens a communication channel to another program using unnamed pipe mechanism and stdin/stdout. * * (C) Frank Klemm 2001,02. All rights reserved. * * Principles: * * History: * 2001 created * 2002 * * Global functions: * - pipeopen * * TODO: * - */ #include #include #include "mpcenc.h" /* * */ static int EscapeProgramPathName ( const char* longprogname, char* escaped, size_t len ) { int ret = 0; #ifdef _WIN32 ret = GetShortPathName ( longprogname, escaped, len ); #else if ( strlen (longprogname) <= len-3 ) ret = sprintf ( escaped, "\"%s\"", longprogname ); // Note that this only helps against spaces and some similar things in the file name, not against all strange stuff #endif if ( ret <= 0 || ret >= (int)len ) { } return ret; } /* * */ static FILE* OpenPipeWhenBinaryExist ( const char* path, size_t pathlen, const char* executable_filename, const char* command_line ) { char filename [4096]; char cmdline [4096]; char* p = filename; FILE* fp; for ( ; *path && pathlen--; path++ ) if ( *path != '"' ) *p++ = *path; *p++ = PATH_SEP; strcpy ( p, executable_filename ); #ifdef DEBUG2 stderr_printf ("Test for file %s \n", filename ); #endif fp = fopen ( filename, "rb" ); if ( fp != NULL ) { fclose ( fp ); EscapeProgramPathName ( filename, cmdline, sizeof cmdline ); strcat ( cmdline, command_line ); fp = POPEN_READ_BINARY_OPEN ( cmdline ); #ifdef DEBUG2 stderr_printf ("Executed %s\n", cmdline ); #endif } return fp; } /* * */ static FILE* TracePathList ( const char* p, const char* executable_filename, const char* command_line ) { const char* nextsep; FILE* fp; while ( p != NULL && *p != '\0' ) { if ( (nextsep = strchr (p, ENVPATH_SEP)) == NULL ) { fp = OpenPipeWhenBinaryExist ( p, (size_t) -1, executable_filename, command_line ); p = NULL; } else { fp = OpenPipeWhenBinaryExist ( p, (size_t)(nextsep-p), executable_filename, command_line ); p = nextsep + 1; } if ( fp != NULL ) return fp; } return NULL; } /* * Executes command line given by command. * The command must be found in some predefined paths or in the ${PATH} aka %PATH% * The char # in command is replaced by the contents * of filename. Special characters are escaped. */ FILE* pipeopen ( const char* command, const char* filename ) { static const char pathlist [] = #ifdef _WIN32 "."; #else "/usr/bin:/usr/local/bin:/opt/mpp:."; #endif char command_line [4096]; // -o - bar.pac char executable_filename [4096]; // foo.exe char* p; const char* q; FILE* fp; // does the source file exist and is readble? if ( (fp = fopen (filename, "rb")) == NULL ) { stderr_printf ("file '%s' not found.\n", filename ); return NULL; } fclose (fp); // extract executable name from the 'command' to executable_filename, append executable extention p = executable_filename; for ( ; *command != ' ' && *command != '\0'; command++ ) *p++ = *command; strcpy ( p, EXE_EXT ); // Copy 'command' to 'command_line' replacing '#' by filename p = command_line; for ( ; *command != '\0'; command++ ) { if ( *command != '#' ) { *p++ = *command; } else { q = filename; if (*q == '-') { *p++ = '.'; *p++ = PATH_SEP; } #ifdef _WIN32 // Windows secure Way to "escape" *p++ = '"'; while (*q) *p++ = *q++; *p++ = '"'; #else // Unix secure Way to \e\s\c\a\p\e while (*q) { if ( !isalnum(*q) && *q != '.' && *q != '-' && *q != '_' && *q != '/' ) *p++ = '\\'; *p++ = *q++; } #endif } } *p = '\0'; // Try the several built-in paths to find binary fp = TracePathList ( pathlist , executable_filename, command_line ); if ( fp != NULL ) return fp; // Try the PATH settings to find binary (Why we must search for the executable in all PATH settings? --> popen itself do not return useful information) fp = TracePathList ( getenv ("PATH"), executable_filename, command_line ); if ( fp != NULL ) return fp; #ifdef DEBUG2 stderr_printf ("Nothing found to execute.\n" ); #endif return NULL; } /* end of pipeopen.c */ musepack_src_r495/mpcdec/0000775000000000000000000000000012765302353014261 5ustar rootrootmusepack_src_r495/mpcdec/mpcdec.c0000664000000000000000000002336511737413610015666 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "../libmpcdec/decoder.h" #include "../libmpcdec/internal.h" #include #include #include #ifdef _MSC_VER #include #endif #ifdef WIN32 # include # include # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) #endif #define MPCDEC_MAJOR 1 #define MPCDEC_MINOR 0 #define MPCDEC_BUILD 0 #define _cat(a,b,c) #a"."#b"."#c #define cat(a,b,c) _cat(a,b,c) #define MPCDEC_VERSION cat(MPCDEC_MAJOR,MPCDEC_MINOR,MPCDEC_BUILD) const char About [] = "mpcdec - Musepack (MPC) decoder v" MPCDEC_VERSION " (C) 2006-2009 MDT\nBuilt " __DATE__ " " __TIME__ "\n"; t_wav_uint32 mpc_wav_output_write(void* p_user_data, void const* p_buffer, t_wav_uint32 p_bytes) { FILE* p_handle = (FILE*) p_user_data; return (t_wav_uint32) fwrite(p_buffer, 1, p_bytes, p_handle); } t_wav_uint32 mpc_wav_output_seek(void* p_user_data, t_wav_uint32 p_position) { FILE* p_handle = (FILE*) p_user_data; return (t_wav_uint32) !fseek(p_handle, p_position, SEEK_SET); } static short bswap_16(short in) { return (in << 8) | ((in >> 8) & 0xFF); } #ifdef MPC_FIXED_POINT static int raw_output_int16(FILE * file, short * buff, int cnt, mpc_bool_t reverse_endian) { int i; for (i = 0; i < cnt; i++) { short out = buff[i]; if (reverse_endian) out = bswap_16(out); if (fwrite(&out, sizeof(out), 1, file) != 1) return -1; } return 0; } #else static int raw_output_float32(FILE * file, float * buff, int cnt, mpc_bool_t reverse_endian) { int i; for (i = 0; i < cnt; i++) { int tmp = nearbyintf(buff[i] * (1 << 15)); short out; if (tmp > ((1 << 15) - 1)) tmp = ((1 << 15) - 1); if (tmp < -(1 << 15)) tmp = -(1 << 15); if (reverse_endian) tmp = bswap_16((short) tmp); out = (short)tmp; if (fwrite(&out, sizeof(out), 1, file) != 1) return -1; } return 0; } #endif static void print_info(mpc_streaminfo * info, char * filename) { int time = (int) mpc_streaminfo_get_length(info); int minutes = time / 60; int seconds = time % 60; fprintf(stderr, "file: %s\n", filename); fprintf(stderr, "stream version %d\n", info->stream_version); fprintf(stderr, "encoder: %s\n", info->encoder); fprintf(stderr, "profile: %s (q=%0.2f)\n", info->profile_name, info->profile - 5); fprintf(stderr, "PNS: %s\n", info->pns == 0xFF ? "unknow" : info->pns ? "on" : "off"); fprintf(stderr, "mid/side stereo: %s\n", info->ms ? "on" : "off"); fprintf(stderr, "gapless: %s\n", info->is_true_gapless ? "on" : "off"); fprintf(stderr, "average bitrate: %6.1f kbps\n", info->average_bitrate * 1.e-3); fprintf(stderr, "samplerate: %d Hz\n", info->sample_freq); fprintf(stderr, "channels: %d\n", info->channels); fprintf(stderr, "length: %d:%.2d (%u samples)\n", minutes, seconds, (mpc_uint32_t)mpc_streaminfo_get_length_samples(info)); fprintf(stderr, "file size: %d Bytes\n", info->total_file_length); fprintf(stderr, "track peak: %2.2f dB\n", info->peak_title / 256.f); fprintf(stderr, "track gain: %2.2f dB / %2.2f dB\n", info->gain_title / 256.f, info->gain_title == 0 ? 0 : 64.82f - info->gain_title / 256.f); fprintf(stderr, "album peak: %2.2f dB\n", info->peak_album / 256.f); fprintf(stderr, "album gain: %2.2f dB / %2.2f dB\n", info->gain_album / 256.f, info->gain_album == 0 ? 0 : 64.82f - info->gain_album / 256.f); fprintf(stderr, "\n"); } static void usage(const char *exename) { fprintf(stderr, "Usage: %s [-i] [-h] []\n" "-i : print file information on stdout\n" "-c : check the file for stream errors\n" " (doesn't fully decode, outfile will be ignored)\n" "-r : output raw data (left/right) in machine native endian\n" "-e : reverse raw data endianness\n" "-h : print this help\n" "you can use stdin and stdout as resp. and\n" " replacing the file name by \"-\"\n", exename); } int main(int argc, char **argv) { mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_status err; mpc_bool_t info = MPC_FALSE, is_wav_output = MPC_FALSE, check = MPC_FALSE; mpc_bool_t is_raw_output = MPC_FALSE, reverse_endian = MPC_FALSE; MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; clock_t begin, end, sum; int total_samples; t_wav_output_file wav_output; t_wav_output_file_callback wavo_fc; int c; fprintf(stderr, About); while ((c = getopt(argc , argv, "ihcre")) != -1) { switch (c) { case 'i': info = MPC_TRUE; break; case 'c': check = MPC_TRUE; break; case 'r': is_raw_output = MPC_TRUE; break; case 'e': reverse_endian = MPC_TRUE; break; case 'h': usage(argv[0]); return 0; } } if(2 < argc - optind || argc - optind < 1) { usage(argv[0]); return 0; } if (strcmp(argv[optind], "-") == 0) { SET_BINARY_MODE(stdin); err = mpc_reader_init_stdio_stream(& reader, stdin); } else err = mpc_reader_init_stdio(&reader, argv[optind]); if(err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if(!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); if (info == MPC_TRUE) { print_info(&si, argv[optind]); mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); return 0; } if (check) { is_raw_output = MPC_FALSE; } else if (argc - optind > 1 && is_raw_output == MPC_FALSE) { is_wav_output = MPC_TRUE; }; if (is_wav_output || is_raw_output) { memset(&wav_output, 0, sizeof wav_output); wavo_fc.m_seek = mpc_wav_output_seek; wavo_fc.m_write = mpc_wav_output_write; if (strcmp(argv[optind + 1], "-") == 0 || (is_raw_output && argc - optind <= 1)) { SET_BINARY_MODE(stdout); wavo_fc.m_user_data = stdout; } else wavo_fc.m_user_data = fopen(argv[optind + 1], "wb"); if(!wavo_fc.m_user_data) return !MPC_STATUS_OK; if (is_wav_output) { if (!waveformat_output_open(&wav_output, wavo_fc, si.channels, 16, 0, si.sample_freq, (t_wav_uint32) si.samples * si.channels)) return !MPC_STATUS_OK; } } sum = total_samples = 0; while(MPC_TRUE) { mpc_frame_info frame; frame.buffer = sample_buffer; if (check) demux->d->samples_to_skip = MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY; begin = clock(); err = mpc_demux_decode(demux, &frame); end = clock(); if(frame.bits == -1) break; total_samples += frame.samples; sum += end - begin; if (is_wav_output || is_raw_output) { #ifdef MPC_FIXED_POINT mpc_int16_t tmp_buff[MPC_DECODER_BUFFER_LENGTH]; int i; for( i = 0; i < MPC_DECODER_BUFFER_LENGTH; i++) { int tmp = sample_buffer[i] >> MPC_FIXED_POINT_FRACTPART; if (tmp > ((1 << 15) - 1)) tmp = ((1 << 15) - 1); if (tmp < -(1 << 15)) tmp = -(1 << 15); tmp_buff[i] = tmp; } #endif if (is_wav_output) { #ifdef MPC_FIXED_POINT if(waveformat_output_process_int16(&wav_output, tmp_buff, frame.samples * si.channels) < 0) #else if(waveformat_output_process_float32(&wav_output, sample_buffer, frame.samples * si.channels) < 0) #endif break; } if (is_raw_output) { #ifdef MPC_FIXED_POINT if (raw_output_int16(wavo_fc.m_user_data, tmp_buff, frame.samples * si.channels, reverse_endian) < 0) #else if (raw_output_float32(wavo_fc.m_user_data, sample_buffer, frame.samples * si.channels, reverse_endian) < 0) #endif break; } } } if (err != MPC_STATUS_OK) fprintf(stderr, "An error occured while decoding\n"); else if (check) fprintf(stderr, "No error found\n"); if (!check) { fprintf(stderr, "%u samples ", total_samples); if (sum <= 0) sum = 1; total_samples = (mpc_uint32_t) ((mpc_uint64_t) total_samples * CLOCKS_PER_SEC * 100 / ((mpc_uint64_t)si.sample_freq * sum)); fprintf(stderr, "decoded in %u ms (%u.%02ux)\n", (unsigned int) (sum * 1000 / CLOCKS_PER_SEC), total_samples / 100, total_samples % 100 ); } mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); if(is_wav_output) { waveformat_output_close(&wav_output); fclose(wav_output.m_callback.m_user_data); } #ifdef _MSC_VER assert(_CrtCheckMemory()); _CrtDumpMemoryLeaks(); #endif return err; } musepack_src_r495/mpcdec/Makefile.am0000664000000000000000000000051411234134160016302 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/libwavformat -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO bin_PROGRAMS = mpcdec mpcdec_SOURCES = mpcdec.c mpcdec_LDADD = -lm \ $(top_builddir)/libmpcdec/libmpcdec.la \ $(top_builddir)/libwavformat/libwavformat.a musepack_src_r495/mpcdec/CMakeLists.txt0000664000000000000000000000145111700102077017007 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/include) include_directories(${libmpc_SOURCE_DIR}/libwavformat) link_directories(${libmpc_BINARY_DIR}/libwavformat) include_directories(${libmpc_SOURCE_DIR}/libmpcdec) link_directories(${libmpc_BINARY_DIR}/libmpcdec) if(MSVC) include_directories(${libmpc_SOURCE_DIR}/win32) add_executable(mpcdec_cmd mpcdec.c ${libmpc_SOURCE_DIR}/win32/attgetopt) endif(MSVC) add_executable(mpcdec_cmd mpcdec.c) target_link_libraries(mpcdec_cmd wavformat_static) if(SHARED) target_link_libraries(mpcdec_cmd mpcdec) else(SHARED) target_link_libraries(mpcdec_cmd mpcdec_static) endif(SHARED) if(NOT MSVC) target_link_libraries(mpcdec_cmd m) endif(NOT MSVC) SET_TARGET_PROPERTIES(mpcdec_cmd PROPERTIES OUTPUT_NAME "mpcdec") install(TARGETS mpcdec_cmd RUNTIME DESTINATION bin) musepack_src_r495/bin/0000775000000000000000000000000012765302354013577 5ustar rootrootmusepack_src_r495/libmpc.kdevelop0000664000000000000000000002070410772206315016027 0ustar rootroot Nicolas Botti 0.1 KDevAutoProject C C Code . false libmpc mpcchap/mpcchap optimized true executable ~/test1.mpc ~/test1-conv.mpc / true /home/nico/test.mpc /home/nico/chaps.ini /home/nico/src/musepack/libmpc/optimized/./mpcchap /home/nico/src/musepack/libmpc/optimized/./mpcchap optimized kdevgccoptions kdevgppoptions kdevg77options -O3 -fomit-frame-pointer -pipe -Wall -m3dnow -msse -ffast-math -I/home/nico/src/musepack/libreplaygain/include -L/home/nico/src/musepack/libreplaygain/src --enable-debug=full debug kdevgccoptions kdevgppoptions kdevg77options -O0 -Wall -g3 -I/home/nico/src/musepack/libreplaygain/include -L/home/nico/src/musepack/libreplaygain/src true 1 false 0 ada ada_bugs_gcc bash bash_bugs clanlib w3c-dom-level2-html fortran_bugs_gcc gnome1 gnustep gtk gtk_bugs haskell haskell_bugs_ghc java_bugs_gcc java_bugs_sun kde2book libstdc++ opengl pascal_bugs_fp php php_bugs perl perl_bugs python python_bugs qt-kdev3 ruby ruby_bugs sdl stl w3c-svg sw w3c-uaag10 wxwidgets_bugs Guide to the Qt Translation Tools Qt Assistant Manual Qt Designer Manual Qt Reference Documentation qmake User Guide KDE Libraries (Doxygen) false false *.o,*.lo,CVS false Doxygen Documentation Collection mpcenc.tag mpcenc mpcenc Mpcenc MPCENC Nicolas Botti GPL COPYING -I/usr/include -lm 0.1 2006 /home/nico/src/musepack/svn/mpcenc-zorg/mpcenc true true true false true true true 250 400 250 false 0 true true false std=_GLIBCXX_STD;__gnu_cxx=std true false false false false true true false .; set m_,_ theValue true true false 3 3 EmbeddedKDevDesigner false true Vertical .h .cpp "/home/nico/test.wav" "/home/nico/test2.wav" libtool true false false false false true 10 musepack_src_r495/mpc2sv8/0000775000000000000000000000000012765302354014331 5ustar rootrootmusepack_src_r495/mpc2sv8/mpc2sv8.c0000664000000000000000000001762212645277514016015 0ustar rootroot/* Copyright (c) 2007-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "../libmpcdec/decoder.h" #include "../libmpcdec/internal.h" #include "../libmpcenc/libmpcenc.h" #define TMP_BUF_SIZE 128 #define MPC2SV8_MAJOR 1 #define MPC2SV8_MINOR 0 #define MPC2SV8_BUILD 0 #define _cat(a,b,c) #a"."#b"."#c #define cat(a,b,c) _cat(a,b,c) #define MPC2SV8_VERSION cat(MPC2SV8_MAJOR,MPC2SV8_MINOR,MPC2SV8_BUILD) const char About [] = "mpc2sv8 - Musepack (MPC) sv7 to sv8 converter v" MPC2SV8_VERSION " (C) 2007-2009 MDT\nBuilt " __DATE__ " " __TIME__ "\n"; static void datacpy(mpc_decoder * d, mpc_encoder_t * e) { static const int offset[] = { 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; int i, j; memcpy(e->SCF_Index_L, d->SCF_Index_L, sizeof(e->SCF_Index_L)); memcpy(e->SCF_Index_R, d->SCF_Index_R, sizeof(e->SCF_Index_R)); memcpy(e->Res_L, d->Res_L, sizeof(e->Res_L)); memcpy(e->Res_R, d->Res_R, sizeof(e->Res_R)); memcpy(e->MS_Flag, d->MS_Flag, sizeof(e->MS_Flag)); for( i = 0; i <= d->max_band; i++){ mpc_int16_t * q_d = d->Q[i].L, * q_e = e->Q[i].L, Res = d->Res_L[i]; if (Res > 0) for( j = 0; j < 36; j++) q_e[j] = q_d[j] + offset[Res]; q_d = d->Q[i].R, q_e = e->Q[i].R, Res = d->Res_R[i]; if (Res > 0) for( j = 0; j < 36; j++) q_e[j] = q_d[j] + offset[Res]; } } static void usage(const char *exename) { printf("Usage:\n" "%s \n" "or\n" "%s [ ... ] \n", exename, exename); } int convert(char * sv7file, char * sv8file) { mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_status err; mpc_encoder_t e; mpc_uint_t si_size; mpc_size_t stream_size; size_t r_size; FILE * in_file; char buf[TMP_BUF_SIZE]; err = mpc_reader_init_stdio(&reader, sv7file); if(err < 0) return err; demux = mpc_demux_init(&reader); if(!demux) { err = !MPC_STATUS_OK; goto READER_ERR; } mpc_demux_get_info(demux, &si); if (si.stream_version >= 8) { fprintf(stderr, "Error : the file \"%s\" is already a sv8 file\n", sv7file); err = !MPC_STATUS_OK; goto DEMUX_ERR; } mpc_encoder_init(&e, si.samples, 6, 1); e.outputFile = fopen( sv8file, "w+b" ); e.MS_Channelmode = si.ms; // copy begining of file in_file = fopen(sv7file, "rb"); if(in_file == 0) { err = !MPC_STATUS_OK; goto OUT_FILE_ERR; } r_size = si.header_position; while(r_size) { size_t tmp_size = fread(buf, 1, mini(TMP_BUF_SIZE, r_size), in_file); if (fwrite(buf, 1, tmp_size, e.outputFile) != tmp_size) { fprintf(stderr, "Error writing to target file : \"%s\"\n", sv8file); err = MPC_STATUS_FAIL; goto IN_FILE_ERR; } r_size -= tmp_size; } // stream conversion e.seek_ref = ftell(e.outputFile); writeMagic(&e); writeStreamInfo( &e, si.max_band, si.ms > 0, si.samples, 0, si.sample_freq, si.channels); si_size = writeBlock(&e, "SH", MPC_TRUE, 0); writeGainInfo(&e, si.gain_title, si.peak_title, si.gain_album, si.peak_album); si_size = writeBlock(&e, "RG", MPC_FALSE, 0); writeEncoderInfo(&e, si.profile, si.pns, si.encoder_version / 100, si.encoder_version % 100, 0); writeBlock(&e, "EI", MPC_FALSE, 0); e.seek_ptr = ftell(e.outputFile); writeBits (&e, 0, 16); writeBits (&e, 0, 24); // jump 40 bits for seek table pointer writeBlock(&e, "SO", MPC_FALSE, 0); // reserve space for seek offset while(MPC_TRUE) { mpc_frame_info frame; demux->d->samples_to_skip = MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY; err = mpc_demux_decode_inner(demux, &frame); if (MPC_IS_FAILURE(err) || frame.bits == -1) break; datacpy(demux->d, &e); writeBitstream_SV8 ( &e, si.max_band); // write SV8-Bitstream } if (err != MPC_STATUS_OK) fprintf(stderr, "An error occured while decoding, this file may be corrupted\n"); // write the last incomplete block if (e.framesInBlock != 0) { if ((e.block_cnt & ((1 << e.seek_pwr) - 1)) == 0) { e.seek_table[e.seek_pos] = ftell(e.outputFile); e.seek_pos++; } e.block_cnt++; writeBlock(&e, "AP", MPC_FALSE, 0); } writeSeekTable(&e); writeBlock(&e, "ST", MPC_FALSE, 0); // write seek table block writeBlock(&e, "SE", MPC_FALSE, 0); // write end of stream block if (demux->d->samples != si.samples) { fseek(e.outputFile, e.seek_ref + 4, SEEK_SET); writeStreamInfo( &e, si.max_band, si.ms > 0, demux->d->samples, 0, si.sample_freq, si.channels); writeBlock(&e, "SH", MPC_TRUE, si_size); fseek(e.outputFile, 0, SEEK_END); } // copy end of file stream_size = (((mpc_demux_pos(demux) + 7 - 20) >> 3) - si.header_position + 3) & ~3; fseek(in_file, si.header_position + stream_size, SEEK_SET); while((r_size = fread(buf, 1, TMP_BUF_SIZE, in_file))) { if (fwrite(buf, 1, r_size, e.outputFile) != r_size) { fprintf(stderr, "Error writing to target file"); break; } } IN_FILE_ERR: fclose ( in_file ); OUT_FILE_ERR: fclose ( e.outputFile ); mpc_encoder_exit(&e); DEMUX_ERR: mpc_demux_exit(demux); READER_ERR: mpc_reader_exit_stdio(&reader); return err; } mpc_bool_t is_dir(char * dir_path) { DIR * out_dir = opendir(dir_path); if (out_dir != 0) { closedir(out_dir); return MPC_TRUE; } return MPC_FALSE; } int main(int argc, char **argv) { int c, i; mpc_bool_t overwrite = MPC_FALSE, use_dir = MPC_FALSE; int ret = MPC_STATUS_OK; printf(About); while ((c = getopt(argc , argv, "oh")) != -1) { switch (c) { case 'o': overwrite = MPC_TRUE; break; case 'h': usage(argv[0]); return 0; } } use_dir = is_dir(argv[argc - 1]); if((argc - optind) < 2 || (use_dir == MPC_FALSE && (argc - optind) > 2)) { usage(argv[0]); return 0; } for (i = optind; i < argc - 1; i++) { char * in_file = argv[i]; char * out_file = argv[argc - 1]; if (use_dir == MPC_TRUE) { char * file_name = basename(in_file); out_file = malloc(strlen(file_name) + strlen(argv[argc - 1]) + 2); sprintf(out_file, "%s/%s", argv[argc - 1], file_name); } if (overwrite == MPC_FALSE) { FILE * test_file = fopen( out_file, "rb" ); if ( test_file != 0 ) { fprintf(stderr, "Error : output file \"%s\" already exists\n", out_file); fclose(test_file); continue; } } // FIXME : test if in and out files are the same ret = convert(in_file, out_file); if (use_dir == MPC_TRUE) free(out_file); } return ret; } musepack_src_r495/mpc2sv8/Makefile.am0000664000000000000000000000054311234134160016353 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif common_sources = ../common/crc32.c METASOURCES = AUTO bin_PROGRAMS = mpc2sv8 mpc2sv8_SOURCES = mpc2sv8.c $(common_sources) mpc2sv8_LDADD = -lm \ $(top_builddir)/libmpcdec/libmpcdec.la \ $(top_builddir)/libmpcenc/libmpcenc.a musepack_src_r495/mpc2sv8/CMakeLists.txt0000664000000000000000000000171511433773325017076 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/include) include_directories(${libmpc_SOURCE_DIR}/libmpcdec) link_directories(${libmpc_BINARY_DIR}/libmpcdec) include_directories(${libmpc_SOURCE_DIR}/libmpcenc) link_directories(${libmpc_BINARY_DIR}/libmpcenc) if(MSVC) include_directories(${libmpc_SOURCE_DIR}/win32) add_executable(mpc2sv8 mpc2sv8.c ${libmpc_SOURCE_DIR}/win32/attgetopt.c ${libmpc_SOURCE_DIR}/win32/basename.c ${libmpc_SOURCE_DIR}/win32/dirent.c) endif(MSVC) add_executable(mpc2sv8 mpc2sv8.c) if(SHARED) target_link_libraries(mpc2sv8 mpcdec) else(SHARED) target_link_libraries(mpc2sv8 mpcdec_static) endif(SHARED) target_link_libraries(mpc2sv8 mpcenc_static) if(WIN32) target_link_libraries(mpc2sv8 winmm) endif(WIN32) if(NOT MSVC) target_link_libraries(mpc2sv8 m) endif(NOT MSVC) if(CMAKE_SYSTEM_NAME STREQUAL OpenBSD) target_link_libraries(mpc2sv8 ossaudio) endif(CMAKE_SYSTEM_NAME STREQUAL OpenBSD) install(TARGETS mpc2sv8 RUNTIME DESTINATION bin) musepack_src_r495/CMakeLists.txt0000664000000000000000000000160712414307151015562 0ustar rootrootCMAKE_MINIMUM_REQUIRED(VERSION 2.4) cmake_policy(SET CMP0003 NEW) include(TestBigEndian) project(libmpc C) set(CMAKE_VERBOSE_MAKEFILE false) TEST_BIG_ENDIAN(MPC_ENDIANNESS) # Use the standard CMake flag to drive the shared object build. if(DEFINED BUILD_SHARED_LIBS AND NOT DEFINED SHARED) set(SHARED ${BUILD_SHARED_LIBS}) else() if(WIN32) option(SHARED "Use shared libmpcdec" OFF) else(WIN32) option(SHARED "Use shared libmpcdec" ON) endif(WIN32) endif() add_definitions(-DFAST_MATH -DCVD_FASTLOG) if(NOT MSVC) set(CMAKE_C_FLAGS "-O3 -Wall -fomit-frame-pointer -pipe") endif(NOT MSVC) add_subdirectory(libmpcdec) add_subdirectory(libmpcpsy) add_subdirectory(libmpcenc) add_subdirectory(libwavformat) add_subdirectory(mpcgain) add_subdirectory(mpcdec) add_subdirectory(mpcenc) add_subdirectory(mpc2sv8) add_subdirectory(mpccut) add_subdirectory(mpcchap) add_subdirectory(wavcmp) musepack_src_r495/libmpcenc/0000775000000000000000000000000012765302354014763 5ustar rootrootmusepack_src_r495/libmpcenc/Makefile.am0000664000000000000000000000041611234134160017004 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO noinst_LIBRARIES = libmpcenc.a libmpcenc_a_SOURCES = analy_filter.c bitstream.c encode_sv7.c huffsv7.c quant.c libmpcenc.h musepack_src_r495/libmpcenc/libmpcenc.h0000664000000000000000000001055312231315357017067 0ustar rootroot/* * Musepack audio compression * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #pragma once #include #include // FIXME : define this somewhere else #ifndef NULL #define NULL 0 #endif #define MPC_FRAME_LENGTH (36 * 32) #define MAX_FRAME_SIZE 4352 typedef struct { mpc_uint16_t Code; // >= 14 bit mpc_uint16_t Length; // >= 4 bit } Huffman_t; typedef struct { mpc_uint_t pos; // next free byte position in the buffer mpc_uint_t bitsCount; // number of used bits in bitsBuff mpc_uint64_t outputBits; // Counter for the number of written bits in the bitstream mpc_uint32_t bitsBuff; // bits buffer mpc_uint8_t * buffer; // Buffer for bitstream-file mpc_uint_t framesInBlock; // Number of frames in current block mpc_uint_t frames_per_block_pwr; // Number of frame in a block = 1 << frames_per_block_pwr // seeking mpc_uint32_t * seek_table; mpc_uint32_t seek_pos; /// current position in the seek table mpc_uint32_t seek_ref; /// reference position for the seek information mpc_uint32_t seek_ptr; /// position of the seek pointer block mpc_uint32_t seek_pwr; /// keep a seek table entry every 2^seek_pwr block mpc_uint32_t block_cnt; /// number of encoded blocks FILE * outputFile; // ouput file mpc_uint32_t MS_Channelmode; mpc_uint32_t Overflows; // = 0; // number of internal (filterbank) clippings mpc_uint32_t MaxBand; /// number of non zero bands in last frame mpc_int32_t SCF_Index_L [32] [3]; mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices mpc_int32_t SCF_Last_L [32]; mpc_int32_t SCF_Last_R [32]; // Last coded SCF value mpc_quantizer Q [32]; // holds quantized samples mpc_int32_t Res_L [32]; mpc_int32_t Res_R [32]; // holds the chosen quantizer for each subband mpc_bool_t DSCF_Flag_L [32]; mpc_bool_t DSCF_Flag_R [32]; // differential SCF used? mpc_bool_t MS_Flag[32]; // MS used? } mpc_encoder_t; void mpc_encoder_init ( mpc_encoder_t * e, mpc_uint64_t SamplesInWAVE, unsigned int FramesBlockPwr, unsigned int SeekDistance ); void mpc_encoder_exit ( mpc_encoder_t * e ); void writeStreamInfo ( mpc_encoder_t*e, const unsigned int MaxBand, const unsigned int MS_on, const unsigned int SamplesCount, const unsigned int SamplesSkip, const unsigned int SampleFreq, const unsigned int ChannelCount); void writeGainInfo ( mpc_encoder_t * e, unsigned short t_gain, unsigned short t_peak, unsigned short a_gain, unsigned short a_peak); void writeEncoderInfo ( mpc_encoder_t * e, const float profile, const int PNS_on, const int version_major, const int version_minor, const int version_build ); mpc_uint32_t writeBlock ( mpc_encoder_t *, const char *, const mpc_bool_t, mpc_uint32_t); void writeMagic (mpc_encoder_t * e); void emptyBits(mpc_encoder_t * e); /// maximum number of output bits is 31 ! static mpc_inline void writeBits (mpc_encoder_t * e, mpc_uint32_t input, unsigned int bits ) { e->outputBits += bits; if (e->bitsCount + bits > sizeof(e->bitsBuff) * 8) { int tmp = (sizeof(e->bitsBuff) * 8 - e->bitsCount); bits -= tmp; e->bitsBuff = (e->bitsBuff << tmp) | (input >> bits); e->bitsCount = sizeof(e->bitsBuff) * 8; emptyBits(e); input &= (1 << bits) - 1; } e->bitsBuff = (e->bitsBuff << bits) | input; e->bitsCount += bits; } void writeSeekTable (mpc_encoder_t * e); void writeBitstream_SV8 ( mpc_encoder_t*, int); unsigned int encodeSize(mpc_uint64_t, char *, mpc_bool_t); void encodeEnum(mpc_encoder_t * e, const mpc_uint32_t bits, const mpc_uint_t N); void encodeLog(mpc_encoder_t * e, mpc_uint32_t value, mpc_uint32_t max); musepack_src_r495/libmpcenc/huffsv7.c0000664000000000000000000003304412231315357016516 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "libmpcenc.h" const Huffman_t HuffBands [33] = { {1, 1}, {1, 3}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {4, 8}, {4, 9}, {5, 10}, {6, 11}, {1, 12}, {2, 12}, {3, 12}, {0, 13}, {4, 12}, {5, 12}, {6, 12}, {7, 12}, {8, 12}, {1, 13}, {9, 12}, {10, 12}, {11, 12}, {7, 11}, {8, 11}, {9, 11}, {6, 10}, {7, 10}, {5, 9}, {5, 8}, {3, 6}, {3, 5}, {1, 2} }; const Huffman_t HuffRes [2] [17] = { { {1, 1}, {1, 2}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {1, 15}, {0, 16}, {1, 16}, {1, 8}, {1, 3} }, { {1, 2}, {2, 2}, {1, 3}, {1, 5}, {1, 7}, {1, 8}, {1, 10}, {1, 12}, {0, 14}, {1, 14}, {2, 14}, {3, 14}, {1, 11}, {1, 9}, {1, 6}, {1, 4}, {3, 2} } }; const Huffman_t HuffSCFI_1 [4] = { {0, 3}, {1, 3}, {1, 1}, {1, 2} }; const Huffman_t HuffSCFI_2 [16] = { {1, 6}, {0, 7}, {2, 6}, {3, 6}, {1, 7}, {3, 5}, {4, 5}, {5, 5}, {4, 6}, {6, 5}, {2, 2}, {2, 3}, {5, 6}, {7, 5}, {3, 3}, {3, 2} }; const Huffman_t HuffDSCF_1 [64] = { {3, 12}, {4, 12}, {5, 12}, {4, 11}, {5, 11}, {6, 11}, {5, 10}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {6, 6}, {7, 6}, {5, 5}, {4, 4}, {5, 4}, {6, 5}, {6, 4}, {7, 4}, {10, 10}, {8, 4}, {5, 3}, {6, 3}, {7, 3}, {9, 4}, {7, 5}, {8, 6}, {9, 6}, {11, 7}, {11, 8}, {12, 8}, {13, 8}, {11, 9}, {12, 9}, {13, 9}, {11, 10}, {12, 10}, {13, 10}, {7, 11}, {8, 11}, {9, 11}, {6, 12}, {7, 12}, {3, 13}, {4, 13}, {5, 13}, {0, 14}, {1, 14}, {2, 14}, {3, 14}, {4, 14}, {5, 14} }; const Huffman_t HuffDSCF_2 [65] = { {0, 15}, {3, 14}, {4, 14}, {4, 13}, {5, 13}, {6, 13}, {5, 12}, {6, 12}, {7, 12}, {8, 12}, {7, 11}, {8, 11}, {9, 11}, {10, 11}, {7, 10}, {8, 10}, {9, 10}, {10, 10}, {7, 9}, {8, 9}, {9, 9}, {6, 8}, {7, 8}, {5, 7}, {6, 7}, {4, 6}, {3, 5}, {3, 4}, {4, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {5, 4}, {4, 5}, {5, 5}, {5, 6}, {7, 7}, {8, 8}, {9, 8}, {10, 9}, {11, 9}, {11, 10}, {12, 10}, {13, 10}, {11, 11}, {12, 11}, {13, 11}, {9, 12}, {10, 12}, {11, 12}, {12, 12}, {7, 13}, {8, 13}, {9, 13}, {5, 14}, {6, 14}, {7, 14}, {1, 15}, {2, 15}, {3, 15}, {4, 15}, {5, 15}, {13, 12} }; static const Huffman_t HuffQ1 [19] = { {1, 6}, {1, 4}, {2, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {3, 4}, {4, 4}, {5, 4}, {1, 5}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {0, 12}, {1, 12} }; static const Huffman_t HuffQ2 [2] [5*5*5] = { { {2, 12}, {3, 11}, {15, 10}, {4, 11}, {0, 13}, {5, 11}, {12, 9}, {18, 8}, {13, 9}, {6, 11}, {7, 11}, {19, 8}, {21, 7}, {20, 8}, {8, 11}, {9, 11}, {14, 9}, {21, 8}, {15, 9}, {10, 11}, {3, 12}, {11, 11}, {16, 10}, {12, 11}, {1, 13}, {13, 11}, {16, 9}, {22, 8}, {17, 9}, {14, 11}, {18, 9}, {15, 6}, {16, 6}, {22, 7}, {19, 9}, {23, 8}, {17, 6}, {8, 4}, {18, 6}, {24, 8}, {20, 9}, {19, 6}, {20, 6}, {23, 7}, {21, 9}, {15, 11}, {22, 9}, {25, 8}, {23, 9}, {16, 11}, {17, 10}, {26, 8}, {24, 7}, {27, 8}, {18, 10}, {28, 8}, {21, 6}, {9, 4}, {22, 6}, {29, 8}, {25, 7}, {10, 4}, {7, 3}, {11, 4}, {26, 7}, {30, 8}, {23, 6}, {12, 4}, {24, 6}, {31, 8}, {19, 10}, {32, 8}, {27, 7}, {33, 8}, {20, 10}, {17, 11}, {24, 9}, {34, 8}, {25, 9}, {18, 11}, {26, 9}, {25, 6}, {26, 6}, {27, 6}, {27, 9}, {35, 8}, {28, 6}, {13, 4}, {29, 6}, {36, 8}, {28, 9}, {28, 7}, {30, 6}, {31, 6}, {29, 9}, {19, 11}, {30, 9}, {37, 8}, {31, 9}, {20, 11}, {2, 13}, {21, 11}, {21, 10}, {22, 11}, {4, 12}, {23, 11}, {32, 9}, {38, 8}, {33, 9}, {24, 11}, {22, 10}, {39, 8}, {29, 7}, {40, 8}, {25, 11}, {26, 11}, {34, 9}, {41, 8}, {35, 9}, {27, 11}, {3, 13}, {28, 11}, {23, 10}, {29, 11}, {5, 12} }, { {2, 11}, {3, 10}, {15, 9}, {4, 10}, {0, 12}, {5, 10}, {12, 8}, {13, 8}, {14, 8}, {6, 10}, {7, 10}, {15, 8}, {30, 7}, {16, 8}, {16, 9}, {8, 10}, {17, 8}, {18, 8}, {19, 8}, {9, 10}, {3, 11}, {10, 10}, {17, 9}, {11, 10}, {1, 12}, {12, 10}, {20, 8}, {21, 8}, {22, 8}, {13, 10}, {23, 8}, {18, 6}, {14, 5}, {19, 6}, {24, 8}, {25, 8}, {20, 6}, {15, 5}, {16, 5}, {26, 8}, {27, 8}, {21, 6}, {17, 5}, {22, 6}, {28, 8}, {14, 10}, {29, 8}, {30, 8}, {31, 8}, {15, 10}, {18, 9}, {32, 8}, {31, 7}, {33, 8}, {19, 9}, {34, 8}, {18, 5}, {19, 5}, {20, 5}, {35, 8}, {32, 7}, {21, 5}, {15, 4}, {22, 5}, {33, 7}, {36, 8}, {23, 5}, {24, 5}, {25, 5}, {37, 8}, {20, 9}, {38, 8}, {34, 7}, {39, 8}, {21, 9}, {16, 10}, {40, 8}, {41, 8}, {42, 8}, {17, 10}, {43, 8}, {23, 6}, {26, 5}, {24, 6}, {44, 8}, {45, 8}, {27, 5}, {28, 5}, {25, 6}, {46, 8}, {47, 8}, {26, 6}, {29, 5}, {27, 6}, {48, 8}, {18, 10}, {49, 8}, {50, 8}, {51, 8}, {19, 10}, {2, 12}, {20, 10}, {21, 10}, {22, 10}, {4, 11}, {23, 10}, {52, 8}, {53, 8}, {54, 8}, {24, 10}, {22, 9}, {55, 8}, {35, 7}, {56, 8}, {25, 10}, {26, 10}, {57, 8}, {58, 8}, {59, 8}, {27, 10}, {3, 12}, {28, 10}, {23, 9}, {29, 10}, {5, 11} } }; static const Huffman_t HuffQ3 [49] = { {0, 9}, {2, 8}, {5, 7}, {6, 7}, {7, 7}, {3, 8}, {1, 9}, {4, 8}, {9, 6}, {10, 6}, {10, 5}, {11, 6}, {8, 7}, {5, 8}, {9, 7}, {12, 6}, {8, 4}, {9, 4}, {11, 5}, {13, 6}, {10, 7}, {11, 7}, {12, 5}, {10, 4}, {7, 3}, {11, 4}, {13, 5}, {12, 7}, {13, 7}, {14, 6}, {14, 5}, {12, 4}, {13, 4}, {15, 6}, {14, 7}, {6, 8}, {16, 6}, {17, 6}, {15, 5}, {18, 6}, {19, 6}, {7, 8}, {2, 9}, {8, 8}, {15, 7}, {16, 7}, {17, 7}, {9, 8}, {3, 9} }; static const Huffman_t HuffQ4 [81] = { {0, 10}, {2, 9}, {5, 8}, {12, 7}, {13, 7}, {6, 8}, {7, 8}, {3, 9}, {1, 10}, {4, 9}, {8, 8}, {14, 7}, {13, 6}, {14, 6}, {15, 6}, {15, 7}, {9, 8}, {5, 9}, {10, 8}, {16, 7}, {16, 6}, {17, 6}, {18, 5}, {18, 6}, {19, 6}, {17, 7}, {11, 8}, {12, 8}, {20, 6}, {21, 6}, {19, 5}, {20, 5}, {21, 5}, {22, 6}, {23, 6}, {13, 8}, {18, 7}, {24, 6}, {22, 5}, {23, 5}, {15, 4}, {24, 5}, {25, 5}, {25, 6}, {19, 7}, {14, 8}, {26, 6}, {27, 6}, {26, 5}, {27, 5}, {28, 5}, {28, 6}, {29, 6}, {15, 8}, {16, 8}, {20, 7}, {30, 6}, {31, 6}, {29, 5}, {32, 6}, {33, 6}, {21, 7}, {17, 8}, {6, 9}, {18, 8}, {22, 7}, {23, 7}, {34, 6}, {35, 6}, {24, 7}, {19, 8}, {7, 9}, {2, 10}, {8, 9}, {20, 8}, {21, 8}, {25, 7}, {22, 8}, {23, 8}, {9, 9}, {3, 10} }; static const Huffman_t HuffQ5 [2] [15] = { { {0, 7}, {1, 7}, {2, 6}, {2, 5}, {2, 4}, {2, 3}, {3, 3}, {3, 2}, {4, 3}, {5, 3}, {3, 4}, {3, 5}, {3, 6}, {2, 7}, {3, 7} }, { {0, 6}, {1, 6}, {2, 5}, {2, 4}, {3, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {4, 4}, {5, 4}, {3, 5}, {2, 6}, {3, 6} } }; static const Huffman_t HuffQ6 [2] [31] = { { {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 8}, {5, 8}, {4, 7}, {3, 6}, {4, 6}, {5, 6}, {5, 5}, {6, 5}, {4, 4}, {5, 4}, {4, 3}, {3, 2}, {5, 3}, {6, 4}, {7, 4}, {7, 5}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {5, 7}, {6, 8}, {7, 8}, {4, 9}, {5, 9}, {6, 9}, {7, 9} }, { {0, 8}, {1, 8}, {2, 7}, {3, 7}, {4, 7}, {4, 6}, {5, 6}, {4, 5}, {5, 5}, {6, 5}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4}, {7, 5}, {8, 5}, {9, 5}, {6, 6}, {7, 6}, {5, 7}, {6, 7}, {7, 7}, {2, 8}, {3, 8} } }; static const Huffman_t HuffQ7 [2] [63] = { { {0, 10}, {1, 10}, {2, 10}, {8, 9}, {9, 9}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10}, {10, 9}, {11, 9}, {12, 9}, {13, 9}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {10, 6}, {11, 6}, {12, 6}, {8, 5}, {9, 5}, {6, 4}, {4, 3}, {3, 2}, {5, 3}, {7, 4}, {10, 5}, {11, 5}, {13, 6}, {14, 6}, {15, 6}, {15, 7}, {16, 7}, {17, 7}, {18, 7}, {15, 8}, {19, 7}, {16, 8}, {17, 8}, {18, 8}, {19, 8}, {14, 9}, {15, 9}, {16, 9}, {17, 9}, {8, 10}, {9, 10}, {10, 10}, {11, 10}, {12, 10}, {18, 9}, {19, 9}, {13, 10}, {14, 10}, {15, 10} }, { {0, 9}, {1, 9}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6}, {16, 6}, {12, 5}, {13, 5}, {14, 5}, {15, 5}, {16, 5}, {17, 5}, {18, 5}, {19, 5}, {20, 5}, {21, 5}, {22, 5}, {23, 5}, {24, 5}, {25, 5}, {26, 5}, {27, 5}, {28, 5}, {29, 5}, {30, 5}, {31, 5}, {17, 6}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {22, 6}, {23, 6}, {13, 7}, {14, 7}, {15, 7}, {16, 7}, {17, 7}, {9, 8}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {2, 9}, {3, 9} } }; static const Huffman_t HuffQ8 [2] [127] = { { {3, 11}, {4, 11}, {10, 10}, {11, 10}, {12, 10}, {13, 10}, {14, 10}, {26, 9}, {15, 10}, {27, 9}, {16, 10}, {0, 12}, {1, 12}, {5, 11}, {6, 11}, {7, 11}, {8, 11}, {9, 11}, {10, 11}, {11, 11}, {17, 10}, {12, 11}, {18, 10}, {19, 10}, {20, 10}, {21, 10}, {22, 10}, {23, 10}, {24, 10}, {25, 10}, {28, 9}, {26, 10}, {27, 10}, {28, 10}, {29, 10}, {30, 10}, {29, 9}, {30, 9}, {31, 9}, {32, 9}, {33, 9}, {34, 9}, {35, 9}, {36, 9}, {25, 8}, {37, 9}, {26, 8}, {27, 8}, {28, 8}, {29, 8}, {30, 8}, {31, 8}, {20, 7}, {21, 7}, {22, 7}, {23, 7}, {14, 6}, {15, 6}, {16, 6}, {17, 6}, {11, 5}, {7, 4}, {4, 3}, {3, 2}, {5, 3}, {12, 5}, {13, 5}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {24, 7}, {25, 7}, {26, 7}, {27, 7}, {32, 8}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {37, 8}, {38, 8}, {39, 8}, {38, 9}, {39, 9}, {40, 9}, {41, 9}, {42, 9}, {43, 9}, {44, 9}, {45, 9}, {46, 9}, {31, 10}, {32, 10}, {47, 9}, {33, 10}, {34, 10}, {35, 10}, {36, 10}, {37, 10}, {38, 10}, {39, 10}, {40, 10}, {41, 10}, {13, 11}, {14, 11}, {42, 10}, {15, 11}, {16, 11}, {17, 11}, {18, 11}, {2, 12}, {19, 11}, {3, 12}, {4, 12}, {5, 12}, {43, 10}, {44, 10}, {48, 9}, {49, 9}, {45, 10}, {46, 10}, {47, 10}, {48, 10}, {49, 10}, {50, 10}, {51, 10} }, { {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {16, 8}, {17, 8}, {18, 8}, {19, 8}, {20, 8}, {21, 8}, {21, 7}, {22, 7}, {23, 7}, {24, 7}, {25, 7}, {26, 7}, {27, 7}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {36, 7}, {37, 7}, {38, 7}, {39, 7}, {40, 7}, {41, 7}, {42, 7}, {43, 7}, {44, 7}, {45, 7}, {46, 7}, {47, 7}, {48, 7}, {38, 6}, {39, 6}, {40, 6}, {41, 6}, {42, 6}, {43, 6}, {44, 6}, {45, 6}, {46, 6}, {47, 6}, {48, 6}, {49, 6}, {50, 6}, {51, 6}, {52, 6}, {53, 6}, {54, 6}, {55, 6}, {56, 6}, {57, 6}, {58, 6}, {59, 6}, {60, 6}, {61, 6}, {62, 6}, {49, 7}, {63, 6}, {50, 7}, {51, 7}, {52, 7}, {53, 7}, {54, 7}, {55, 7}, {56, 7}, {57, 7}, {58, 7}, {59, 7}, {60, 7}, {61, 7}, {62, 7}, {63, 7}, {64, 7}, {65, 7}, {66, 7}, {67, 7}, {68, 7}, {69, 7}, {70, 7}, {71, 7}, {72, 7}, {73, 7}, {74, 7}, {75, 7}, {22, 8}, {23, 8}, {24, 8}, {25, 8}, {26, 8}, {27, 8}, {28, 8}, {29, 8}, {30, 8}, {31, 8}, {32, 8}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {37, 8}, {38, 8}, {39, 8}, {40, 8}, {41, 8}, {4, 9}, {5, 9}, {6, 9}, {7, 9} } }; const Huffman_t HuffQ9up [256] = { {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}, {12, 9}, {13, 9}, {14, 9}, {15, 9}, {16, 9}, {17, 9}, {18, 9}, {38, 8}, {39, 8}, {19, 9}, {20, 9}, {21, 9}, {22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {29, 9}, {30, 9}, {31, 9}, {32, 9}, {33, 9}, {34, 9}, {35, 9}, {36, 9}, {37, 9}, {40, 8}, {38, 9}, {41, 8}, {42, 8}, {43, 8}, {44, 8}, {45, 8}, {46, 8}, {47, 8}, {48, 8}, {49, 8}, {50, 8}, {51, 8}, {52, 8}, {53, 8}, {54, 8}, {55, 8}, {56, 8}, {57, 8}, {58, 8}, {59, 8}, {60, 8}, {61, 8}, {62, 8}, {63, 8}, {64, 8}, {65, 8}, {66, 8}, {67, 8}, {68, 8}, {69, 8}, {70, 8}, {71, 8}, {72, 8}, {73, 8}, {74, 8}, {75, 8}, {76, 8}, {77, 8}, {78, 8}, {79, 8}, {80, 8}, {81, 8}, {82, 8}, {83, 8}, {84, 8}, {85, 8}, {86, 8}, {87, 8}, {88, 8}, {89, 8}, {90, 8}, {91, 8}, {92, 8}, {93, 8}, {94, 8}, {95, 8}, {96, 8}, {97, 8}, {98, 8}, {99, 8}, {100, 8}, {101, 8}, {102, 8}, {103, 8}, {104, 8}, {105, 8}, {106, 8}, {86, 7}, {87, 7}, {88, 7}, {89, 7}, {90, 7}, {91, 7}, {92, 7}, {93, 7}, {94, 7}, {95, 7}, {96, 7}, {97, 7}, {98, 7}, {99, 7}, {100, 7}, {101, 7}, {102, 7}, {103, 7}, {104, 7}, {62, 6}, {63, 6}, {105, 7}, {106, 7}, {107, 7}, {108, 7}, {109, 7}, {110, 7}, {111, 7}, {112, 7}, {113, 7}, {114, 7}, {115, 7}, {116, 7}, {117, 7}, {118, 7}, {119, 7}, {120, 7}, {121, 7}, {122, 7}, {107, 8}, {123, 7}, {108, 8}, {109, 8}, {110, 8}, {111, 8}, {112, 8}, {113, 8}, {114, 8}, {115, 8}, {116, 8}, {117, 8}, {118, 8}, {119, 8}, {120, 8}, {121, 8}, {122, 8}, {123, 8}, {124, 8}, {125, 8}, {126, 8}, {127, 8}, {128, 8}, {129, 8}, {130, 8}, {131, 8}, {132, 8}, {133, 8}, {134, 8}, {135, 8}, {136, 8}, {137, 8}, {138, 8}, {139, 8}, {140, 8}, {141, 8}, {142, 8}, {143, 8}, {144, 8}, {145, 8}, {146, 8}, {147, 8}, {148, 8}, {149, 8}, {150, 8}, {151, 8}, {152, 8}, {153, 8}, {154, 8}, {155, 8}, {156, 8}, {157, 8}, {158, 8}, {159, 8}, {160, 8}, {161, 8}, {162, 8}, {163, 8}, {164, 8}, {165, 8}, {166, 8}, {167, 8}, {168, 8}, {169, 8}, {170, 8}, {171, 8}, {39, 9}, {40, 9}, {41, 9}, {42, 9}, {43, 9}, {44, 9}, {45, 9}, {46, 9}, {47, 9}, {48, 9}, {49, 9}, {50, 9}, {51, 9}, {52, 9}, {53, 9}, {54, 9}, {55, 9}, {56, 9}, {57, 9}, {58, 9}, {59, 9}, {60, 9}, {61, 9}, {62, 9}, {63, 9}, {64, 9}, {65, 9}, {66, 9}, {67, 9}, {68, 9}, {69, 9}, {70, 9}, {71, 9}, {72, 9}, {73, 9}, {74, 9}, {75, 9}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, {0, 11}, {1, 11} }; Huffman_t const * const HuffQ [2] [8] = { { HuffQ1, HuffQ2[0], HuffQ3, HuffQ4, HuffQ5[0], HuffQ6[0], HuffQ7[0], HuffQ8[0] }, { HuffQ1, HuffQ2[1], HuffQ3, HuffQ4, HuffQ5[1], HuffQ6[1], HuffQ7[1], HuffQ8[1] } }; /* end of huffsv7.c */ musepack_src_r495/libmpcenc/bitstream.c0000664000000000000000000003121412231315357017115 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #ifdef _WIN32 #include #define sleep(t) Sleep((t) * 1000) #else #include #endif #include "libmpcenc.h" #include "stdio.h" unsigned long mpc_crc32(unsigned char *buf, int len); #define MAX_ENUM 32 static const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, {0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465}, {0, 0, 0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, 2300, 2600, 2925, 3276, 3654, 4060, 4495}, {0, 0, 0, 0, 1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465}, {0, 0, 0, 0, 0, 1, 6, 21, 56, 126, 252, 462, 792, 1287, 2002, 3003, 4368, 6188, 8568, 11628, 15504, 20349, 26334, 33649, 42504, 53130, 65780, 80730, 98280, 118755, 142506, 169911}, {0, 0, 0, 0, 0, 0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003, 5005, 8008, 12376, 18564, 27132, 38760, 54264, 74613, 100947, 134596, 177100, 230230, 296010, 376740, 475020, 593775, 736281}, {0, 0, 0, 0, 0, 0, 0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435, 11440, 19448, 31824, 50388, 77520, 116280, 170544, 245157, 346104, 480700, 657800, 888030, 1184040, 1560780, 2035800, 2629575}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870, 24310, 43758, 75582, 125970, 203490, 319770, 490314, 735471, 1081575, 1562275, 2220075, 3108105, 4292145, 5852925, 7888725}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92378, 167960, 293930, 497420, 817190, 1307504, 2042975, 3124550, 4686825, 6906900, 10015005, 14307150, 20160075}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758, 92378, 184756, 352716, 646646, 1144066, 1961256, 3268760, 5311735, 8436285, 13123110, 20030010, 30045015, 44352165}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 78, 364, 1365, 4368, 12376, 31824, 75582, 167960, 352716, 705432, 1352078, 2496144, 4457400, 7726160, 13037895, 21474180, 34597290, 54627300, 84672315}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 91, 455, 1820, 6188, 18564, 50388, 125970, 293930, 646646, 1352078, 2704156, 5200300, 9657700, 17383860, 30421755, 51895935, 86493225, 141120525}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 105, 560, 2380, 8568, 27132, 77520, 203490, 497420, 1144066, 2496144, 5200300, 10400600, 20058300, 37442160, 67863915, 119759850, 206253075}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 120, 680, 3060, 11628, 38760, 116280, 319770, 817190, 1961256, 4457400, 9657700, 20058300, 40116600, 77558760, 145422675, 265182525}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 136, 816, 3876, 15504, 54264, 170544, 490314, 1307504, 3268760, 7726160, 17383860, 37442160, 77558760, 155117520, 300540195}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 153, 969, 4845, 20349, 74613, 245157, 735471, 2042975, 5311735, 13037895, 30421755, 67863915, 145422675, 300540195} }; static const mpc_uint8_t Cnk_len[MAX_ENUM / 2][MAX_ENUM] = { {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, {0, 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9}, {0, 0, 0, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13}, {0, 0, 0, 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, {0, 0, 0, 0, 0, 3, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18}, {0, 0, 0, 0, 0, 0, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20}, {0, 0, 0, 0, 0, 0, 0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22}, {0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 23, 24}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 25, 26, 26}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 28}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 29}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 16, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 28, 29}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 10, 12, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30} }; static const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM] = { {0, 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, {0, 0, 1, 2, 6, 1, 11, 4, 28, 19, 9, 62, 50, 37, 23, 8, 120, 103, 85, 66, 46, 25, 3, 236, 212, 187, 161, 134, 106, 77, 47, 16}, {0, 0, 0, 0, 6, 12, 29, 8, 44, 8, 91, 36, 226, 148, 57, 464, 344, 208, 55, 908, 718, 508, 277, 24, 1796, 1496, 1171, 820, 442, 36, 3697, 3232}, {0, 0, 0, 0, 3, 1, 29, 58, 2, 46, 182, 17, 309, 23, 683, 228, 1716, 1036, 220, 3347, 2207, 877, 7529, 5758, 3734, 1434, 15218, 12293, 9017, 5363, 1303, 29576}, {0, 0, 0, 0, 0, 2, 11, 8, 2, 4, 50, 232, 761, 46, 1093, 3824, 2004, 7816, 4756, 880, 12419, 6434, 31887, 23032, 12406, 65292, 50342, 32792, 12317, 119638, 92233, 60768}, {0, 0, 0, 0, 0, 0, 1, 4, 44, 46, 50, 100, 332, 1093, 3187, 184, 4008, 14204, 5636, 26776, 11272, 56459, 30125, 127548, 85044, 31914, 228278, 147548, 49268, 454801, 312295, 142384}, {0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 182, 232, 332, 664, 1757, 4944, 13320, 944, 15148, 53552, 14792, 91600, 16987, 178184, 43588, 390776, 160546, 913112, 536372, 61352, 1564729, 828448}, {0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 91, 17, 761, 1093, 1757, 3514, 8458, 21778, 55490, 5102, 58654, 204518, 33974, 313105, 1015577, 534877, 1974229, 1086199, 4096463, 2535683, 499883, 6258916}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 36, 309, 46, 3187, 4944, 8458, 16916, 38694, 94184, 230358, 26868, 231386, 789648, 54177, 1069754, 3701783, 1481708, 6762211, 2470066, 13394357, 5505632}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 62, 226, 23, 1093, 184, 13320, 21778, 38694, 77388, 171572, 401930, 953086, 135896, 925544, 3076873, 8340931, 3654106, 13524422, 3509417, 22756699, 2596624}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 50, 148, 683, 3824, 4008, 944, 55490, 94184, 171572, 343144, 745074, 1698160, 3931208, 662448, 3739321, 12080252, 32511574, 12481564, 49545413, 5193248}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 57, 228, 2004, 14204, 15148, 5102, 230358, 401930, 745074, 1490148, 3188308, 7119516, 16170572, 3132677, 15212929, 47724503, 127314931, 42642616}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 464, 1716, 7816, 5636, 53552, 58654, 26868, 953086, 1698160, 3188308, 6376616, 13496132, 29666704, 66353813, 14457878, 62182381, 189497312}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 344, 1036, 4756, 26776, 14792, 204518, 231386, 135896, 3931208, 7119516, 13496132, 26992264, 56658968, 123012781, 3252931, 65435312}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 208, 220, 880, 11272, 91600, 33974, 789648, 925544, 662448, 16170572, 29666704, 56658968, 113317936, 236330717, 508019104}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 103, 55, 3347, 12419, 56459, 16987, 313105, 54177, 3076873, 3739321, 3132677, 66353813, 123012781, 236330717} }; static const mpc_uint8_t log2[32] = { 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6}; static const mpc_uint8_t log2_lost[32] = { 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31}; void emptyBits(mpc_encoder_t * e) { while( e->bitsCount >= 8 ){ e->bitsCount -= 8; e->buffer[e->pos] = (mpc_uint8_t) (e->bitsBuff >> e->bitsCount); e->pos++; } } unsigned int encodeSize(mpc_uint64_t size, char * buff, mpc_bool_t addCodeSize) { unsigned int i = 1; int j; if (addCodeSize) { while ((1ull << (7 * i)) - i <= size) i++; size += i; } else while ((1ull << (7 * i)) <= size) i++; for( j = i - 1; j >= 0; j--){ buff[j] = (char) (size | 0x80); size >>= 7; } buff[i - 1] &= 0x7F; return i; } static void encodeGolomb(mpc_encoder_t * e, mpc_uint32_t nb, mpc_uint_t k) { unsigned int l = (nb >> k) + 1; nb &= (1 << k) - 1; while( l > 31 ){ writeBits(e, 0, 31); l -= 31; } writeBits(e, 1, l); writeBits(e, nb, k); } void encodeEnum(mpc_encoder_t * e, const mpc_uint32_t bits, const mpc_uint_t N) { mpc_uint32_t code = 0; const mpc_uint32_t * C = Cnk[0]; unsigned int n = 0, k = 0; for( ; n < N; n++){ if ((bits >> n) & 1) { code += C[n]; C += MAX_ENUM; k++; } } if (k == 0) return; if (code < Cnk_lost[k-1][n-1]) writeBits(e, code, Cnk_len[k-1][n-1] - 1); else writeBits(e, code + Cnk_lost[k-1][n-1], Cnk_len[k-1][n-1]); } void encodeLog(mpc_encoder_t * e, mpc_uint32_t value, mpc_uint32_t max) { if (value < log2_lost[max - 1]) writeBits(e, value, log2[max - 1] - 1); else writeBits(e, value + log2_lost[max - 1], log2[max - 1]); } void writeMagic(mpc_encoder_t * e) { fwrite("MPCK", sizeof(char), 4, e->outputFile); e->outputBits += 32; e->framesInBlock = 0; } mpc_uint32_t writeBlock ( mpc_encoder_t * e, const char * key, const mpc_bool_t addCRC, mpc_uint32_t min_size) { FILE * fp = e->outputFile; mpc_uint32_t written = 0; mpc_uint8_t * datas = e->buffer; char blockSize[10]; mpc_uint32_t len; writeBits(e, 0, (8 - e->bitsCount) % 8); emptyBits(e); // write block header (key / length) len = e->pos + (addCRC > 0) * 4; if (min_size <= len) min_size = len; else { mpc_uint32_t pad = min_size - len, i; for(i = 0; i < pad; i++) writeBits(e, 0, 8); emptyBits(e); } len = encodeSize(min_size + 2, blockSize, MPC_TRUE); fwrite(key, sizeof(char), 2, fp); fwrite(blockSize, sizeof(char), len, fp); e->outputBits += (len + 2) * 8; if (addCRC) { char tmp[4]; unsigned long CRC32 = mpc_crc32((unsigned char *) e->buffer, e->pos); tmp[0] = (char) (CRC32 >> 24); tmp[1] = (char) (CRC32 >> 16); tmp[2] = (char) (CRC32 >> 8); tmp[3] = (char) CRC32; fwrite(tmp, sizeof(char), 4, fp); e->outputBits += 32; } // write datas while ( e->pos != 0 ) { written = fwrite ( datas, sizeof(*e->buffer), e->pos, fp ); if ( written == 0 ) { fprintf(stderr, "\b\n WARNING: Disk full?, retry after 10 sec ...\a"); sleep (10); } if ( written > 0 ) { datas += written; e->pos -= written; } } e->framesInBlock = 0; return min_size; } void writeSeekTable (mpc_encoder_t * e) { mpc_uint32_t i, len; mpc_uint32_t * table = e->seek_table; mpc_uint8_t tmp[10]; // write the position to header i = ftell(e->outputFile); // get the seek table position len = encodeSize(i - e->seek_ptr, (char*)tmp, MPC_FALSE); fseek(e->outputFile, e->seek_ptr + 3, SEEK_SET); fwrite(tmp, sizeof(mpc_uint8_t), len, e->outputFile); fseek(e->outputFile, i, SEEK_SET); // write the seek table datas len = encodeSize(e->seek_pos, (char*)tmp, MPC_FALSE); for( i = 0; i < len; i++) writeBits ( e, tmp[i], 8 ); writeBits ( e, e->seek_pwr, 4 ); len = encodeSize(table[0] - e->seek_ref, (char*)tmp, MPC_FALSE); for( i = 0; i < len; i++) writeBits ( e, tmp[i], 8 ); if (e->seek_pos > 1) { len = encodeSize(table[1] - e->seek_ref, (char*)tmp, MPC_FALSE); for( i = 0; i < len; i++) writeBits ( e, tmp[i], 8 ); } for( i = 2; i < e->seek_pos; i++){ int code = (table[i] - 2 * table[i-1] + table[i-2]) << 1; if (code < 0) code = -code | 1; encodeGolomb(e, code, 12); } } /* end of bitstream.c */ musepack_src_r495/libmpcenc/CMakeLists.txt0000664000000000000000000000024610601546075017522 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/include) add_library(mpcenc_static STATIC analy_filter bitstream encode_sv7 huffsv7 quant ${libmpc_SOURCE_DIR}/common/crc32) musepack_src_r495/libmpcenc/analy_filter.c0000664000000000000000000003413012231315357017574 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include #include #include #define FASTER /* C O N S T A N T S */ #undef _ #define _(value) (float)(value##.##L / 0x200000) static float Ci_opt [512] = { _( 0), _( 213), _( 2037), _( 6574), _(75038), _( 6574), _(2037), _(213), _( -1), _( 218), _( 2000), _( 5959), _(74992), _( 7134), _(2063), _(208), _( -1), _( 222), _( 1952), _( 5288), _(74856), _( 7640), _(2080), _(202), _( -1), _( 225), _( 1893), _( 4561), _(74630), _( 8092), _(2087), _(196), _( -1), _( 227), _( 1822), _( 3776), _(74313), _( 8492), _(2085), _(190), _( -1), _( 228), _( 1739), _( 2935), _(73908), _( 8840), _(2075), _(183), _( -1), _( 228), _( 1644), _( 2037), _(73415), _( 9139), _(2057), _(176), _( -2), _( 227), _( 1535), _( 1082), _(72835), _( 9389), _(2032), _(169), _( -2), _( 224), _( 1414), _( 70), _(72169), _( 9592), _(2001), _(161), _( -2), _( 221), _( 1280), _( -998), _(71420), _( 9750), _(1962), _(154), _( -2), _( 215), _( 1131), _( -2122), _(70590), _( 9863), _(1919), _(147), _( -3), _( 208), _( 970), _( -3300), _(69679), _( 9935), _(1870), _(139), _( -3), _( 200), _( 794), _( -4533), _(68692), _( 9966), _(1817), _(132), _( -4), _( 189), _( 605), _( -5818), _(67629), _( 9959), _(1759), _(125), _( -4), _( 177), _( 402), _( -7154), _(66494), _( 9916), _(1698), _(117), _( -5), _( 163), _( 185), _( -8540), _(65290), _( 9838), _(1634), _(111), _( -5), _( 146), _( -45), _( -9975), _(64019), _( 9727), _(1567), _(104), _( -6), _( 127), _( -288), _(-11455), _(62684), _( 9585), _(1498), _( 97), _( -7), _( 106), _( -545), _(-12980), _(61289), _( 9416), _(1428), _( 91), _( -7), _( 83), _( -814), _(-14548), _(59838), _( 9219), _(1356), _( 85), _( -8), _( 57), _(-1095), _(-16155), _(58333), _( 8998), _(1283), _( 79), _( -9), _( 29), _(-1388), _(-17799), _(56778), _( 8755), _(1210), _( 73), _( -10), _( -2), _(-1692), _(-19478), _(55178), _( 8491), _(1137), _( 68), _( -11), _( -36), _(-2006), _(-21189), _(53534), _( 8209), _(1064), _( 63), _( -13), _( -72), _(-2330), _(-22929), _(51853), _( 7910), _( 991), _( 58), _( -14), _( -111), _(-2663), _(-24694), _(50137), _( 7597), _( 919), _( 53), _( -16), _( -153), _(-3004), _(-26482), _(48390), _( 7271), _( 848), _( 49), _( -17), _( -197), _(-3351), _(-28289), _(46617), _( 6935), _( 779), _( 45), _( -19), _( -244), _(-3705), _(-30112), _(44821), _( 6589), _( 711), _( 41), _( -21), _( -294), _(-4063), _(-31947), _(43006), _( 6237), _( 645), _( 38), _( -24), _( -347), _(-4425), _(-33791), _(41176), _( 5879), _( 581), _( 35), _( -26), _( -401), _(-4788), _(-35640), _(39336), _( 5517), _( 519), _( 31), _( -29), _( -459), _(-5153), _(-37489), _(37489), _( 5153), _( 459), _( 29), _( -31), _( -519), _(-5517), _(-39336), _(35640), _( 4788), _( 401), _( 26), _( -35), _( -581), _(-5879), _(-41176), _(33791), _( 4425), _( 347), _( 24), _( -38), _( -645), _(-6237), _(-43006), _(31947), _( 4063), _( 294), _( 21), _( -41), _( -711), _(-6589), _(-44821), _(30112), _( 3705), _( 244), _( 19), _( -45), _( -779), _(-6935), _(-46617), _(28289), _( 3351), _( 197), _( 17), _( -49), _( -848), _(-7271), _(-48390), _(26482), _( 3004), _( 153), _( 16), _( -53), _( -919), _(-7597), _(-50137), _(24694), _( 2663), _( 111), _( 14), _( -58), _( -991), _(-7910), _(-51853), _(22929), _( 2330), _( 72), _( 13), _( -63), _(-1064), _(-8209), _(-53534), _(21189), _( 2006), _( 36), _( 11), _( -68), _(-1137), _(-8491), _(-55178), _(19478), _( 1692), _( 2), _( 10), _( -73), _(-1210), _(-8755), _(-56778), _(17799), _( 1388), _( -29), _( 9), _( -79), _(-1283), _(-8998), _(-58333), _(16155), _( 1095), _( -57), _( 8), _( -85), _(-1356), _(-9219), _(-59838), _(14548), _( 814), _( -83), _( 7), _( -91), _(-1428), _(-9416), _(-61289), _(12980), _( 545), _(-106), _( 7), _( -97), _(-1498), _(-9585), _(-62684), _(11455), _( 288), _(-127), _( 6), _(-104), _(-1567), _(-9727), _(-64019), _( 9975), _( 45), _(-146), _( 5), _(-111), _(-1634), _(-9838), _(-65290), _( 8540), _( -185), _(-163), _( 5), _(-117), _(-1698), _(-9916), _(-66494), _( 7154), _( -402), _(-177), _( 4), _(-125), _(-1759), _(-9959), _(-67629), _( 5818), _( -605), _(-189), _( 4), _(-132), _(-1817), _(-9966), _(-68692), _( 4533), _( -794), _(-200), _( 3), _(-139), _(-1870), _(-9935), _(-69679), _( 3300), _( -970), _(-208), _( 3), _(-147), _(-1919), _(-9863), _(-70590), _( 2122), _(-1131), _(-215), _( 2), _(-154), _(-1962), _(-9750), _(-71420), _( 998), _(-1280), _(-221), _( 2), _(-161), _(-2001), _(-9592), _(-72169), _( -70), _(-1414), _(-224), _( 2), _(-169), _(-2032), _(-9389), _(-72835), _(-1082), _(-1535), _(-227), _( 2), _(-176), _(-2057), _(-9139), _(-73415), _(-2037), _(-1644), _(-228), _( 1), _(-183), _(-2075), _(-8840), _(-73908), _(-2935), _(-1739), _(-228), _( 1), _(-190), _(-2085), _(-8492), _(-74313), _(-3776), _(-1822), _(-227), _( 1), _(-196), _(-2087), _(-8092), _(-74630), _(-4561), _(-1893), _(-225), _( 1), _(-202), _(-2080), _(-7640), _(-74856), _(-5288), _(-1952), _(-222), _( 1), _(-208), _(-2063), _(-7134), _(-74992), _(-5959), _(-2000), _(-218), _( 1), }; #undef _ static float M [1024]; void Klemm ( void ) { int i; int k; float S [512]; for ( i=0; i<32; i++ ) { for ( k=0; k<32; k++ ) { M [i*32 + k] = (float) cos ( ((2*i+1)*k & 127) * M_PI/64 ); } } #ifdef FASTER for ( i = 0; i < 384; i++ ) S[i] = Ci_opt[i]; for ( i = 384; i < 392; i++ ) S[i] = 0; for ( i = 392; i < 512; i++ ) S[i] = -Ci_opt[i]; for ( i = 0; i < 512; i++ ) Ci_opt[i] = S[i]; for ( i = 0; i < 128; i++ ) Ci_opt[i] = S[(i&7) + 120 - (i&120)]; for ( i = 128; i < 384; i++ ) Ci_opt[i] = S[i]; for ( i = 384; i < 512; i++ ) Ci_opt[i] = S[ 384 + (i&7) + 120 - (i&120)]; #endif } /* D E F I N E S */ #define X_MEM 1152 /* V A R I A B L E S */ float X_L [ X_MEM + 480 ]; float X_R [ X_MEM + 480 ]; /* F U N C T I O N S */ // vectoring & partial calculation static void Vectoring ( const float* x, float* y ) { #ifdef FASTER int i = 0; const float* c1; const float* c2; const float* x1; const float* x2; # define EXPR(c,x) (c[0]*x[0] + c[1]*x[64] + c[2]*x[128] + c[3]*x[192] + c[4]*x[256] + c[5]*x[320] + c[6]*x[384] + c[7]*x[448]) i++; *y++ = EXPR ((Ci_opt+128),(x+31)); c1 = Ci_opt - 8; c2 = Ci_opt + 128; x1 = x + 16; x2 = x + 31; do { x1--, x2--, i++; c1 += 8, c2 += 8; *y++ = EXPR (c1,x1) + EXPR (c2,x2); } while ( i < 16 ); i++; *y++ = EXPR ((Ci_opt+120),(x+0)) + EXPR ((Ci_opt+256),(x+32)); c1 = Ci_opt + 384 - 8; c2 = Ci_opt + 256; x1 = x + 47; x2 = x + 32; do { x1++, x2++, i++; c1 += 8, c2 += 8; *y++ = EXPR (c1,x1) + EXPR (c2,x2); } while ( i < 32 ); #else int i; const float* c = Ci_opt; for ( i = 0; i < 16; i++, c += 32, x += 4, y += 4 ) { y[0] = c[ 0] * x[ 0] + c[ 1] * x[ 64] + c[ 2] * x[128] + c[ 3] * x[192] + c[ 4] * x[256] + c[ 5] * x[320] + c[ 6] * x[384] + c[ 7] * x[448]; y[1] = c[ 8] * x[ 1] + c[ 9] * x[ 65] + c[10] * x[129] + c[11] * x[193] + c[12] * x[257] + c[13] * x[321] + c[14] * x[385] + c[15] * x[449]; y[2] = c[16] * x[ 2] + c[17] * x[ 66] + c[18] * x[130] + c[19] * x[194] + c[20] * x[258] + c[21] * x[322] + c[22] * x[386] + c[23] * x[450]; y[3] = c[24] * x[ 3] + c[25] * x[ 67] + c[26] * x[131] + c[27] * x[195] + c[28] * x[259] + c[29] * x[323] + c[30] * x[387] + c[31] * x[451]; } #endif } // matrixing with Mi[32][32] = Mi[1024] static void Matrixing ( const int MaxBand, const float* mi, const float* y, float* samples ) { int i; #ifdef FASTER for ( i = 0; i <= MaxBand; i++, mi += 32, samples += 72 ) { // 144 = sizeof(SubbandFloatTyp)/sizeof(float) samples[0] = y[ 0] + mi[ 1] * y[ 1] + mi[ 2] * y[ 2] + mi[ 3] * y[ 3] + mi[ 4] * y[ 4] + mi[ 5] * y[ 5] + mi[ 6] * y[ 6] + mi[ 7] * y[ 7] + mi[ 8] * y[ 8] + mi[ 9] * y[ 9] + mi[10] * y[10] + mi[11] * y[11] + mi[12] * y[12] + mi[13] * y[13] + mi[14] * y[14] + mi[15] * y[15] + mi[16] * y[16] + mi[17] * y[17] + mi[18] * y[18] + mi[19] * y[19] + mi[20] * y[20] + mi[21] * y[21] + mi[22] * y[22] + mi[23] * y[23] + mi[24] * y[24] + mi[25] * y[25] + mi[26] * y[26] + mi[27] * y[27] + mi[28] * y[28] + mi[29] * y[29] + mi[30] * y[30] + mi[31] * y[31]; } #else for ( i = 0; i <= MaxBand; i++, mi += 32, samples += 72 ) { // 144 = sizeof(SubbandFloatTyp)/sizeof(float) samples[0] = y[16] + mi[ 1] * (y[15]+y[17]) + mi[ 2] * (y[14]+y[18]) + mi[ 3] * (y[13]+y[19]) + mi[ 4] * (y[12]+y[20]) + mi[ 5] * (y[11]+y[21]) + mi[ 6] * (y[10]+y[22]) + mi[ 7] * (y[ 9]+y[23]) + mi[ 8] * (y[ 8]+y[24]) + mi[ 9] * (y[ 7]+y[25]) + mi[10] * (y[ 6]+y[26]) + mi[11] * (y[ 5]+y[27]) + mi[12] * (y[ 4]+y[28]) + mi[13] * (y[ 3]+y[29]) + mi[14] * (y[ 2]+y[30]) + mi[15] * (y[ 1]+y[31]) + mi[16] * (y[ 0]+y[32]) + mi[31] * (y[47]-y[49]) + mi[30] * (y[46]-y[50]) + mi[29] * (y[45]-y[51]) + mi[28] * (y[44]-y[52]) + mi[27] * (y[43]-y[53]) + mi[26] * (y[42]-y[54]) + mi[25] * (y[41]-y[55]) + mi[24] * (y[40]-y[56]) + mi[23] * (y[39]-y[57]) + mi[22] * (y[38]-y[58]) + mi[21] * (y[37]-y[59]) + mi[20] * (y[36]-y[60]) + mi[19] * (y[35]-y[61]) + mi[18] * (y[34]-y[62]) + mi[17] * (y[33]-y[63]); } #endif } // Analysis-Filterbank void Analyse_Filter ( const PCMDataTyp* in, SubbandFloatTyp* out, const int MaxBand ) { #ifdef FASTER float Y_L [32]; float Y_R [32]; #else float Y_L [64]; float Y_R [64]; #endif float* x; const float* pcm; int n; int i; /************************* calculate L-signal ***************************/ memcpy ( X_L + X_MEM, X_L, 480*sizeof(*X_L) ); x = X_L + X_MEM; pcm = in->L + 479; // 479 = CENTER + 31 for ( n = 0; n < 36; n++, pcm += 64 ) { x -= 32; // updating vector x #ifdef FASTER for ( i = 0; i < 16; i++ ) x[i] = *pcm--; for ( i = 31; i >= 16; i-- ) x[i] = *pcm--; #else for ( i = 0; i < 32; i++ ) x[i] = *pcm--; #endif Vectoring ( x, Y_L ); // vectoring & partial calculation Matrixing ( MaxBand, M, Y_L, &out[0].L[n] ); // matrixing } /************************* calculate R-signal ***************************/ memcpy ( X_R + X_MEM, X_R, 480*sizeof(*X_R) ); x = X_R + X_MEM; pcm = in->R + 479; // 479 = CENTER + 31 for ( n = 0; n < 36; n++, pcm += 64 ) { x -= 32; // updating vector x #ifdef FASTER for ( i = 0; i < 16; i++ ) x[i] = *pcm--; for ( i = 31; i >= 16; i-- ) x[i] = *pcm--; #else for ( i = 0; i < 32; i++ ) x[i] = *pcm--; #endif Vectoring ( x, Y_R ); // vectoring & partial calculation Matrixing ( MaxBand, M, Y_R, &out[0].R[n] ); // matrixing } } void Analyse_Init ( float Left, float Right, SubbandFloatTyp* out, const int MaxBand ) { #ifdef FASTER float Y_L [32]; float Y_R [32]; #else float Y_L [64]; float Y_R [64]; #endif float* x; int n; int i; /************************* calculate L-signal ***************************/ memcpy ( X_L + X_MEM, X_L, 480*sizeof(*X_L) ); x = X_L + X_MEM; for ( n = 0; n < 36; n++ ) { x -= 32; // updating vector x #ifdef FASTER for ( i = 0; i < 16; i++ ) x[i] = Left; for ( i = 31; i >= 16; i-- ) x[i] = Left; #else for ( i = 0; i < 32; i++ ) x[i] = Left; #endif Vectoring ( x, Y_L ); // vectoring & partial calculation Matrixing ( MaxBand, M, Y_L, &out[0].L[n] ); // matrixing } /************************* calculate R-signal ***************************/ memcpy ( X_R + X_MEM, X_R, 480*sizeof(*X_R) ); x = X_R + X_MEM; for ( n = 0; n < 36; n++ ) { x -= 32; // updating vector x #ifdef FASTER for ( i = 0; i < 16; i++ ) x[i] = Right; for ( i = 31; i >= 16; i-- ) x[i] = Right; #else for ( i = 0; i < 32; i++ ) x[i] = Right; #endif Vectoring ( x, Y_R ); // vectoring & partial calculation Matrixing ( MaxBand, M, Y_R, &out[0].R[n] ); // matrixing } } /* end of analy_filter.c */ musepack_src_r495/libmpcenc/quant.c0000664000000000000000000003574112231315357016264 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "libmpcenc.h" #include #include /* V A R I A B L E S */ float __SCF [128 + 6]; // tabulated scalefactors #define SCF ( __SCF + 6 ) float __invSCF [128 + 6]; // inverted scalefactors #define invSCF (__invSCF + 6) // Quantization-coefficients: step/65536 bzw. (2*D[Res]+1)/65536 static const float __A [1 + 18] = { 0.0000762939453125f, 0.0000000000000000f, 0.0000457763671875f, 0.0000762939453125f, 0.0001068115234375f, 0.0001373291015625f, 0.0002288818359375f, 0.0004730224609375f, 0.0009613037109375f, 0.0019378662109375f, 0.0038909912109375f, 0.0077972412109375f, 0.0156097412109375f, 0.0312347412109375f, 0.0624847412109375f, 0.1249847412109375f, 0.2499847412109375f, 0.4999847412109375f }; // Requantization-coefficients: 65536/step bzw. 1/A[Res] static const float __C [1 + 18] = { 13107.200000000001f, 65535.000000000000f, 21845.333333333332f, 13107.200000000001f, 9362.285714285713f, 7281.777777777777f, 4369.066666666666f, 2114.064516129032f, 1040.253968253968f, 516.031496062992f, 257.003921568627f, 128.250489236790f, 64.062561094819f, 32.015632633121f, 16.003907203907f, 8.000976681723f, 4.000244155527f, 2.000061037018f, 1.000015259022f }; // Requantization-Offset: 2*D+1 = steps of quantizer static const int __D [1 + 18] = { 2, 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; #define A (__A + 1) #define C (__C + 1) #define D (__D + 1) // Generation of the scalefactors and their inverses void Init_Skalenfaktoren ( void ) { int n; for ( n = -6; n < 128; n++ ) { SCF[n] = (float) ( pow(10.,-0.1*(n-1)/1.26) ); invSCF[n] = (float) ( pow(10., 0.1*(n-1)/1.26) ); } } #ifdef WIN32 #pragma warning ( disable : 4305 ) #endif static float NoiseInjectionCompensation1D [18] = { #if 1 1.f, 0.884621, 0.935711, 0.970829, 0.987941, 0.994315, 0.997826, 0.999744, 1., 1., 1., 1., 1., 1., 1., 1., 1., 1. #else 1., 0.907073, // -1...+1 0.946334, // -2...+2 0.974793, // -3...+3 0.987647, // -4...+4 0.994330, // -7...+7 0.997846, // -15...+15 1., // -31...+31 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., #endif } ; #if 0 static float NoiseInjectionCompensation2D [18] [32] = { { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, { 0.931595, 0.891390, 0.852494, 0.872420, 0.904053, 0.933716, 0.958976, 0.977719, 0.993979, 1.009011, 1.020961, 1.029564, 1.026582, 1.026753, 1.035573, 1.053251, 1.073429, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, }, { 0.878264, 0.882351, 0.904261, 0.930843, 0.949243, 0.966741, 0.980500, 0.988182, 0.993361, 0.997112, 0.998918, 0.999501, 1.003179, 1.007445, 1.008678, 0.995890, 0.991015, 0.988019, 0.985479, 0.987646, 1.003605, 1.029301, 1.040511, 1.061531, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, }, { 0.866977, 0.943500, 0.941561, 0.953049, 0.967274, 0.980476, 0.988678, 0.993240, 0.996376, 0.998513, 0.999545, 0.999775, 1.000898, 1.003954, 1.006308, 1.004932, 1.002867, 1.002922, 1.003624, 1.005487, 1.003919, 1.008022, 0.987693, 1.000358, 1.017461, 1.039166, 1.056053, 1.068191, 1.068191, 1.068191, 1.068191, 1.068191, }, { 0.880390, 0.976713, 0.976180, 0.976596, 0.982011, 0.988786, 0.993619, 0.996641, 0.998824, 1.000297, 1.001195, 1.001718, 1.002395, 1.003503, 1.005617, 1.005072, 1.002409, 1.003703, 1.003412, 1.003318, 1.005290, 1.007112, 1.014370, 1.010040, 1.000780, 1.005700, 1.020505, 1.030123, 1.030123, 1.030123, 1.030123, 1.030123, }, { 0.916894, 0.987164, 0.988734, 0.992318, 0.995268, 0.996932, 0.998141, 0.999072, 0.999674, 1.000104, 1.000292, 1.000386, 1.000399, 1.000222, 1.000671, 1.002127, 1.000137, 1.000046, 0.999644, 0.999156, 1.000568, 1.000098, 0.993764, 0.993954, 0.998971, 1.002835, 1.002972, 0.995376, 1.001643, 1.001643, 1.001643, 1.001643, }, { 0.982771, 0.995034, 0.997118, 0.998294, 0.998652, 0.999016, 0.999382, 0.999598, 0.999746, 0.999851, 0.999837, 0.999881, 0.999847, 1.000154, 0.999885, 1.000222, 0.999963, 1.000934, 0.999804, 0.999927, 1.000379, 0.997574, 0.997943, 0.998748, 0.998151, 0.997458, 1.000319, 1.001091, 0.998461, 0.996151, 1.005969, 1.005969, }, { 0.997150, 0.999903, 0.999424, 0.999537, 0.999661, 0.999753, 0.999851, 0.999903, 0.999928, 0.999963, 0.999969, 0.999941, 0.999974, 0.999967, 0.999996, 0.999975, 0.999966, 0.999704, 0.999946, 0.999894, 0.999905, 1.000840, 1.000716, 1.000799, 1.000406, 0.999912, 1.000153, 0.999789, 1.000495, 1.000495, 1.001167, 1.001347, }, { 0.995524, 0.999983, 1.000044, 0.999965, 0.999970, 0.999974, 0.999986, 0.999995, 0.999996, 1.000011, 0.999997, 1.000010, 1.000010, 1.000026, 1.000006, 1.000148, 1.000048, 0.999999, 1.000161, 1.000193, 0.999797, 1.000145, 0.999974, 1.000039, 0.999731, 0.999985, 1.000563, 1.000256, 1.000637, 1.000050, 1.002013, 1.001053, }, { 0.994796, 0.999833, 1.000003, 1.000012, 0.999986, 0.999991, 0.999991, 1.000000, 1.000004, 0.999999, 1.000005, 1.000004, 1.000008, 0.999996, 1.000027, 1.000097, 0.999951, 0.999938, 0.999989, 1.000001, 1.000048, 0.999935, 1.000068, 1.000134, 0.999961, 1.000198, 0.999956, 0.999957, 0.999844, 1.000087, 0.999708, 1.000198, }, { 0.996046, 0.999902, 1.000019, 1.000017, 0.999983, 0.999997, 1.000002, 0.999993, 0.999999, 1.000003, 1.000001, 1.000015, 1.000004, 1.000006, 0.999987, 0.999993, 0.999992, 1.000029, 1.000064, 0.999997, 1.000044, 1.000044, 0.999919, 0.999875, 1.000011, 0.999897, 0.999905, 0.999996, 0.999934, 0.999968, 1.000008, 0.999902, }, { 0.998703, 0.999963, 1.000021, 1.000006, 1.000008, 1.000000, 1.000003, 0.999994, 0.999990, 0.999990, 1.000003, 1.000009, 1.000001, 0.999999, 1.000001, 1.000009, 0.999999, 0.999988, 1.000003, 0.999971, 1.000005, 1.000042, 0.999924, 0.999995, 0.999998, 0.999988, 0.999961, 0.999942, 1.000046, 1.000061, 1.000112, 1.000052, }, { 0.999872, 1.000001, 1.000004, 0.999998, 0.999999, 0.999998, 0.999992, 0.999990, 0.999991, 1.000000, 1.000000, 1.000000, 1.000002, 0.999996, 1.000004, 1.000011, 0.999963, 1.000016, 1.000050, 0.999996, 0.999998, 1.000006, 0.999990, 0.999948, 0.999974, 1.000060, 1.000014, 0.999987, 0.999986, 0.999917, 0.999973, 1.000035, }, { 1.000366, 1.000006, 0.999996, 0.999995, 0.999998, 0.999996, 0.999991, 1.000001, 0.999990, 0.999996, 1.000010, 0.999999, 1.000002, 1.000000, 0.999996, 0.999990, 1.000014, 0.999978, 1.000011, 0.999983, 0.999988, 0.999971, 0.999997, 0.999989, 0.999986, 0.999958, 1.000005, 0.999992, 0.999975, 0.999975, 0.999975, 0.999975, }, { 0.999736, 0.999995, 1.000002, 1.000004, 0.999999, 1.000000, 1.000003, 1.000000, 1.000007, 0.999992, 0.999997, 0.999998, 0.999998, 0.999997, 1.000007, 1.000012, 1.000004, 0.999995, 0.999996, 1.000009, 1.000003, 1.000008, 1.000001, 1.000003, 1.000011, 1.000019, 0.999991, 0.999970, 0.999970, 0.999970, 0.999970, 0.999965, }, { 0.999970, 1.000000, 1.000000, 1.000000, 1.000001, 1.000000, 1.000000, 0.999999, 1.000001, 1.000000, 0.999999, 0.999999, 0.999999, 1.000007, 1.000005, 1.000002, 0.999999, 0.999999, 1.000000, 0.999997, 0.999999, 1.000001, 1.000001, 0.999988, 0.999988, 0.999984, 0.999995, 0.999986, 0.999986, 0.999986, 0.999986, 0.999986, }, { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, }; #endif #ifdef WIN32 #pragma warning ( default : 4305 ) #endif void NoiseInjectionComp ( void ) { int i; for ( i = 0; i < sizeof(NoiseInjectionCompensation1D)/sizeof(*NoiseInjectionCompensation1D); i++ ) NoiseInjectionCompensation1D [i] = 1.f; #if 0 for ( i = 0; i < sizeof(NoiseInjectionCompensation2D)/sizeof(**NoiseInjectionCompensation2D); i++ ) NoiseInjectionCompensation2D [0][i] = 1.f; #endif } // Quantizes a subband and calculates iSNR float ISNR_Schaetzer ( const float* input, const float SNRcomp, const int res ) { const float fac = A [res] * NoiseInjectionCompensation1D [res]; const float invfac = C [res] / NoiseInjectionCompensation1D [res]; float signal = 1.e-30f; float error = 1.e-30f; const float * in_end = input + 36; // Summation of the absolute power and the quadratic error do { float err; err = mpc_nearbyintf(input[0] * fac) * invfac - input[0]; error += err * err; signal += input[0] * input[0]; err = mpc_nearbyintf(input[1] * fac) * invfac - input[1]; error += err * err; signal += input[1] * input[1]; err = mpc_nearbyintf(input[2] * fac) * invfac - input[2]; error += err * err; signal += input[2] * input[2]; err = mpc_nearbyintf(input[3] * fac) * invfac - input[3]; error += err * err; signal += input[3] * input[3]; input += 4; } while (input < in_end); error *= NoiseInjectionCompensation1D [res] * NoiseInjectionCompensation1D [res]; signal *= NoiseInjectionCompensation1D [res] * NoiseInjectionCompensation1D [res]; // Utilization of SNRcomp only if SNR > 1 !!! return signal > error ? error / (SNRcomp * signal) : error / signal; } float ISNR_Schaetzer_Trans ( const float* input, const float SNRcomp, const int res ) { int k; float fac = A [res]; float invfac = C [res]; float signal, error, ret, err, sig; // Summation of the absolute power and the quadratic error k = 0; signal = error = 1.e-30f; for ( ; k < 12; k++ ) { sig = input[k] * NoiseInjectionCompensation1D [res]; err = mpc_nearbyintf(sig * fac) * invfac - sig; error += err * err; signal += sig * sig; } err = signal > error ? error / (SNRcomp * signal) : error / signal; ret = err; signal = error = 1.e-30f; for ( ; k < 24; k++ ) { sig = input[k] * NoiseInjectionCompensation1D [res]; err = mpc_nearbyintf(sig * fac) * invfac - sig; error += err * err; signal += sig * sig; } err = signal > error ? error / (SNRcomp * signal) : error / signal; ret = maxf(ret, err); signal = error = 1.e-30f; for ( ; k < 36; k++ ) { sig = input[k] * NoiseInjectionCompensation1D [res]; err = mpc_nearbyintf(sig * fac) * invfac - sig; error += err * err; signal += sig * sig; } err = signal > error ? error / (SNRcomp * signal) : error / signal; ret = maxf(ret, err); return ret; } // Linear quantizer for a subband void QuantizeSubband ( mpc_int16_t* qu_output, const float* input, const int res, float* errors, const int maxNsOrder ) { int n, quant; int offset = D [res]; float mult = A [res] * NoiseInjectionCompensation1D [res]; float invmult = C [res]; float signal; for ( n = 0; n < 36 - maxNsOrder; n++) { quant = (unsigned int)(mpc_lrintf(input[n] * mult) + offset); // limitation to 0...2D if ((unsigned int)quant > (unsigned int)offset * 2 ) { quant = mini ( quant, offset * 2 ); quant = maxi ( quant, 0 ); } qu_output[n] = quant; } for ( ; n < 36; n++) { signal = input[n] * mult; quant = (unsigned int)(mpc_lrintf(signal) + offset); // calculate the current error and save it for error refeeding errors [n + 6] = invmult * (quant - offset) - signal * NoiseInjectionCompensation1D [res]; // limitation to 0...2D if ((unsigned int)quant > (unsigned int)offset * 2 ) { quant = mini ( quant, offset * 2 ); quant = maxi ( quant, 0 ); } qu_output[n] = quant; } } // NoiseShaper for a subband void QuantizeSubbandWithNoiseShaping ( mpc_int16_t* qu_output, const float* input, const int res, float* errors, const float* FIR ) { float signal; float mult = A [res]; float invmult = C [res]; int offset = D [res]; int n, quant; memset(errors, 0, 6 * sizeof *errors); // arghh, it produces pops on each frame boundary! for ( n = 0; n < 36; n++) { signal = input[n] * NoiseInjectionCompensation1D [res] - (FIR[5]*errors[n+0] + FIR[4]*errors[n+1] + FIR[3]*errors[n+2] + FIR[2]*errors[n+3] + FIR[1]*errors[n+4] + FIR[0]*errors[n+5]); quant = mpc_lrintf(signal * mult); // calculate the current error and save it for error refeeding errors [n + 6] = invmult * quant - signal * NoiseInjectionCompensation1D [res]; // limitation to +/-D quant = minf ( quant, +offset ); quant = maxf ( quant, -offset ); qu_output[n] = (unsigned int)(quant + offset); } } /* end of quant.c */ // pfk@schnecke.offl.uni-jena.de@EMAIL, Andree.Buschmann@web.de@EMAIL, BuschmannA@becker.de@EMAIL, miyaguch@eskimo.com@EMAIL, r3mix@irc.openprojects.net@EMAIL, dibrom@users.sourceforge.net@EMAIL, m.p.bakker-10@student.utwente.nl@EMAIL, djmrob@essex.ac.uk@EMAIL, dim@psytel-research.co.yu@EMAIL, lerch@zplane.de@EMAIL, takehiro@users.sourceforge.net@EMAIL, aleidinger@users.sourceforge.net@EMAIL, Robert.Hegemann@gmx.de@EMAIL, bouvigne@mp3-tech.org@EMAIL, monty@xiph.org@EMAIL, Pumpkinz99@aol.com@EMAIL, spase@outerspase.net@EMAIL, mt@wildpuppy.com@EMAIL, juha.laaksonheimo@tut.fi@EMAIL, speek@myrealbox.com@EMAIL, w.speek@12move.nl@EMAIL, martin@spueler.de@EMAIL, nicolaus.berglmeir@t-online.de@EMAIL, thomas.a.juerges@ruhr-uni-bochum.de@EMAIL, HelH@mpex.net@EMAIL, garf@roadum.demon.co.uk@EMAIL, gcp@sjeng.org@EMAIL, mike@naivesoftware.com@EMAIL, case@mobiili.net@EMAIL, steve.lhomme@free.fr@EMAIL, walter@binity.com@EMAIL musepack_src_r495/libmpcenc/encode_sv7.c0000664000000000000000000003466112231315357017170 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include #include #include "libmpcenc.h" #include void Klemm ( void ); void Init_Skalenfaktoren ( void ); // huffsv7.c extern Huffman_t const HuffBands [33]; extern Huffman_t const HuffRes [2][17]; extern Huffman_t const HuffSCFI_1 [4]; // contains tables for SV7-scalefactor select extern Huffman_t const HuffSCFI_2 [16]; // contains tables for SV7-scalefactor select extern Huffman_t const HuffDSCF_1 [64]; // contains tables for SV7-scalefactor coding extern Huffman_t const HuffDSCF_2 [65]; // contains tables for SV7-scalefactor coding extern Huffman_t const * const HuffQ [2][8]; // points to tables for SV7-sample coding extern Huffman_t const HuffQ9up [256]; /* * SV1: DATE 13.12.1998 * SV2: DATE 12.06.1999 * SV3: DATE 19.10.1999 * SV4: DATE 20.10.1999 * SV5: DATE 18.06.2000 * SV6: DATE 10.08.2000 * SV7: DATE 23.08.2000 * SV7.f: DATE 20.07.2002 */ // initialize SV8 void mpc_encoder_init ( mpc_encoder_t * e, mpc_uint64_t SamplesInWAVE, unsigned int FramesBlockPwr, unsigned int SeekDistance ) { Init_Skalenfaktoren (); Klemm (); memset(e, 0, sizeof(*e)); if (SeekDistance > 15) SeekDistance = 1; if (FramesBlockPwr > 14) FramesBlockPwr = 6; e->seek_pwr = SeekDistance; e->frames_per_block_pwr = FramesBlockPwr; if (SamplesInWAVE == 0) e->seek_table = malloc((1 << 16) * sizeof(mpc_uint32_t)); else e->seek_table = malloc((size_t)(2 + SamplesInWAVE / (MPC_FRAME_LENGTH << (e->seek_pwr + e->frames_per_block_pwr))) * sizeof(mpc_uint32_t)); e->buffer = malloc(MAX_FRAME_SIZE * (1 << e->frames_per_block_pwr) * sizeof(mpc_uint8_t)); } void mpc_encoder_exit ( mpc_encoder_t * e ) { free(e->seek_table); free(e->buffer); } // writes replay gain info void writeGainInfo ( mpc_encoder_t * e, unsigned short t_gain, unsigned short t_peak, unsigned short a_gain, unsigned short a_peak) { writeBits ( e, 1, 8 ); // version writeBits ( e, t_gain, 16 ); // Title gain writeBits ( e, t_peak, 16 ); // Title peak writeBits ( e, a_gain, 16 ); // Album gain writeBits ( e, a_peak, 16 ); // Album peak } // writes SV8-header void writeStreamInfo ( mpc_encoder_t*e, const unsigned int MaxBand, const unsigned int MS_on, const unsigned int SamplesCount, const unsigned int SamplesSkip, const unsigned int SampleFreq, const unsigned int ChannelCount) { unsigned char tmp[10]; int i, len; writeBits ( e, 8, 8 ); // StreamVersion len = encodeSize(SamplesCount, (char *)tmp, MPC_FALSE); for( i = 0; i < len; i++) // nb of samples writeBits ( e, tmp[i], 8 ); len = encodeSize(SamplesSkip, (char *)tmp, MPC_FALSE); for( i = 0; i < len; i++) // nb of samples to skip at beginning writeBits ( e, tmp[i], 8 ); switch ( SampleFreq ) { case 44100: writeBits ( e, 0, 3 ); break; case 48000: writeBits ( e, 1, 3 ); break; case 37800: writeBits ( e, 2, 3 ); break; case 32000: writeBits ( e, 3, 3 ); break; default : fprintf(stderr, "Internal error\n");// FIXME : stderr_printf ( "Internal error\n"); exit (1); } writeBits ( e, MaxBand - 1 , 5 ); // Bandwidth writeBits ( e, ChannelCount - 1 , 4 ); // Channels writeBits ( e, MS_on , 1 ); // MS-Coding Flag writeBits ( e, e->frames_per_block_pwr >> 1, 3 ); // frames per block (log4 unit) } // writes encoder signature void writeEncoderInfo ( mpc_encoder_t * e, const float profile, const int PNS_on, const int version_major, const int version_minor, const int version_build ) { writeBits ( e, (mpc_uint32_t)(profile * 8 + .5), 7 ); writeBits ( e, PNS_on, 1 ); writeBits ( e, version_major, 8 ); writeBits ( e, version_minor, 8 ); writeBits ( e, version_build, 8 ); } // formatting and writing SV8-bitstream for one frame void writeBitstream_SV8 ( mpc_encoder_t* e, int MaxBand) { int n; const Huffman_t * Table, * Tables[2]; mpc_int32_t * Res_L = e->Res_L; mpc_int32_t * Res_R = e->Res_R; mpc_bool_t * DSCF_Flag_L = e->DSCF_Flag_L; mpc_bool_t * DSCF_Flag_R = e->DSCF_Flag_R; mpc_int32_t * SCF_Last_L = e->SCF_Last_L; mpc_int32_t * SCF_Last_R = e->SCF_Last_R; for( n = MaxBand; n >= 0; n--) if (Res_L[n] != 0 || Res_R[n] != 0) break; n++; if (e->framesInBlock == 0) { encodeLog(e, n, MaxBand + 1); MaxBand = e->MaxBand = n; } else { n = n - e->MaxBand; MaxBand = e->MaxBand = n + e->MaxBand; if (n < 0) n += 33; writeBits(e, HuffBands[n].Code, HuffBands[n].Length); } /************************************ Resolution *********************************/ if (MaxBand) { { int tmp = Res_L[MaxBand - 1]; if (tmp < 0) tmp += 17; writeBits(e, HuffRes[0][tmp].Code, HuffRes[0][tmp].Length); tmp = Res_R[MaxBand - 1]; if (tmp < 0) tmp += 17; writeBits(e, HuffRes[0][tmp].Code, HuffRes[0][tmp].Length); } for ( n = MaxBand - 2; n >= 0; n--) { int tmp = Res_L[n] - Res_L[n + 1]; if (tmp < 0) tmp += 17; writeBits(e, HuffRes[Res_L[n + 1] > 2][tmp].Code, HuffRes[Res_L[n + 1] > 2][tmp].Length); tmp = Res_R[n] - Res_R[n + 1]; if (tmp < 0) tmp += 17; writeBits(e, HuffRes[Res_R[n + 1] > 2][tmp].Code, HuffRes[Res_R[n + 1] > 2][tmp].Length); } if (e->MS_Channelmode > 0) { mpc_uint32_t tmp = 0; int cnt = 0, tot = 0; mpc_bool_t * MS_Flag = e->MS_Flag; for( n = 0; n < MaxBand; n++) { if ( Res_L[n] != 0 || Res_R[n] != 0 ) { tmp = (tmp << 1) | MS_Flag[n]; cnt += MS_Flag[n]; tot++; } } encodeLog(e, cnt, tot); if (cnt * 2 > tot) tmp = ~tmp; encodeEnum(e, tmp, tot); } } /************************************ SCF encoding type ***********************************/ if (e->framesInBlock == 0){ for( n = 0; n < 32; n++) DSCF_Flag_L[n] = DSCF_Flag_R[n] = 1; // new block -> force key frame } Tables[0] = HuffSCFI_1; Tables[1] = HuffSCFI_2; for ( n = 0; n < MaxBand; n++ ) { int tmp = 0, cnt = -1; if (Res_L[n]) { tmp = (e->SCF_Index_L[n][1] == e->SCF_Index_L[n][0]) * 2 + (e->SCF_Index_L[n][2] == e->SCF_Index_L[n][1]); cnt++; } if (Res_R[n]) { tmp = (tmp << 2) | ((e->SCF_Index_R[n][1] == e->SCF_Index_R[n][0]) * 2 + (e->SCF_Index_R[n][2] == e->SCF_Index_R[n][1])); cnt++; } if (cnt >= 0) writeBits(e, Tables[cnt][tmp].Code, Tables[cnt][tmp].Length); } /************************************* SCF **********************************/ for ( n = 0; n < MaxBand; n++ ) { if ( Res_L[n] ) { int m; mpc_int32_t * SCFI_L_n = e->SCF_Index_L[n]; if (DSCF_Flag_L[n] == 1) { writeBits(e, SCFI_L_n[0] + 6, 7); DSCF_Flag_L[n] = 0; } else { unsigned int tmp = (SCFI_L_n[0] - SCF_Last_L[n] + 31) & 127; if (tmp < 64) writeBits(e, HuffDSCF_2[tmp].Code, HuffDSCF_2[tmp].Length); else { writeBits(e, HuffDSCF_2[64].Code, HuffDSCF_2[64].Length); writeBits(e, tmp - 64, 6); } } for( m = 0; m < 2; m++){ if (SCFI_L_n[m+1] != SCFI_L_n[m]) { unsigned int tmp = (SCFI_L_n[m+1] - SCFI_L_n[m] + 31) & 127; if (tmp < 64) writeBits(e, HuffDSCF_1[tmp].Code, HuffDSCF_1[tmp].Length); else { writeBits(e, HuffDSCF_1[31].Code, HuffDSCF_1[31].Length); writeBits(e, tmp - 64, 6); } } } SCF_Last_L[n] = SCFI_L_n[2]; } if ( Res_R[n] ) { int m; mpc_int32_t * SCFI_R_n = e->SCF_Index_R[n]; if (DSCF_Flag_R[n] == 1) { writeBits(e, SCFI_R_n[0] + 6, 7); DSCF_Flag_R[n] = 0; } else { unsigned int tmp = (SCFI_R_n[0] - SCF_Last_R[n] + 31) & 127; if (tmp < 64) writeBits(e, HuffDSCF_2[tmp].Code, HuffDSCF_2[tmp].Length); else { writeBits(e, HuffDSCF_2[64].Code, HuffDSCF_2[64].Length); writeBits(e, tmp - 64, 6); } } for( m = 0; m < 2; m++){ if (SCFI_R_n[m+1] != SCFI_R_n[m]) { unsigned int tmp = (SCFI_R_n[m+1] - SCFI_R_n[m] + 31) & 127; if (tmp < 64) writeBits(e, HuffDSCF_1[tmp].Code, HuffDSCF_1[tmp].Length); else { writeBits(e, HuffDSCF_1[31].Code, HuffDSCF_1[31].Length); writeBits(e, tmp - 64, 6); } } } SCF_Last_R[n] = SCFI_R_n[2]; } } /*********************************** Samples *********************************/ for ( n = 0; n < MaxBand; n++ ) { int Res = Res_L[n]; const mpc_int16_t * q = e->Q[n].L; static const unsigned int thres[] = {0, 0, 3, 7, 9, 1, 3, 4, 8}; static const int HuffQ2_var[5*5*5] = {6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6}; do { int k = 0, idx = 1, cnt = 0, sng; switch ( Res ) { case -1: case 0: break; case 1: Table = HuffQ [0][0]; for( ; k < 36; ){ int kmax = k + 18; cnt = 0, sng = 0; for ( ; k < kmax; k++) { idx <<= 1; if (q[k] != 1) { cnt++; idx |= 1; sng = (sng << 1) | (q[k] >> 1); } } writeBits(e, Table[cnt].Code, Table[cnt].Length); if (cnt > 0) { if (cnt > 9) idx = ~idx; encodeEnum(e, idx, 18); writeBits(e, sng, cnt); } } break; case 2: Tables[0] = HuffQ [0][1]; Tables[1] = HuffQ [1][1]; idx = 2 * thres[Res]; for ( ; k < 36; k += 3) { int tmp = q[k] + 5*q[k+1] + 25*q[k+2]; writeBits ( e, Tables[idx > thres[Res]][tmp].Code, Tables[idx > thres[Res]][tmp].Length ); idx = (idx >> 1) + HuffQ2_var[tmp]; } break; case 3: case 4: Table = HuffQ [0][Res - 1]; for ( ; k < 36; k += 2 ) { int tmp = q[k] + thres[Res]*q[k+1]; writeBits ( e, Table[tmp].Code, Table[tmp].Length ); } break; case 5: case 6: case 7: case 8: Tables[0] = HuffQ [0][Res - 1]; Tables[1] = HuffQ [1][Res - 1]; idx = 2 * thres[Res]; for ( ; k < 36; k++ ) { int tmp = q[k] - (1 << (Res - 2)) + 1; writeBits ( e, Tables[idx > thres[Res]][q[k]].Code, Tables[idx > thres[Res]][q[k]].Length ); if (tmp < 0) tmp = -tmp; idx = (idx >> 1) + tmp; } break; default: for ( ; k < 36; k++ ) { writeBits ( e, HuffQ9up[q[k] >> (Res - 9)].Code, HuffQ9up[q[k] >> (Res - 9)].Length ); if (Res != 9) writeBits ( e, q[k] & ((1 << (Res - 9)) - 1), Res - 9); } break; } Res = Res_R[n]; } while (q == e->Q[n].L && (q = e->Q[n].R)); } e->framesInBlock++; if (e->framesInBlock == (1 << e->frames_per_block_pwr)) { if ((e->block_cnt & ((1 << e->seek_pwr) - 1)) == 0) { e->seek_table[e->seek_pos] = ftell(e->outputFile); e->seek_pos++; } e->block_cnt++; writeBlock(e, "AP", MPC_FALSE, 0); } } #if 0 typedef struct { int Symbol; unsigned int Count; unsigned int Code; unsigned int Bits; } huff_sym_t; void _Huffman_MakeTree( huff_sym_t *sym, unsigned int num_symbols); void _Huffman_PrintCodes(huff_sym_t * sym, unsigned int num_symbols, int print_type, int offset); void print_histo(void) { int i, j; huff_sym_t sym[HISTO_NB][HISTO_LEN]; unsigned int dist[HISTO_NB]; unsigned int size[HISTO_NB]; unsigned int cnt[HISTO_NB]; unsigned int total_cnt, total_size, full_count = 0, full_size = 0; double optim_size, full_optim = 0; return; memset(dist, 1, sizeof dist); memset(sym, 0, sizeof(huff_sym_t) * HISTO_LEN * HISTO_NB); for(j = 0 ; j < HISTO_NB ; j++) { for(i = 0 ; i < HISTO_LEN; i++) { sym[j][i].Symbol = i; sym[j][i].Count = histo[j][i]; if (sym[j][i].Count == 0) sym[j][i].Count = 1; } _Huffman_MakeTree(sym[j], HISTO_LEN); _Huffman_PrintCodes(sym[j], HISTO_LEN, 3, 0); _Huffman_PrintCodes(sym[j], HISTO_LEN, 0, 0); _Huffman_PrintCodes(sym[j], HISTO_LEN, 1, 0); total_cnt = 0; total_size = 0; optim_size = 0; for( i = 0; i < HISTO_LEN; i++) { total_cnt += sym[j][i].Count; total_size += sym[j][i].Count * sym[j][i].Bits; if (sym[j][i].Count != 0) optim_size += sym[j][i].Count * __builtin_log2(sym[j][i].Count); } full_count += total_cnt; full_size += total_size; optim_size = total_cnt * __builtin_log2(total_cnt) - optim_size; full_optim += optim_size; size[j] = total_size; cnt[j] = total_cnt; printf("%u count : %u huff : %f bps ", j, total_cnt, (float)total_size / total_cnt); printf("opt : %f bps ", (float)optim_size / total_cnt); printf("loss : %f bps (%f %%)\n", (float)(total_size - optim_size) / total_cnt, (float)(total_size - optim_size) * 100 / optim_size); for( i = 0; i < HISTO_LEN; i++){ printf("%u ", sym[j][i].Bits); } printf("\n\n"); } printf("cnt : %u size %f optim %f\n", full_count, (float)full_size / full_count, (float)full_optim / full_count); printf("loss : %f bps (%f %%)\n", (float)(full_size - full_optim) / full_count, (float)(full_size - full_optim) * 100 / full_optim); printf("\n"); } void Dump ( const unsigned int* q, const int Res ) { switch ( Res ) { case 1: for ( k = 0; k < 36; k++, q++ ) printf ("%2d%c", *q-1, k==35?'\n':' '); break; case 2: for ( k = 0; k < 36; k++, q++ ) printf ("%2d%c", *q-2, k==35?'\n':' '); break; case 3: case 4: case 5: case 6: case 7: if ( Res == 5 ) for ( k = 0; k < 36; k++, q++ ) printf ("%2d%c", *q-7, k==35?'\n':' '); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: printf ("%2u: ", Res-1 ); for ( k = 0; k < 36; k++, q++ ) { printf ("%6d", *q - (1 << (Res-2)) ); } printf ("\n"); break; } } #endif /* end of encode_sv7.c */ musepack_src_r495/include/0000775000000000000000000000000012765302354014452 5ustar rootrootmusepack_src_r495/include/Makefile.am0000664000000000000000000000035410607476770016517 0ustar rootroot## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign nobase_include_HEADERS = \ mpc/datatypes.h \ mpc/minimax.h \ mpc/mpcmath.h \ mpc/mpc_types.h \ mpc/mpcdec.h \ mpc/reader.h \ mpc/streaminfo.h musepack_src_r495/include/mpc/0000775000000000000000000000000012765302354015231 5ustar rootrootmusepack_src_r495/include/mpc/mpcdec.h0000664000000000000000000001405312645277514016646 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file mpcdec.h /// Top level include file for libmpcdec. #ifndef _MPCDEC_H_ #define _MPCDEC_H_ #ifdef WIN32 #pragma once #endif #include "reader.h" #include "streaminfo.h" #ifdef __cplusplus extern "C" { #endif enum { MPC_FRAME_LENGTH = (36 * 32), ///< Samples per mpc frame MPC_DECODER_BUFFER_LENGTH = (MPC_FRAME_LENGTH * 4), ///< Required buffer size for decoder MPC_DECODER_SYNTH_DELAY = 481 }; typedef struct mpc_decoder_t mpc_decoder; typedef struct mpc_demux_t mpc_demux; typedef struct mpc_bits_reader_t { unsigned char * buff; /// pointer on current byte unsigned int count; /// unread bits in current byte } mpc_bits_reader; typedef struct mpc_frame_info_t { mpc_uint32_t samples; /// number of samples in the frame (counting once for multiple channels) mpc_int32_t bits; /// number of bits consumed by this frame (-1) if end of stream MPC_SAMPLE_FORMAT * buffer; /// frame samples buffer (size = samples * channels * sizeof(MPC_SAMPLE_FORMAT)) mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer. } mpc_frame_info; typedef struct mpc_chap_info_t { mpc_uint64_t sample; /// sample where the chapter starts mpc_uint16_t gain; /// replaygain chapter value mpc_uint16_t peak; /// peak chapter loudness level mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter) char * tag; /// pointer to an APEv2 tag without the preamble } mpc_chap_info; /// Initializes mpc decoder with the supplied stream info parameters. /// \param si streaminfo structure indicating format of source stream /// \return pointer on the initialized decoder structure if successful, 0 if not MPC_API mpc_decoder * mpc_decoder_init(mpc_streaminfo *si); /// Releases input mpc decoder MPC_API void mpc_decoder_exit(mpc_decoder *p_dec); /** * Sets decoder sample scaling factor. All decoded samples will be multiplied * by this factor. Useful for applying replay gain. * @param scale_factor multiplicative scaling factor */ MPC_API void mpc_decoder_scale_output(mpc_decoder *p_dec, double scale_factor); MPC_API void mpc_decoder_decode_frame(mpc_decoder * d, mpc_bits_reader * r, mpc_frame_info * i); // This is the gain reference used in old replaygain #define MPC_OLD_GAIN_REF 64.82 /** * init demuxer * @param p_reader initialized mpc_reader pointer * @return an initialized mpc_demux pointer */ MPC_API mpc_demux * mpc_demux_init(mpc_reader * p_reader); /// free demuxer MPC_API void mpc_demux_exit(mpc_demux * d); /** * Calls mpc_decoder_scale_output to set the scaling factor according to the * replay gain stream information and the supplied ouput level * @param d pointer to a musepack demuxer * @param level the desired ouput level (in db). Must be MPC_OLD_GAIN_REF (64.82 db) if you want to get the old replaygain behavior * @param use_gain set it to MPC_TRUE if you want to set the scaling factor according to the stream gain * @param use_title MPC_TRUE : uses the title gain, MPC_FALSE : uses the album gain * @param clip_prevention MPC_TRUE : uses cliping prevention */ MPC_API void mpc_set_replay_level(mpc_demux * d, float level, mpc_bool_t use_gain, mpc_bool_t use_title, mpc_bool_t clip_prevention); /// decode frame MPC_API mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i); /// decode frame : use mpc_demux_decode() instead. This function is only used by mpc2sv8. MPC_API mpc_status mpc_demux_decode_inner(mpc_demux * d, mpc_frame_info * i); /// get streaminfo MPC_API void mpc_demux_get_info(mpc_demux * d, mpc_streaminfo * i); /// seeks to a given sample MPC_API mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_uint64_t destsample); /// seeks to a given second MPC_API mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds); /// \return the current position in the stream (in bits) from the beginning of the file MPC_API mpc_seek_t mpc_demux_pos(mpc_demux * d); /// chapters : only for sv8 streams /** * Gets the number of chapters in the stream * @param d pointer to a musepack demuxer * @return the number of chapters found in the stream */ MPC_API mpc_int_t mpc_demux_chap_nb(mpc_demux * d); /** * Gets datas associated to a given chapter * The chapter tag is an APEv2 tag without the preamble * @param d pointer to a musepack demuxer * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) * @return the chapter information structure */ MPC_API mpc_chap_info const * mpc_demux_chap(mpc_demux * d, int chap_nb); #ifdef __cplusplus } #endif #endif musepack_src_r495/include/mpc/minimax.h0000664000000000000000000000321712231315357017042 0ustar rootroot/* * Musepack audio compression * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #pragma once # define clip(x,min,max) ( (x) < (min) ? (min) : (x) > (max) ? (max) : (x) ) #ifdef __cplusplus # define maxi(A,B) ( (A) >? (B) ) # define mini(A,B) ( (A) ? (B) ) # define mind(A,B) ( (A) ? (B) ) # define minf(A,B) ( (A) (B) ? (A) : (B) ) # define mini(A,B) ( (A) < (B) ? (A) : (B) ) # define maxd(A,B) ( (A) > (B) ? (A) : (B) ) # define mind(A,B) ( (A) < (B) ? (A) : (B) ) # define maxf(A,B) ( (A) > (B) ? (A) : (B) ) # define minf(A,B) ( (A) < (B) ? (A) : (B) ) #endif #ifdef __GNUC__ # define absi(A) abs (A) # define absf(A) fabsf (A) # define absd(A) fabs (A) #else # define absi(A) ( (A) >= 0 ? (A) : -(A) ) # define absf(A) ( (A) >= 0.f ? (A) : -(A) ) # define absd(A) ( (A) >= 0. ? (A) : -(A) ) #endif musepack_src_r495/include/mpc/mpcmath.h0000664000000000000000000001073312231315357017032 0ustar rootroot/* * Musepack audio compression * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include #include typedef union mpc_floatint { float f; mpc_int32_t n; } mpc_floatint; typedef union mpc_doubleint { double d; mpc_int32_t n[2]; } mpc_doubleint; static mpc_inline mpc_int32_t mpc_lrintf(float fVal) { mpc_floatint tmp; tmp.f = fVal + 0x00FF8000; return tmp.n - 0x4B7F8000; } #define mpc_round32 mpc_lrintf #define mpc_nearbyintf mpc_lrintf #ifndef M_PI # define M_PI 3.1415926535897932384626433832795029 // 4*atan(1) # define M_PIl 3.1415926535897932384626433832795029L # define M_LN2 0.6931471805599453094172321214581766 // ln(2) # define M_LN2l 0.6931471805599453094172321214581766L # define M_LN10 2.3025850929940456840179914546843642 // ln 10 */ # define M_LN10l 2.3025850929940456840179914546843642L #endif // fast but maybe more inaccurate, use if you need speed #if defined(__GNUC__) && !defined(__APPLE__) # define SIN(x) sinf ((float)(x)) # define COS(x) cosf ((float)(x)) # define ATAN2(x,y) atan2f ((float)(x), (float)(y)) # define SQRT(x) sqrtf ((float)(x)) # define LOG(x) logf ((float)(x)) # define LOG10(x) log10f ((float)(x)) # define POW(x,y) expf (logf(x) * (y)) # define POW10(x) expf (M_LN10 * (x)) # define FLOOR(x) floorf ((float)(x)) # define IFLOOR(x) (int) floorf ((float)(x)) # define FABS(x) fabsf ((float)(x)) #else # define SIN(x) (float) sin (x) # define COS(x) (float) cos (x) # define ATAN2(x,y) (float) atan2 (x, y) # define SQRT(x) (float) sqrt (x) # define LOG(x) (float) log (x) # define LOG10(x) (float) log10 (x) # define POW(x,y) (float) pow (x,y) # define POW10(x) (float) pow (10., (x)) # define FLOOR(x) (float) floor (x) # define IFLOOR(x) (int) floor (x) # define FABS(x) (float) fabs (x) #endif #define SQRTF(x) SQRT (x) #ifdef FAST_MATH # define TABSTEP 64 # define COSF(x) my_cos ((float)(x)) # define ATAN2F(x,y) my_atan2 ((float)(x), (float)(y)) # define IFLOORF(x) my_ifloor ((float)(x)) void Init_FastMath ( void ); extern const float tabatan2 [] [2]; extern const float tabcos [] [2]; extern const float tabsqrt_ex []; extern const float tabsqrt_m [] [2]; static mpc_inline float my_atan2 ( float x, float y ) { float t, ret; int i; mpc_floatint mx, my; mx.f = x; my.f = y; if ( (mx.n & 0x7FFFFFFF) < (my.n & 0x7FFFFFFF) ) { i = mpc_round32 (t = TABSTEP * (mx.f / my.f)); ret = tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (t-i); if ( my.n < 0 ) ret = (float)(ret - M_PI); } else if ( mx.n < 0 ) { i = mpc_round32 (t = TABSTEP * (my.f / mx.f)); ret = - M_PI/2 - tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (i-t); } else if ( mx.n > 0 ) { i = mpc_round32 (t = TABSTEP * (my.f / mx.f)); ret = + M_PI/2 - tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (i-t); } else { ret = 0.; } return ret; } static mpc_inline float my_cos ( float x ) { float t, ret; int i; i = mpc_round32 (t = TABSTEP * x); ret = tabcos [13*TABSTEP+i][0] + tabcos [13*TABSTEP+i][1] * (t-i); return ret; } static mpc_inline int my_ifloor ( float x ) { mpc_floatint mx; mx.f = (float) (x + (0x0C00000L + 0.500000001)); return mx.n - 1262485505; } static mpc_inline float my_sqrt ( float x ) { float ret; int i, ex; mpc_floatint mx; mx.f = x; ex = mx.n >> 23; // get the exponent mx.n = (mx.n & 0x7FFFFF) | 0x42800000; // delete the exponent i = mpc_round32 (mx.f); // Integer-part of the mantissa (round ????????????) ret = tabsqrt_m [i-TABSTEP][0] + tabsqrt_m [i-TABSTEP][1] * (mx.f-i); // calculate value ret *= tabsqrt_ex [ex]; return ret; } #else # define COSF(x) COS (x) # define ATAN2F(x,y) ATAN2 (x,y) # define IFLOORF(x) IFLOOR (x) #endif musepack_src_r495/include/mpc/streaminfo.h0000664000000000000000000001062111150567164017550 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file streaminfo.h #ifndef _MPCDEC_STREAMINFO_H_ #define _MPCDEC_STREAMINFO_H_ #ifdef WIN32 #pragma once #endif #include #ifdef __cplusplus extern "C" { #endif typedef mpc_int32_t mpc_streaminfo_off_t; /// \brief mpc stream properties structure /// /// Structure containing all the properties of an mpc stream. Populated /// by the streaminfo_read function. typedef struct mpc_streaminfo { /// @name Core mpc stream properties //@{ mpc_uint32_t sample_freq; ///< Sample frequency of stream mpc_uint32_t channels; ///< Number of channels in stream mpc_uint32_t stream_version; ///< Streamversion of stream mpc_uint32_t bitrate; ///< Bitrate of stream file (in bps) double average_bitrate; ///< Average bitrate of stream (in bits/sec) mpc_uint32_t max_band; ///< Maximum band-index used in stream (0...31) mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on) mpc_uint32_t fast_seek; ///< True if stream supports fast-seeking (sv7) mpc_uint32_t block_pwr; ///< Number of frames in a block = 2^block_pwr (sv8) //@} /// @name Replaygain properties //@{ mpc_uint16_t gain_title; ///< Replaygain title value mpc_uint16_t gain_album; ///< Replaygain album value mpc_uint16_t peak_album; ///< Peak album loudness level mpc_uint16_t peak_title; ///< Peak title loudness level //@} /// @name True gapless properties //@{ mpc_uint32_t is_true_gapless; ///< True gapless? (0: no, 1: yes) mpc_uint64_t samples; ///< Number of samples in the stream mpc_uint64_t beg_silence; ///< Number of samples that must not be played at the beginning of the stream //@} /// @name Encoder informations //@{ mpc_uint32_t encoder_version; ///< Version of encoder used char encoder[256]; ///< Encoder name mpc_bool_t pns; ///< pns used float profile; ///< Quality profile of stream const char* profile_name; ///< Name of profile used by stream //@} mpc_streaminfo_off_t header_position; ///< Byte offset of position of header in stream mpc_streaminfo_off_t tag_offset; ///< Offset to file tags mpc_streaminfo_off_t total_file_length; ///< Total length of underlying file } mpc_streaminfo; /// Gets length of stream si, in seconds. /// \return length of stream in seconds MPC_API double mpc_streaminfo_get_length(mpc_streaminfo *si); /// Returns length of stream si, in samples. /// \return length of stream in samples MPC_API mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); #ifdef __cplusplus } #endif #endif musepack_src_r495/include/mpc/reader.h0000664000000000000000000000701211150567164016643 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /// \file reader.h #ifndef _MPCDEC_READER_H_ #define _MPCDEC_READER_H_ #ifdef WIN32 #pragma once #endif #include #include #ifdef __cplusplus extern "C" { #endif /// \brief Stream reader interface structure. /// /// This is the structure you must supply to the musepack decoding library /// to feed it with raw data. Implement the five member functions to provide /// a functional reader. typedef struct mpc_reader_t mpc_reader; struct mpc_reader_t { /// Reads size bytes of data into buffer at ptr. mpc_int32_t (*read)(mpc_reader *p_reader, void *ptr, mpc_int32_t size); /// Seeks to byte position offset. mpc_bool_t (*seek)(mpc_reader *p_reader, mpc_int32_t offset); /// Returns the current byte offset in the stream. mpc_int32_t (*tell)(mpc_reader *p_reader); /// Returns the total length of the source stream, in bytes. mpc_int32_t (*get_size)(mpc_reader *p_reader); /// True if the stream is a seekable stream. mpc_bool_t (*canseek)(mpc_reader *p_reader); /// Field that can be used to identify a particular instance of /// reader or carry along data associated with that reader. void *data; }; /// Initializes reader with default stdio file reader implementation. Use /// this if you're just reading from a plain file. /// /// \param r p_reader handle to initialize /// \param filename input filename to attach to the reader MPC_API mpc_status mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename); /// Initializes reader with default stdio file reader implementation. Use /// this if you prefer to open the file yourself. /// /// \param r p_reader handle to initialize /// \param p_file input file handle (already open) MPC_API mpc_status mpc_reader_init_stdio_stream(mpc_reader * p_reader, FILE * p_file); /// Release reader with default stdio file reader implementation. /// /// \param r reader handle to release MPC_API void mpc_reader_exit_stdio(mpc_reader *p_reader); #ifdef __cplusplus } #endif #endif musepack_src_r495/include/mpc/mpc_types.h0000664000000000000000000001033511614327766017415 0ustar rootroot/* Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _MPC_TYPES_H_ #define _MPC_TYPES_H_ #ifdef WIN32 #pragma once #endif #include #include #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER typedef __int8 mpc_int8_t; typedef unsigned __int8 mpc_uint8_t; typedef __int16 mpc_int16_t; typedef unsigned __int16 mpc_uint16_t; typedef __int32 mpc_int32_t; typedef unsigned __int32 mpc_uint32_t; typedef __int64 mpc_int64_t; typedef unsigned __int64 mpc_uint64_t; #define mpc_inline __inline #else #include typedef int8_t mpc_int8_t; typedef uint8_t mpc_uint8_t; typedef int16_t mpc_int16_t; typedef uint16_t mpc_uint16_t; typedef int32_t mpc_int32_t; typedef uint32_t mpc_uint32_t; typedef int64_t mpc_int64_t; typedef uint64_t mpc_uint64_t; #define mpc_inline inline #endif typedef int mpc_int_t; typedef unsigned int mpc_uint_t; typedef size_t mpc_size_t; typedef mpc_uint8_t mpc_bool_t; // #define LONG_SEEK_TABLE #ifdef LONG_SEEK_TABLE // define as needed (mpc_uint32_t supports files up to 512 MB) typedef mpc_uint64_t mpc_seek_t; #else typedef mpc_uint32_t mpc_seek_t; #endif # define mpc_int64_min -9223372036854775808ll # define mpc_int64_max 9223372036854775807ll typedef struct mpc_quantizer { mpc_int16_t L [36]; mpc_int16_t R [36]; } mpc_quantizer; /// Libmpcdec error codes typedef enum mpc_status { // Success. MPC_STATUS_OK = 0, // Generic failure (I/O error or invalid file). MPC_STATUS_FAIL = -1 } mpc_status; #define MPC_FIXED_POINT_SHIFT 16 #ifdef MPC_FIXED_POINT # define MPC_FIXED_POINT_FRACTPART 14 # define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART) # define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1)) typedef mpc_int32_t MPC_SAMPLE_FORMAT; #else typedef float MPC_SAMPLE_FORMAT; #endif enum { MPC_FALSE = 0, MPC_TRUE = !MPC_FALSE }; //// 'Cdecl' forces the use of standard C/C++ calling convention /////// #if defined _WIN32 # define mpc_cdecl __cdecl #elif defined __ZTC__ # define mpc_cdecl _cdecl #elif defined __TURBOC__ # define mpc_cdecl cdecl #else # define mpc_cdecl #endif /* DLL building support on win32 hosts */ #ifndef MPC_API # ifdef DLL_EXPORT /* defined by libtool (if required) */ # define MPC_API __declspec(dllexport) # endif # ifdef MPC_DLL_IMPORT /* define if linking with this dll */ # define MPC_API __declspec(dllimport) # endif # ifndef MPC_API /* static linking or !_WIN32 */ # if defined(__GNUC__) && (__GNUC__ >= 4) # define MPC_API __attribute__ ((visibility("default"))) # else # define MPC_API # endif # endif #endif #ifdef __cplusplus } #endif #endif musepack_src_r495/include/mpc/datatypes.h0000664000000000000000000000223012231315357017370 0ustar rootroot/* * Musepack audio compression * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #pragma once // mpcenc.h #define CENTER 448 // offset for centering current data in Main-array #define BLOCK 1152 // blocksize #define ANABUFFER (BLOCK + CENTER) // size of PCM-data array for analysis typedef struct { float L [36]; float R [36]; } SubbandFloatTyp; typedef struct { float L [ANABUFFER]; float R [ANABUFFER]; float M [ANABUFFER]; float S [ANABUFFER]; } PCMDataTyp; musepack_src_r495/libmpcpsy/0000775000000000000000000000000012765302354015031 5ustar rootrootmusepack_src_r495/libmpcpsy/fft4g.c0000664000000000000000000003156112231315357016210 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "libmpcpsy.h" #include /* F U N C T I O N S */ static void makewt ( const int nw, int* ip, float* w ); static void makect ( const int nc, int* ip, float* c ); # define cftmdl(n,l,a,w) cftmdl_i386 ( n, l, a, w ) /* -------- child routines -------- */ static mpc_inline void bitrv2 ( const int n, int* ip, float* a ) { int j, j1, k, k1, l, m, m2; float xr, xi, yr, yi; ip[0] = 0; l = n; m = 1; while ( (m << 3) < l ) { l >>= 1; for ( j = 0; j < m; j++ ) { ip[m + j] = ip[j] + l; } m <<= 1; } m2 = 2 * m; if ( (m << 3) == l ) { for ( k = 0; k < m; k++ ) { for ( j = 0; j < k; j++ ) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 -= m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } j1 = 2 * k + m2 + ip[k]; k1 = j1 + m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } else { for ( k = 1; k < m; k++ ) { for ( j = 0; j < k; j++ ) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } } return; } static mpc_inline void cft1st ( const int n, float* a, float* w ) { int j, k1; float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[ 0] + a[ 2]; x0i = a[ 1] + a[ 3]; x1r = a[ 0] - a[ 2]; x1i = a[ 1] - a[ 3]; x2r = a[ 4] + a[ 6]; x2i = a[ 5] + a[ 7]; x3r = a[ 4] - a[ 6]; x3i = a[ 5] - a[ 7]; a[ 0] = x0r + x2r; a[ 1] = x0i + x2i; a[ 4] = x0r - x2r; a[ 5] = x0i - x2i; a[ 2] = x1r - x3i; a[ 3] = x1i + x3r; a[ 6] = x1r + x3i; a[ 7] = x1i - x3r; wk1r = w[ 2]; x0r = a[ 8] + a[10]; x0i = a[ 9] + a[11]; x1r = a[ 8] - a[10]; x1i = a[ 9] - a[11]; x2r = a[12] + a[14]; x2i = a[13] + a[15]; x3r = a[12] - a[14]; x3i = a[13] - a[15]; a[ 8] = x0r + x2r; a[ 9] = x0i + x2i; a[12] = x2i - x0i; a[13] = x0r - x2r; x0r = x1r - x3i; x0i = x1i + x3r; a[10] = wk1r * (x0r - x0i); a[11] = wk1r * (x0r + x0i); x0r = x3i + x1r; x0i = x3r - x1i; a[14] = wk1r * (x0i - x0r); a[15] = wk1r * (x0i + x0r); k1 = 0; j = 16; do { k1 += 2; wk2r = w[k1]; wk2i = w[k1 + 1]; wk1r = w[2*k1]; wk1i = w[2*k1 + 1]; wk3r = wk1r - 2 * wk2i * wk1i; wk3i = 2 * wk2i * wk1r - wk1i; x0r = a[j] + a[j + 2]; x0i = a[j + 1] + a[j + 3]; x1r = a[j] - a[j + 2]; x1i = a[j + 1] - a[j + 3]; x2r = a[j + 4] + a[j + 6]; x2i = a[j + 5] + a[j + 7]; x3r = a[j + 4] - a[j + 6]; x3i = a[j + 5] - a[j + 7]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; x0r -= x2r; x0i -= x2i; a[j + 4] = wk2r * x0r - wk2i * x0i; a[j + 5] = wk2r * x0i + wk2i * x0r; x0r = x1r - x3i; x0i = x1i + x3r; a[j + 2] = wk1r * x0r - wk1i * x0i; a[j + 3] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j + 6] = wk3r * x0r - wk3i * x0i; a[j + 7] = wk3r * x0i + wk3i * x0r; wk1r = w[2*k1 + 2]; wk1i = w[2*k1 + 3]; wk3r = wk1r - 2 * wk2r * wk1i; wk3i = 2 * wk2r * wk1r - wk1i; x0r = a[j + 8] + a[j + 10]; x0i = a[j + 9] + a[j + 11]; x1r = a[j + 8] - a[j + 10]; x1i = a[j + 9] - a[j + 11]; x2r = a[j + 12] + a[j + 14]; x2i = a[j + 13] + a[j + 15]; x3r = a[j + 12] - a[j + 14]; x3i = a[j + 13] - a[j + 15]; a[j + 8] = x0r + x2r; a[j + 9] = x0i + x2i; x0r -= x2r; x0i -= x2i; a[j + 12] = -wk2i * x0r - wk2r * x0i; a[j + 13] = -wk2i * x0i + wk2r * x0r; x0r = x1r - x3i; x0i = x1i + x3r; a[j + 10] = wk1r * x0r - wk1i * x0i; a[j + 11] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j + 14] = wk3r * x0r - wk3i * x0i; a[j + 15] = wk3r * x0i + wk3i * x0r; } while ( j += 16, j < n ); return; } static mpc_inline void cftmdl_i386 ( const int n, const int l, float* a, float* w ) { int j, j1, j2, j3, k, k1, m, m2; float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; m = l << 2; for ( j = 0; j < l; j += 2 ) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x0r - x2r; a[j2 + 1] = x0i - x2i; a[j1] = x1r - x3i; a[j1 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; } wk1r = w[2]; for ( j = m; j < l + m; j += 2 ) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x2i - x0i; a[j2 + 1] = x0r - x2r; x0r = x1r - x3i; x0i = x1i + x3r; a[j1] = wk1r * (x0r - x0i); a[j1 + 1] = wk1r * (x0r + x0i); x0r = x3i + x1r; x0i = x3r - x1i; a[j3] = wk1r * (x0i - x0r); a[j3 + 1] = wk1r * (x0i + x0r); } k1 = 0; m2 = 2 * m; for ( k = m2; k < n; k += m2 ) { k1 += 2; wk2r = w[k1]; wk2i = w[k1 + 1]; wk1r = w[2*k1]; wk1i = w[2*k1 + 1]; wk3r = wk1r - 2 * wk2i * wk1i; wk3i = 2 * wk2i * wk1r - wk1i; j = k; do { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; x0r -= x2r; x0i -= x2i; a[j2] = wk2r * x0r - wk2i * x0i; a[j2 + 1] = wk2r * x0i + wk2i * x0r; x0r = x1r - x3i; x0i = x1i + x3r; a[j1] = wk1r * x0r - wk1i * x0i; a[j1 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r - wk3i * x0i; a[j3 + 1] = wk3r * x0i + wk3i * x0r; } while ( j += 2, j < l + k ); wk1r = w[2*k1 + 2]; wk1i = w[2*k1 + 3]; wk3r = wk1r - 2 * wk2r * wk1i; wk3i = 2 * wk2r * wk1r - wk1i; j = k + m; do { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; x0r -= x2r; x0i -= x2i; a[j2] = -wk2i * x0r - wk2r * x0i; a[j2 + 1] = -wk2i * x0i + wk2r * x0r; x0r = x1r - x3i; x0i = x1i + x3r; a[j1] = wk1r * x0r - wk1i * x0i; a[j1 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r - wk3i * x0i; a[j3 + 1] = wk3r * x0i + wk3i * x0r; } while ( j += 2, j < l+k+m ); } return; } static mpc_inline void cftfsub ( const int n, float* a, float* w ) { int j, j1, j2, j3, l; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; l = 2; if ( n > 8 ) { cft1st ( n, a, w ); l = 8; while ( (l << 2) < n ) { cftmdl ( n, l, a, w ); l <<= 2; } } if ( (l << 2) == n ) { j = 0; do { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x0r - x2r; a[j2 + 1] = x0i - x2i; a[j1] = x1r - x3i; a[j1 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; } while ( j += 2, j < l ); } else { j = 0; do { j1 = j + l; x0r = a[j] - a[j1]; x0i = a[j + 1] - a[j1 + 1]; a[j] += a[j1]; a[j + 1] += a[j1 + 1]; a[j1] = x0r; a[j1 + 1] = x0i; } while ( j += 2, j < l ); } return; } static mpc_inline void rftfsub ( const int n, float* a, int nc, float* c ) { int j, k, kk, ks, m; float wkr, wki, xr, xi, yr, yi; m = n >> 1; ks = 2 * nc / m; kk = ks; j = 2; k = n; do { k -= 2; nc -= ks; wkr = 0.5f - c[nc]; wki = c[kk]; xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; kk += ks; } while ( j += 2, j < m ); return; } // generates lookup-tables void Generate_FFT_Tables ( const int n, int* ip, float* w ) { int nw; int nc; nw = n >> 2; makewt ( nw, ip, w ); nc = n >> 2; makect ( nc, ip, w + nw ); } // patched to only-forward void rdft ( const int n, float* a, int* ip, float* w ) { float xi; if ( n > 4) { bitrv2 ( n, ip + 2, a ); cftfsub ( n, a, w ); rftfsub ( n, a, ip[1], w + ip[0] ); } else if ( n == 4 ) { cftfsub ( n, a, w ); } xi = a[0] - a[1]; a[0] += a[1]; a[1] = xi; return; } /* -------- initializing routines -------- */ static void makewt ( const int nw, int* ip, float* w ) { int j; int nwh; float x; float y; double delta; ip[0] = nw; ip[1] = 1; if ( nw > 2 ) { nwh = nw >> 1; delta = (M_PI/4) / nwh; w[0] = 1.; w[1] = 0.; w[nwh] = COS (delta * nwh); w[nwh + 1] = w[nwh]; if ( nwh > 2 ) { for ( j = 2; j < nwh; j += 2 ) { x = COS (delta * j); y = SIN (delta * j); w[j] = x; w[j + 1] = y; w[nw - j] = y; w[nw - j + 1] = x; } bitrv2 ( nw, ip + 2, w ); } } return; } static void makect ( const int nc, int* ip, float* c ) { int j; int nch; double delta; ip[1] = nc; if ( nc > 1 ) { nch = nc >> 1; delta = (M_PI/4) / nch; c[0] = COS (delta * nch); c[nch] = 0.5f * c[0]; for ( j = 1; j < nch; j++ ) { c[j] = 0.5f * COS (delta * j); c[nc - j] = 0.5f * SIN (delta * j); } } return; } /* end of fft4g.c */ musepack_src_r495/libmpcpsy/profile.c0000664000000000000000000001566512231315357016645 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "libmpcpsy.h" #include typedef struct { float ShortThr; unsigned char MinValChoice; unsigned int EarModelFlag; signed char Ltq_offset; float TMN; float NMT; signed char minSMR; signed char Ltq_max; unsigned short BandWidth; unsigned char tmpMask_used; unsigned char CVD_used; float varLtq; unsigned char MS_Channelmode; unsigned char CombPenalities; unsigned char NS_Order; float PNS; float TransDetect; } Profile_Setting_t; #define PROFILE_PRE2_TELEPHONE 5 // --quality 0 // #define PROFILE_PRE_TELEPHONE 6 // --quality 1 // #define PROFILE_TELEPHONE 7 // --quality 2 // #define PROFILE_THUMB 8 // --quality 3 // #define PROFILE_RADIO 9 // --quality 4 // #define PROFILE_STANDARD 10 // --quality 5 // #define PROFILE_XTREME 11 // --quality 6 // #define PROFILE_INSANE 12 // --quality 7 // #define PROFILE_BRAINDEAD 13 // --quality 8 // #define PROFILE_POST_BRAINDEAD 14 // --quality 9 #define PROFILE_POST2_BRAINDEAD 15 // --quality 10 static const Profile_Setting_t Profiles [16] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* Short MinVal EarModel Ltq_ min Ltq_ Band- tmpMask CVD_ varLtq MS Comb NS_ Trans */ /* Thr Choice Flag offset TMN NMT SMR max Width _used used channel Penal used PNS Det */ { 1.e9f, 1, 300, 30, 3.0, -1.0, 0, 106, 4820, 1, 1, 1., 3, 24, 6, 1.09f, 200 }, // 0: pre-Telephone { 1.e9f, 1, 300, 24, 6.0, 0.5, 0, 100, 7570, 1, 1, 1., 3, 20, 6, 0.77f, 180 }, // 1: pre-Telephone { 1.e9f, 1, 400, 18, 9.0, 2.0, 0, 94, 10300, 1, 1, 1., 4, 18, 6, 0.55f, 160 }, // 2: Telephone { 50.0f, 2, 430, 12, 12.0, 3.5, 0, 88, 13090, 1, 1, 1., 5, 15, 6, 0.39f, 140 }, // 3: Thumb { 15.0f, 2, 440, 6, 15.0, 5.0, 0, 82, 15800, 1, 1, 1., 6, 10, 6, 0.27f, 120 }, // 4: Radio { 5.0f, 2, 550, 0, 18.0, 6.5, 1, 76, 19980, 1, 2, 1., 11, 9, 6, 0.00f, 100 }, // 5: Standard { 4.0f, 2, 560, -6, 21.0, 8.0, 2, 70, 22000, 1, 2, 1., 12, 7, 6, 0.00f, 80 }, // 6: Xtreme { 3.0f, 2, 570, -12, 24.0, 9.5, 3, 64, 24000, 1, 2, 2., 13, 5, 6, 0.00f, 60 }, // 7: Insane { 2.8f, 2, 580, -18, 27.0, 11.0, 4, 58, 26000, 1, 2, 4., 13, 4, 6, 0.00f, 40 }, // 8: BrainDead { 2.6f, 2, 590, -24, 30.0, 12.5, 5, 52, 28000, 1, 2, 8., 13, 4, 6, 0.00f, 20 }, // 9: post-BrainDead { 2.4f, 2, 599, -30, 33.0, 14.0, 6, 46, 30000, 1, 2, 16., 15, 2, 6, 0.00f, 10 }, //10: post-BrainDead }; int TestProfileParams ( PsyModel* m ) { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 static signed char TMNStereoAdj [] = { -6, -18, -15, -18, -12, -9, -6, 0,0,0, +1, +1, +1, +1, 0, +1 }; // Penalties for TMN static signed char NMTStereoAdj [] = { -3, -18, -15, -15, -9, -6, -3, 0,0,0, 0, +1, +1, +1, 0, +1 }; // Penalties for NMT int i; m->MainQual = PROFILE_PRE2_TELEPHONE; for ( i = PROFILE_PRE2_TELEPHONE; i <= PROFILE_POST2_BRAINDEAD; i++ ) { if ( m->ShortThr > Profiles [i].ShortThr ) continue; if ( m->MinValChoice < Profiles [i].MinValChoice ) continue; if ( m->EarModelFlag < Profiles [i].EarModelFlag ) continue; if ( m->Ltq_offset > Profiles [i].Ltq_offset ) continue; if ( m->Ltq_max > Profiles [i].Ltq_max ) continue; // offset should normally be considered here if ( m->TMN + TMNStereoAdj [m->MS_Channelmode] < Profiles [i].TMN + TMNStereoAdj [Profiles [i].MS_Channelmode] ) continue; if ( m->NMT + NMTStereoAdj [m->MS_Channelmode] < Profiles [i].NMT + NMTStereoAdj [Profiles [i].MS_Channelmode] ) continue; if ( m->minSMR < Profiles [i].minSMR ) continue; if ( m->BandWidth < Profiles [i].BandWidth ) continue; if ( m->tmpMask_used < Profiles [i].tmpMask_used ) continue; if ( m->CVD_used < Profiles [i].CVD_used ) continue; // if ( varLtq > Profiles [i].varLtq ) continue; // if ( NS_Order < Profiles [i].NS_Order ) continue; if ( m->PNS > Profiles [i].PNS ) continue; m->MainQual = i; } return m->MainQual; } void SetQualityParams (PsyModel * m, float qual ) { int i; float mix; qual = clip(qual, 0., 10.); i = (int) qual + PROFILE_PRE2_TELEPHONE; mix = qual - (int) qual; m->MainQual = i; m->FullQual = qual + PROFILE_PRE2_TELEPHONE; m->ShortThr = Profiles [i].ShortThr * (1-mix) + Profiles [i+1].ShortThr * mix; m->MinValChoice = Profiles [i].MinValChoice ; m->EarModelFlag = Profiles [i].EarModelFlag ; m->Ltq_offset = Profiles [i].Ltq_offset * (1-mix) + Profiles [i+1].Ltq_offset * mix; m->varLtq = Profiles [i].varLtq * (1-mix) + Profiles [i+1].varLtq * mix; m->Ltq_max = Profiles [i].Ltq_max * (1-mix) + Profiles [i+1].Ltq_max * mix; m->TMN = Profiles [i].TMN * (1-mix) + Profiles [i+1].TMN * mix; m->NMT = Profiles [i].NMT * (1-mix) + Profiles [i+1].NMT * mix; m->minSMR = Profiles [i].minSMR ; m->BandWidth = Profiles [i].BandWidth * (1-mix) + Profiles [i+1].BandWidth * mix; m->tmpMask_used = Profiles [i].tmpMask_used ; m->CVD_used = Profiles [i].CVD_used ; m->MS_Channelmode = Profiles [i].MS_Channelmode; m->CombPenalities = Profiles [i].CombPenalities; m->NS_Order = Profiles [i].NS_Order ; m->PNS = Profiles [i].PNS * (1-mix) + Profiles [i+1].PNS * mix; m->TransDetect = Profiles [i].TransDetect* (1-mix) + Profiles [i+1].TransDetect* mix; } musepack_src_r495/libmpcpsy/Makefile.am0000664000000000000000000000042411234134160017051 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO noinst_LIBRARIES = libmpcpsy.a libmpcpsy_a_SOURCES = ans.c cvd.c fft4g.c fft_routines.c psy.c psy_tab.c \ profile.c libmpcpsy.h musepack_src_r495/libmpcpsy/ans.c0000664000000000000000000002547512231315357015766 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ /* * Depending on how transient it is, it can be further reduced (up to 0=No ANS). * Estimate coefficient for feedback at Order=1 over Mask_fu - Mask_fo. * 3 quantization routines: Order=0, Order=1, Order=2...6 * Order doesn't specify the power of the noise shaping, but only the flexibility of the form. * Don't reset utilization of the "remains" at the frame borders; * "remains"-utilization as scalefactor-independent values, * so that a utilization beyond Subframe/Frame Borders is even possible. */ #include #include "libmpcpsy.h" #include static float InvFourier [MAX_NS_ORDER + 1] [16]; static float Cos_Tab [16] [MAX_NS_ORDER + 1]; static float Sin_Tab [16] [MAX_NS_ORDER + 1]; float ANSspec_L [MAX_ANS_LINES]; float ANSspec_R [MAX_ANS_LINES]; // L/R-masking thresholds for ANS float ANSspec_M [MAX_ANS_LINES]; float ANSspec_S [MAX_ANS_LINES]; // M/S-masking thresholds for ANS void Init_ANS ( void ) { int n; int k; // calculate Fourier tables for ( k = 0; k <= MAX_NS_ORDER; k++ ) { for ( n = 0; n < 16; n++ ) { InvFourier [k] [n] = (float) cos ( +2*M_PI/64 * (2*n) * k ) / 16.; Cos_Tab [n] [k] = (float) cos ( -2*M_PI/64 * (2*n+1) * (k+1) ); Sin_Tab [n] [k] = (float) sin ( -2*M_PI/64 * (2*n+1) * (k+1) ); } } } // calculates optimal reflection coefficients and time response of a prediction filter in LPC analysis static mpc_inline void durbin_akf_to_kh1( float* k, // out: reflection coefficients float* h, // out: time response const float* akf ) // in : autocorrelation function (0..1 used) { h[0] = k[0] = akf [1] / akf [0]; } static mpc_inline void durbin_akf_to_kh2( float* k, // out: reflection coefficients float* h, // out: time response const float* akf ) // in : autocorrelation function (0..2 used) { float tk,e; tk = akf [1] / akf[0]; e = akf[0] * (1. - tk*tk); h[0] = k[0] = tk; h[0] *= 1. - (h[1] = k[1] = tk = (akf[2] - h[0] * akf[1]) / e); } static mpc_inline void durbin_akf_to_kh3( float* k, // out: reflection coefficients float* h, // out: time response const float* akf ) // in : autocorrelation function (0..3 used) { float a,b,tk,e; tk = akf[1] / akf[0]; e = akf[0] * (1. - tk*tk); h[0] = k[0] = tk; tk = (akf[2] - h[0] * akf[1]) / e; e *= 1. - tk*tk; h[0] *= 1. - (h[1] = k[1] = tk); h[2] = k[2] = tk = (akf[3] - h[0] * akf[2] - h[1] * akf[1]) / e; h[0] = (a=h[0]) - (b=h[1])*tk; h[1] = b - a*tk; } static mpc_inline void durbin_akf_to_kh ( float* k, // out: reflection coefficients float* h, // out: time response float* akf, // in : autocorrelation function (0..n used) const int n ) // in : number of parameters to calculate { int i,j; float s,a,b,tk,e; float* p; float* q; e = akf [0]; for ( i = 0; i < n; i++ ) { s = 0.f; p = h; q = akf+i; j = i; while ( j-- ) s += *p++ * *q--; tk = (akf[i+1] - s) / e; e *= 1. - tk*tk; h[i] = k[i] = tk; p = h; q = h + i - 1; for ( ; p < q; p++, q-- ) { a = *p; b = *q; *p = a - b*tk; *q = b - a*tk; } if ( p == q ) *p *= 1. - tk; } } static const unsigned char maxANSOrder [32] = { 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static void FindOptimalANS ( const int MaxBand, const unsigned char* ms, const float* spec0, const float* spec1, unsigned int* NS, float* snr_comp, float fir [] [MAX_NS_ORDER], const float* smr0, const float* smr1, const int scf [] [3], const int Transient [32] ) { int Band; int n; int k; int order; float akf [MAX_NS_ORDER + 1]; float h [MAX_NS_ORDER]; float reflex [MAX_NS_ORDER]; float spec [16]; float invspec [16]; float norm; float ns_loss; float min_spec; float min_diff; float re; float im; float ns_energy; float gain; float NS_Gain; float actSMR; int max; const float* tmp; for ( Band = 0; Band <= MaxBand && maxANSOrder[Band]; Band++ ) { if ( scf[Band][0] != scf[Band][1] || scf[Band][1] != scf[Band][2] ) continue; if ( Transient[Band] ) continue; max = maxANSOrder [Band]; if ( ms[Band] ) { // setting pointer and SMR in relation to the M/S-flag tmp = &spec1 [Band<<4]; // pointer to MS-data actSMR = smr1 [Band]; // selecting SMR } else { tmp = &spec0 [Band<<4]; // pointer to LR-data actSMR = smr0 [Band]; // selecting SMR } if ( actSMR >= 1. ) { NS_Gain = 1.f; // reset gain norm = 1.e-30f; // Selection of the masking threshold of the current subband, also considering frequency inversion in every 2nd subband if ( Band & 1 ) for ( n = 0, tmp += 15; n < 16; n++ ) norm += spec[n] = *tmp--; else for ( n = 0; n < 16; n++ ) norm += spec[n] = *tmp++; // Preprocessing: normalization of the the power of spec[] to 1, and search for minimum of masking threshold norm = 16.f / norm; min_spec = 1.e+12f; for ( n = 0; n < 16; n++ ) { invspec[n] = 1.f / (spec[n] *= norm); if ( spec[n] < min_spec ) // normalize spec[] min_spec = spec[n]; } // Calculation of the auto-correlation function tmp = InvFourier [0]; for ( k = 0; k <= max; k++, tmp += 16 ) { akf[k] = tmp[ 0]*invspec[ 0] + tmp[ 1]*invspec[ 1] + tmp[ 2]*invspec[ 2] + tmp[ 3]*invspec[ 3] + tmp[ 4]*invspec[ 4] + tmp[ 5]*invspec[ 5] + tmp[ 6]*invspec[ 6] + tmp[ 7]*invspec[ 7] + tmp[ 8]*invspec[ 8] + tmp[ 9]*invspec[ 9] + tmp[10]*invspec[10] + tmp[11]*invspec[11] + tmp[12]*invspec[12] + tmp[13]*invspec[13] + tmp[14]*invspec[14] + tmp[15]*invspec[15]; } // Searching for the noise-shaper with maximum gain for ( order = 1; order <= max; order++ ) { switch ( order ) { // calculating best FIR-Filter for the return case 1: durbin_akf_to_kh1 (reflex, h, akf); break; case 2: durbin_akf_to_kh2 (reflex, h, akf); break; case 3: durbin_akf_to_kh3 (reflex, h, akf); break; default: durbin_akf_to_kh (reflex, h, akf, order); break; } ns_loss = 1.e-30f; // estimating the gain min_diff = 1.e+12f; for ( n = 0; n < 16; n++ ) { re = 1.f; // calculating the obtained noise shaping im = 0.f; for ( k = 0; k < order; k++ ) { re -= h[k] * Cos_Tab[n][k]; im += h[k] * Sin_Tab[n][k]; } ns_energy = re*re + im*im; // calculated spectral shaped noise ns_loss += ns_energy; // noise energy increases with shaping if ( spec[n] < min_diff * ns_energy ) // Searching for minimum distance between the shaped noise and the masking threshold min_diff = spec[n] / ns_energy; } // Updating the Filter if new gain is bigger than old gain and if the extra noise power through shaping is smaller than the SMR of this band gain = 16. * min_diff / (min_spec * ns_loss); if ( gain > NS_Gain && ns_loss < actSMR ) { NS [Band] = order; NS_Gain = gain; memcpy ( fir [Band], h, order * sizeof(*h) ); } } if ( NS_Gain > 1.f ) { // Activation of ANS if there is gain snr_comp[Band] *= NS_Gain; } } } return; } // perform ANS-analysis (calculation of FIR-filter and gain) void NS_Analyse ( PsyModel* m, const int MaxBand, const unsigned char* MSflag, const SMRTyp smr, const int* Transient ) { // for L or M, respectively memset ( m->FIR_L, 0, sizeof m->FIR_L ); // reset FIR memset ( m->NS_Order_L, 0, sizeof m->NS_Order_L ); // reset Flags FindOptimalANS ( MaxBand, MSflag, ANSspec_L, ANSspec_M, m->NS_Order_L, m->SNR_comp_L, m->FIR_L, smr.L, smr.M, m->SCF_Index_L, Transient ); // for R or S, respectively memset ( m->FIR_R, 0, sizeof m->FIR_R ); // reset FIR memset ( m->NS_Order_R, 0, sizeof m->NS_Order_R ); // reset Flags FindOptimalANS ( MaxBand, MSflag, ANSspec_R, ANSspec_S, m->NS_Order_R, m->SNR_comp_R, m->FIR_R, smr.R, smr.S, m->SCF_Index_R, Transient ); return; } /* end of ans.c */ musepack_src_r495/libmpcpsy/CMakeLists.txt0000664000000000000000000000025010632552310017554 0ustar rootrootinclude_directories(${libmpc_SOURCE_DIR}/include) add_library(mpcpsy_static STATIC ans cvd fft4g fft_routines profile psy psy_tab ${libmpc_SOURCE_DIR}/common/fastmath) musepack_src_r495/libmpcpsy/psy_tab.c0000664000000000000000000003404712231315357016641 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "libmpcpsy.h" #include #include /* * Klemm 1994 and 1997. Experimental data. Sorry, data looks a little bit * dodderly. Data below 30 Hz is extrapolated from other material, above 18 * kHz the ATH is limited due to the original purpose (too much noise at * ATH is not good even if it's theoretically inaudible). */ // FIXME : move this in a struct, to eliminate multiple declarations // w_low for long 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 const int wl [PART_LONG] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 38, 41, 44, 47, 50, 54, 58, 62, 67, 72, 78, 84, 91, 98, 106, 115, 124, 134, 145, 157, 170, 184, 199, 216, 234, 254, 276, 301, 329, 360, 396, 437, 485 }; const int wh [PART_LONG] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 37, 40, 43, 46, 49, 53, 57, 61, 66, 71, 77, 83, 90, 97, 105, 114, 123, 133, 144, 156, 169, 183, 198, 215, 233, 253, 275, 300, 328, 359, 395, 436, 484, 511 }; // Width: 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 4 4 4 5 5 6 6 7 7 8 9 9 10 11 12 13 14 15 17 18 20 22 25 28 31 36 41 48 27 // inverse partition-width for long const float iw [PART_LONG] = { 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/3, 1.f/3, 1.f/3, 1.f/3, 1.f/3, 1.f/4, 1.f/4, 1.f/4, 1.f/5, 1.f/5, 1.f/6, 1.f/6, 1.f/7, 1.f/7, 1.f/8, 1.f/9, 1.f/9, 1.f/10, 1.f/11, 1.f/12, 1.f/13, 1.f/14, 1.f/15, 1.f/17, 1.f/18, 1.f/20, 1.f/22, 1.f/25, 1.f/28, 1.f/31, 1.f/36, 1.f/41, 1.f/48, 1.f/27 }; // w_low for short 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const int wl_short [PART_SHORT] = { 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 23, 29, 36, 46, 59, 75, 99 }; const int wh_short [PART_SHORT] = { 0, 1, 2, 3, 5, 6, 7, 9, 12, 14, 18, 23, 29, 36, 46, 58, 75, 99, 127 }; // inverse partition-width for short const float iw_short [PART_SHORT] = { 1.f, 1.f, 1.f, 1.f, 1.f/2, 1.f/2, 1.f/2, 1.f/2, 1.f/3, 1.f/3, 1.f/4, 1.f/6, 1.f/7, 1.f/8, 1.f/11, 1.f/13, 1.f/17, 1.f/25, 1.f/29 }; float MinVal [PART_LONG]; // contains minimum tonality soffsets float Loudness [PART_LONG]; // weighting factors for loudness calculation float SPRD [PART_LONG] [PART_LONG]; // tabulated spreading function float O_MAX; float O_MIN; float FAC1; float FAC2; // constants for offset calculation float partLtq [PART_LONG]; // threshold in quiet (partitions) float invLtq [PART_LONG]; // inverse threshold in quiet (partitions, long) float fftLtq [512]; // threshold in quiet (FFT) static float ATHformula_Frank ( float freq ) { /* * one value per 100 cent = 1 * semitone = 1/4 * third = 1/12 * octave = 1/40 decade * rest is linear interpolated, values are currently in millibel rel. 20 Pa */ static short tab [] = { /* 10.0 */ 9669, 9669, 9626, 9512, /* 12.6 */ 9353, 9113, 8882, 8676, /* 15.8 */ 8469, 8243, 7997, 7748, /* 20.0 */ 7492, 7239, 7000, 6762, /* 25.1 */ 6529, 6302, 6084, 5900, /* 31.6 */ 5717, 5534, 5351, 5167, /* 39.8 */ 5004, 4812, 4638, 4466, /* 50.1 */ 4310, 4173, 4050, 3922, /* 63.1 */ 3723, 3577, 3451, 3281, /* 79.4 */ 3132, 3036, 2902, 2760, /* 100.0 */ 2658, 2591, 2441, 2301, /* 125.9 */ 2212, 2125, 2018, 1900, /* 158.5 */ 1770, 1682, 1594, 1512, /* 199.5 */ 1430, 1341, 1260, 1198, /* 251.2 */ 1136, 1057, 998, 943, /* 316.2 */ 887, 846, 744, 712, /* 398.1 */ 693, 668, 637, 606, /* 501.2 */ 580, 555, 529, 502, /* 631.0 */ 475, 448, 422, 398, /* 794.3 */ 375, 351, 327, 322, /* 1000.0 */ 312, 301, 291, 268, /* 1258.9 */ 246, 215, 182, 146, /* 1584.9 */ 107, 61, 13, -35, /* 1995.3 */ -96, -156, -179, -235, /* 2511.9 */ -295, -350, -401, -421, /* 3162.3 */ -446, -499, -532, -535, /* 3981.1 */ -513, -476, -431, -313, /* 5011.9 */ -179, 8, 203, 403, /* 6309.6 */ 580, 736, 881, 1022, /* 7943.3 */ 1154, 1251, 1348, 1421, /* 10000.0 */ 1479, 1399, 1285, 1193, /* 12589.3 */ 1287, 1519, 1914, 2369, #if 0 /* 15848.9 */ 3352, 4865, 5942, 6177, /* 19952.6 */ 6385, 6604, 6833, 7009, /* 25118.9 */ 7066, 7127, 7191, 7260, #else /* 15848.9 */ 3352, 4352, 5352, 6352, /* 19952.6 */ 7352, 8352, 9352, 9999, /* 25118.9 */ 9999, 9999, 9999, 9999, #endif }; double freq_log; unsigned index; if ( freq < 10. ) freq = 10.; if ( freq > 29853. ) freq = 29853.; freq_log = 40. * log10 (0.1 * freq); /* 4 steps per third, starting at 10 Hz */ index = (unsigned) freq_log; return 0.01 * (tab [index] * (1 + index - freq_log) + tab [index+1] * (freq_log - index)); } /* F U N C T I O N S */ // calculation of the threshold in quiet in FFT-resolution static void Ruhehoerschwelle ( PsyModel* m, unsigned int EarModelFlag, int Ltq_offset, int Ltq_max ) { int n; int k; float f; float erg; double tmp; float absLtq [512]; for ( n = 0; n < 512; n++ ) { f = (float) ( (n+1) * (float)(m->SampleFreq / 2000.) / 512 ); // Frequency in kHz switch ( EarModelFlag / 100 ) { case 0: // ISO-threshold in quiet tmp = 3.64*pow (f,-0.8) - 6.5*exp (-0.6*(f-3.3)*(f-3.3)) + 0.001*pow (f, 4.0); break; default: case 1: // measured threshold in quiet (Nick Berglmeir, Andree Buschmann, Kopfh�er) tmp = 3.00*pow (f,-0.8) - 5.0*exp (-0.1*(f-3.0)*(f-3.0)) + 0.0000015022693846297*pow (f, 6.0) + 10.*exp (-(f-0.1)*(f-0.1)); break; case 2: // measured threshold in quiet (Filburt, Kopfh�er) tmp = 9.00*pow (f,-0.5) - 15.0*exp (-0.1*(f-4.0)*(f-4.0)) + 0.0341796875*pow (f, 2.5) + 15.*exp (-(f-0.1)*(f-0.1)) - 18; tmp = mind ( tmp, Ltq_max - 18 ); break; case 3: tmp = ATHformula_Frank ( 1.e3 * f ); break; case 4: tmp = ATHformula_Frank ( 1.e3 * f ); if ( f > 4.8 ) { tmp += 3.00*pow (f,-0.8) - 5.0*exp (-0.1*(f-3.0)*(f-3.0)) + 0.0000015022693846297*pow (f, 6.0) + 10.*exp (-(f-0.1)*(f-0.1)); tmp *= 0.5 ; } break; case 5: tmp = ATHformula_Frank ( 1.e3 * f ); if ( f > 4.8 ) { tmp = 3.00*pow (f,-0.8) - 5.0*exp (-0.1*(f-3.0)*(f-3.0)) + 0.0000015022693846297*pow (f, 6.0) + 10.*exp (-(f-0.1)*(f-0.1)); } break; } tmp -= f * f * (int)(EarModelFlag % 100 - 50) * 0.0015; // 00: +30 dB, 100: -30 dB @20 kHz tmp = mind ( tmp, Ltq_max ); // Limit ATH tmp += Ltq_offset - 23; // Add chosen Offset fftLtq[n] = absLtq[n] = POW10 ( 0.1 * tmp); // conversion into power } // threshold in quiet in partitions (long) for ( n = 0; n < PART_LONG; n++ ) { erg = 1.e20f; for ( k = wl[n]; k <= wh[n]; k++ ) erg = minf (erg, absLtq[k]); partLtq[n] = erg; // threshold in quiet invLtq [n] = 1.f / partLtq[n]; // Inverse } } #ifdef _MSC_VER static double asinh ( double x ) { return x >= 0 ? log (sqrt (x*x+1) + x) : -log (sqrt (x*x+1) - x); } #endif static double Freq2Bark ( double Hz ) // Klemm 2002 { return 9.97074*asinh (1.1268e-3 * Hz) - 6.25817*asinh (0.197193e-3 * Hz) ; } // static double // Bark2Freq ( double Bark ) // Klemm 2002 // { // return 956.86 * sinh (0.101561*Bark) + 11.7296 * sinh (0.304992*Bark) + 6.33622e-3*sinh (0.538621*Bark); // } static double LongPart2Bark ( PsyModel* m, int Part ) { return Freq2Bark ((wl [Part] + wh [Part]) * m->SampleFreq / 2048.); } // calculating the table for loudness calculation based on absLtq = ank static void Loudness_Tabelle (PsyModel* m) { int n; float midfreq; float tmp; // ca. dB(A) for ( n = 0; n < PART_LONG; n++ ){ midfreq = (wh[n] + wl[n] + 3) * (0.25 * m->SampleFreq / 512); // center frequency in kHz, why +3 ??? tmp = LOG10 (midfreq) - 3.5f; // dB(A) tmp = -10 * tmp * tmp + 3 - midfreq/3000; Loudness [n] = POW10 ( 0.1 * tmp ); // conversion into power } } static double Bass ( float f, float TMN, float NMT, float bass ) { static unsigned char lfe [11] = { 120, 100, 80, 60, 50, 40, 30, 20, 15, 10, 5 }; int tmp = (int) ( 1024/44100. * f + 0.5 ); switch ( tmp ) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: return TMN + bass * lfe [tmp]; case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: return TMN; case 19: case 20: case 21: case 22: return TMN*0.75 + NMT*0.25; case 23: case 24: return TMN*0.50 + NMT*0.50; case 25: case 26: return TMN*0.25 + NMT*0.75; default: return NMT; } } // calculating the coefficient for utilization of the tonality offset, depending on TMN und NMT static void Tonalitaetskoeffizienten ( PsyModel* m ) { double tmp; int n; float bass; bass = 0.1/8 * m->NMT; if ( m->MinValChoice <= 2 && bass > 0.1 ) bass = 0.1f; if ( m->MinValChoice <= 1 ) bass = 0.0f; // alternative: calculation of the minval-values dependent on TMN and TMN for ( n = 0; n < PART_LONG; n++ ) { tmp = Bass ( (wl [n] + wh [n]) / 2048. * m->SampleFreq, m->TMN, m->NMT, bass ); MinVal [n] = POW10 ( -0.1 * tmp ); // conversion into power } // calculation of the constants for "tonality offset" O_MAX = POW10 ( -0.1 * m->TMN ); O_MIN = POW10 ( -0.1 * m->NMT ); FAC1 = POW10 ( -0.1 * (m->NMT - (m->TMN - m->NMT) * 0.229) ) ; FAC2 = (m->TMN - m->NMT) * (0.99011159 * 0.1); } // calculation of the spreading function static void Spread ( PsyModel* m ) { int i; int j; float tmpx; float tmpy; float tmpz; float x; // calculation of the spreading-function for all occuring values for ( i = 0; i < PART_LONG; i++ ) { // i is masking Partition, Source for ( j = 0; j < PART_LONG; j++ ) { // j is masking Partition, Target tmpx = LongPart2Bark (m, j) - LongPart2Bark (m, i);// Difference of the partitions in Bark tmpy = tmpz = 0.; // tmpz = 0: no dip if ( tmpx < 0 ) { // downwards (S1) tmpy = -32.f * tmpx; // 32 dB per Bark, e33 (10) } else if ( tmpx > 0 ) { // upwards (S2) #if 0 x = (wl[i]+wh[i])/2 * (float)(SampleFreq / 2000)/512; // center frequency in kHz ??????? if (i==0) x = 0.5f * (float)(SampleFreq / 2000)/512; // if first spectral line #else x = i ? wl[i]+wh[i] : 1; x *= m->SampleFreq / 1000. / 2048; // center frequency in kHz #endif // dB/Bark tmpy = (22.f + 0.23f / x) * tmpx; // e33 (10) // dip (up to 6 dB) tmpz = 8 * minf ( (tmpx-0.5f) * (tmpx-0.5f) - 2 * (tmpx-0.5f), 0.f ); } // calculate coefficient SPRD[i][j] = POW10 ( -0.1 * (tmpy+tmpz) ); // [Source] [Target] } } // Normierung e33 (10) for ( i = 0; i < PART_LONG; i++ ) { // i is masked Partition float norm = 0.f; for ( j = 0; j < PART_LONG; j++ ) // j is masking Partition norm += SPRD [j] [i]; for ( j = 0; j < PART_LONG; j++ ) // j is masking Partition SPRD [j] [i] /= norm; } } // call all initialisation procedures void Init_Psychoakustiktabellen ( PsyModel* m ) { m->Max_Band = (int) ( m->BandWidth * 64. / m->SampleFreq ); if ( m->Max_Band < 1 ) m->Max_Band = 1; if ( m->Max_Band > 31 ) m->Max_Band = 31; Tonalitaetskoeffizienten (m); Ruhehoerschwelle ( m, m->EarModelFlag, m->Ltq_offset, m->Ltq_max ); Loudness_Tabelle (m); Spread (m); } /* end of psy_tab.c */ musepack_src_r495/libmpcpsy/psy.c0000664000000000000000000013441712231315357016015 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ /* * Prediction * Short-Block-detection with smooth inset * revise CalcMSThreshold * /dev/audio for Windows too * revise PNS/IS * CVS with smoother inset * several files per call * revise ANS with changing SCFs * No IS * PNS estimation very rough, also IS should be used to reduce data rate in the side channel * ANS problems at Frame boundaries when resolution changes * ANS problems at Subframe boundaries when SCF changes * CVS+ with smoother transition ---------------------------------------- Optimize Tabelle[18] (use second table) CVS+ - ANS is disregarded during the search for the best Res - ANS messes up if res changes (each 36 samples) and/or SCF changes (each 12 samples) - PNS not in difference signal - implement IS in decoder - Experimental Quantizer with complete energy preservation - 1D, calculated - 2D, calculated - 2D, manually modified, coeffs set to 1.f */ #include #include #include "libmpcpsy.h" #include #include #include // psy_tab.c extern const float iw [PART_LONG]; // inverse partition-width for long extern const float iw_short [PART_SHORT]; // inverse partition-width for short extern const int wl [PART_LONG]; // w_low for long extern const int wl_short [PART_SHORT]; // w_low for short extern const int wh [PART_LONG]; // w_high for long extern const int wh_short [PART_SHORT]; // w_high for short extern float MinVal [PART_LONG]; // minimum quality that's adapted to the model, minval for long extern float Loudness [PART_LONG]; // weighting factors for loudness calculation extern float SPRD [PART_LONG] [PART_LONG]; // tabulated spreading function extern float O_MAX; extern float O_MIN; extern float FAC1; extern float FAC2; // constants for offset calculation extern float partLtq [PART_LONG]; // threshold in quiet (partitions) extern float invLtq [PART_LONG]; // inverse threshold in quiet (partitions, long) extern float fftLtq [512]; // threshold in quiet (FFT) // ans.c extern float ANSspec_L [MAX_ANS_LINES]; extern float ANSspec_R [MAX_ANS_LINES]; // L/R-masking threshold for ANS extern float ANSspec_M [MAX_ANS_LINES]; extern float ANSspec_S [MAX_ANS_LINES]; // M/S-masking threshold for ANS void Init_Psychoakustiktabellen ( PsyModel* ); int CVD2048 ( PsyModel*, const float*, int* ); // Antialiasing for calculation of the subband power const float Butfly [7] = { 0.5f, 0.2776f, 0.1176f, 0.0361f, 0.0075f, 0.000948f, 0.0000598f }; // Antialiasing for calculation of the masking thresholds const float InvButfly [7] = { 2.f, 3.6023f, 8.5034f, 27.701f, 133.33f, 1054.852f, 16722.408f }; /* V A R I A B L E S */ static float a [PART_LONG]; static float b [PART_LONG]; static float c [PART_LONG]; static float d [PART_LONG]; // Integrations for tmpMask static float Xsave_L [3 * 512]; static float Xsave_R [3 * 512]; // FFT-Amplitudes L/R static float Ysave_L [3 * 512]; static float Ysave_R [3 * 512]; // FFT-Phases L/R static float T_L [PART_LONG]; static float T_R [PART_LONG]; // time-constants for tmpMask static float pre_erg_L[2][PART_SHORT]; static float pre_erg_R[2][PART_SHORT]; // Preecho-control short static float PreThr_L [PART_LONG]; static float PreThr_R [PART_LONG]; // for Pre-Echo-control L/R static float tmp_Mask_L [PART_LONG]; static float tmp_Mask_R [PART_LONG]; // for Post-Masking L/R static int Vocal_L [MAX_CVD_LINE + 4]; static int Vocal_R [MAX_CVD_LINE + 4]; // FFT-Line belongs to harmonic? /* F U N C T I O N S */ // fft_routines.c void Init_FFT ( PsyModel* ); void PowSpec256 ( const float*, float* ); void PowSpec1024 ( const float*, float* ); void PowSpec2048 ( const float*, float* ); void PolarSpec1024 ( const float*, float*, float* ); void Cepstrum2048 ( float* cep, const int ); void Init_ANS ( void ); // Resets Arrays void Init_Psychoakustik ( PsyModel* m) { int i; // initializing arrays with zero memset ( Xsave_L, 0, sizeof Xsave_L ); memset ( Xsave_R, 0, sizeof Xsave_R ); memset ( Ysave_L, 0, sizeof Ysave_L ); memset ( Ysave_R, 0, sizeof Ysave_R ); memset ( a, 0, sizeof a ); memset ( b, 0, sizeof b ); memset ( c, 0, sizeof c ); memset ( d, 0, sizeof d ); memset ( T_L, 0, sizeof T_L ); memset ( T_R, 0, sizeof T_R ); memset ( Vocal_L, 0, sizeof Vocal_L ); memset ( Vocal_R, 0, sizeof Vocal_R ); m->SampleFreq = 0.; m->BandWidth = 0.; m->KBD1 = 2.; m->KBD2 = -1.; m->Ltq_offset = 0; m->Ltq_max = 0; m->EarModelFlag = 0; m->PNS = 0.; m->CombPenalities = -1; // generate FFT lookup-tables with largest FFT-size of 1024 Init_FFT (m); Init_ANS (); Init_Psychoakustiktabellen (m); // setting pre-echo variables to Ltq for ( i = 0; i < PART_LONG; i++ ) { pre_erg_L [0][i/3] = pre_erg_R [0][i/3] = pre_erg_L [1][i/3] = pre_erg_R [1][i/3] = tmp_Mask_L [i] = tmp_Mask_R [i] = PreThr_L [i] = PreThr_R [i] = partLtq [i]; } return; } // VBRmode 1: Adjustment of all SMRs via a factor (offset of SMRoffset dB) // VBRmode 2: SMRs have a minimum of minSMR dB static void RaiseSMR_Signal ( const int MaxBand, float* signal, float tmp ) { int Band; float z = 0.; for ( Band = MaxBand; Band >= 0; Band-- ) { if ( z < signal [Band] ) z = signal [Band]; if ( z > tmp ) z = tmp; if ( signal [Band] < z ) signal [Band] = z; } } void RaiseSMR (PsyModel* m, const int MaxBand, SMRTyp* smr ) { float tmp = POW10 ( 0.1 * m->minSMR ); RaiseSMR_Signal ( MaxBand, smr->L, tmp ); RaiseSMR_Signal ( MaxBand, smr->R, tmp ); RaiseSMR_Signal ( MaxBand, smr->M, tmp ); RaiseSMR_Signal ( MaxBand, smr->S, 0.5 * tmp ); return; } // input : *smr // output: *smr, *ms, *x (only the entries for L/R contain relevant data) // Check if either M/S- or L/R-coding has a lower perceptual entropy // Choose the better mode, copy the appropriate data into the // arrays that belong to L and R and set the ms-Flag accordingly. void MS_LR_Entscheidung ( const int MaxBand, unsigned char* ms, SMRTyp* smr, SubbandFloatTyp* x ) { int Band; int n; float PE_MS; float PE_LR; float tmpM; float tmpS; float* l; float* r; for ( Band = 0; Band <= MaxBand; Band++ ) { // calculate perceptual entropy PE_LR = PE_MS = 1.f; if (smr->L[Band] > 1.) PE_LR *= smr->L[Band]; if (smr->R[Band] > 1.) PE_LR *= smr->R[Band]; if (smr->M[Band] > 1.) PE_MS *= smr->M[Band]; if (smr->S[Band] > 1.) PE_MS *= smr->S[Band]; if ( PE_MS < PE_LR ) { ms[Band] = 1; // calculate M/S-signal and copies it to L/R-array l = x[Band].L; r = x[Band].R; for ( n = 0; n < 36; n++, l++, r++ ) { tmpM = (*l + *r) * 0.5f; tmpS = (*l - *r) * 0.5f; *l = tmpM; *r = tmpS; } // copy M/S - SMR to L/R-fields smr->L[Band] = smr->M[Band]; smr->R[Band] = smr->S[Band]; } else { ms[Band] = 0; } } return; } // input : FFT-spectrums *spec0 und *spec1 // output: energy in the individual subbands *erg0 and *erg1 // With Butfly[], you can calculate the results of aliasing during calculation // of subband energy from the FFT-spectrums. static void SubbandEnergy ( const int MaxBand, float* erg0, float* erg1, const float* spec0, const float* spec1 ) { int n; int k; int alias; float tmp0; float tmp1; // Is this here correct for FFT-based data or is this calculation rule only for MDCTs??? for ( k = 0; k <= MaxBand; k++ ) { // subband index tmp0 = tmp1 = 0.f; for ( n = 0; n < 16; n++, spec0++, spec1++ ) { // spectral index tmp0 += *spec0; tmp1 += *spec1; // Consideration of Aliasing between the subbands if ( n < +sizeof(Butfly)/sizeof(*Butfly) && k != 0 ) { alias = -1 - (n<<1); tmp0 += Butfly [n] * (spec0[alias] - *spec0); tmp1 += Butfly [n] * (spec1[alias] - *spec1); } else if ( n > 15-sizeof(Butfly)/sizeof(*Butfly) && k != 31 ) { alias = 31 - (n<<1); tmp0 += Butfly [15-n] * (spec0[alias] - *spec0); tmp1 += Butfly [15-n] * (spec1[alias] - *spec1); } } *erg0++ = tmp0; *erg1++ = tmp1; } return; } // input : FFT-Spectrums *spec0 and *spec1 // output: energy in the individual partitions *erg0 and *erg1 static void PartitionEnergy ( float* erg0, float* erg1, const float* spec0, const float* spec1 ) { unsigned int n; unsigned int k; float e0; float e1; n = 0; for ( ; n < 23; n++ ) { // 11 or 23 k = wh[n] - wl[n]; e0 = *spec0++; e1 = *spec1++; while ( k-- ) { e0 += *spec0++; e1 += *spec1++; } *erg0++ = e0; *erg1++ = e1; } for ( ; n < 48; n++ ) { // 37 ... 46, 48, 57 k = wh[n] - wl[n]; e0 = sqrt (*spec0++); e1 = sqrt (*spec1++); while ( k-- ) { e0 += sqrt (*spec0++); e1 += sqrt (*spec1++); } *erg0++ = e0*e0 * iw[n]; *erg1++ = e1*e1 * iw[n]; } for ( ; n < PART_LONG; n++ ) { k = wh[n] - wl[n]; e0 = *spec0++; e1 = *spec1++; while ( k-- ) { e0 += *spec0++; e1 += *spec1++; } *erg0++ = e0; *erg1++ = e1; } } // input : FFT-Spectrums *spec0, *spec1 and unpredictability *cw0 and *cw1 // output: weighted energy in the individual partitions *erg0, *erg1 static void WeightedPartitionEnergy ( float* erg0, float* erg1, const float* spec0, const float* spec1, const float* cw0, const float* cw1 ) { unsigned int n; unsigned int k; float e0; float e1; n = 0; for ( ; n < 23; n++ ) { e0 = *spec0++ * *cw0++; e1 = *spec1++ * *cw1++; k = wh[n] - wl[n]; while ( k-- ) { e0 += *spec0++ * *cw0++; e1 += *spec1++ * *cw1++; } *erg0++ = e0; *erg1++ = e1; } for ( ; n < 48; n++ ) { e0 = sqrt (*spec0++ * *cw0++); e1 = sqrt (*spec1++ * *cw1++); k = wh[n] - wl[n]; while ( k-- ) { e0 += sqrt (*spec0++ * *cw0++); e1 += sqrt (*spec1++ * *cw1++); } *erg0++ = e0*e0 * iw[n]; *erg1++ = e1*e1 * iw[n]; } for ( ; n < PART_LONG; n++ ) { e0 = *spec0++ * *cw0++; e1 = *spec1++ * *cw1++; k = wh[n] - wl[n]; while ( k-- ) { e0 += *spec0++ * *cw0++; e1 += *spec1++ * *cw1++; } *erg0++ = e0; *erg1++ = e1; } } // input : masking thresholds, first half of the arrays *shaped0 and *shaped1 // output: masking thresholds, second half of the arrays *shaped0 and *shaped1 // Considering the result of aliasing via InvButfly[] // The input *thr0, *thr1 is gathered via address calculation from *shaped0, *shaped1 static void AdaptThresholds ( const int MaxLine, float* shaped0, float* shaped1 ) { int n; int mod; int alias; float tmp; const float* invb = InvButfly; const float* thr0 = shaped0 - 512; const float* thr1 = shaped1 - 512; float tmp0; float tmp1; // should be able to optimize it with coasting. [ 9 ] + n * [ 7 + 7 + 2 ] + [ 7 ] // Schleife Schl Schl Ausr Schleife for ( n = 0; n < MaxLine; n++, thr0++, thr1++ ) { mod = n & 15; // n%16 tmp0 = *thr0; tmp1 = *thr1; if ( mod < +sizeof(InvButfly)/sizeof(*InvButfly) && n > 12 ) { alias = -1 - (mod<<1); tmp = thr0[alias] * invb[mod]; if ( tmp < tmp0 ) tmp0 = tmp; tmp = thr1[alias] * invb[mod]; if ( tmp < tmp1 ) tmp1 = tmp; } else if ( mod > 15-sizeof(InvButfly)/sizeof(*InvButfly) && n < 499 ) { alias = 31 - (mod<<1); tmp = thr0[alias] * invb[15-mod]; if ( tmp < tmp0 ) tmp0 = tmp; tmp = thr1[alias] * invb[15-mod]; if ( tmp < tmp1 ) tmp1 = tmp; } *shaped0++ = tmp0; *shaped1++ = tmp1; } return; } // input : current spectrum in the form of power *spec and phase *phase, // the last two earlier spectrums are at position // 512 and 1024 of the corresponding Input-Arrays. // Array *vocal, which can mark an FFT_Linie as harmonic // output: current amplitude *amp and unpredictability *cw static void CalcUnpred (PsyModel* m, const int MaxLine, const float* spec, const float* phase, const int* vocal, float* amp0, float* phs0, float* cw ) { int n; float amp; float tmp; #define amp1 ((amp0) + 512) // amp[ 512...1023] contains data of frame-1 #define amp2 ((amp0) + 1024) // amp[1024...1535] contains data of frame-2 #define phs1 ((phs0) + 512) // phs[ 512...1023] contains data of frame-1 #define phs2 ((phs0) + 1024) // phs[1024...1535] contains data of frame-2 for ( n = 0; n < MaxLine; n++ ) { tmp = COSF ((phs0[n] = phase[n]) - 2*phs1[n] + phs2[n]); // copy phase to output-array, predict phase and calculate predictive error amp0[n] = SQRTF (spec[n]); // calculate and set amplitude amp = 2*amp1[n] - amp2[n]; // predict amplitude // calculate unpredictability cw[n] = SQRTF (spec[n] + amp * (amp - 2*amp0[n] * tmp)) / (amp0[n] + FABS(amp)); } // postprocessing of harmonic FFT-lines (*cw is set to CVD_UNPRED) if ( m->CVD_used && vocal != NULL ) { for ( n = 0; n < MAX_CVD_LINE; n++, cw++, vocal++ ) if ( *vocal != 0 && *cw > CVD_UNPRED * 0.01 * *vocal ) *cw = CVD_UNPRED * 0.01 * *vocal; } return; } #undef amp1 #undef amp2 #undef phs1 #undef phs2 // input : Energy *erg, calibrated energy *werg // output: spread energy *res, spread weighted energy *wres // SPRD describes the spreading function as calculated in psy_tab.c static void SpreadingSignal ( const float* erg, const float* werg, float* res, float* wres ) { int n; int k; int start; int stop; const float* sprd; float e; float ew; for (k=0; k static float AdaptLtq ( PsyModel* m, const float* erg0, const float* erg1 ) { static float loud = 0.f; float* weight = Loudness; float sum = 0.f; int n; // calculate loudness for ( n = 0; n < PART_LONG; n++ ) sum += (*erg0++ + *erg1++) * *weight++; // Utilization of the time constants (fast drop of Ltq T=5, slow rise of Ltq T=20) //loud = (sum < loud) ? (4 * sum + loud)*0.2f : (19 * loud + sum)*0.05f; loud = 0.98 * loud + 0.02 * (0.5 * sum); // calculate dynamic offset for threshold in quiet, 0...+20 dB, at 96 dB loudness, an offset of 20 dB is assumed return 1.f + m->varLtq * loud * 5.023772e-08f; } // input : simultaneous masking threshold *frqthr, // previous masking threshold *tmpthr, // Integrations *a (short-time) and *b (long-time) // output: tracked Integrations *a and *b, time constant *tau static void CalcTemporalThreshold ( float* a, float* b, float* tau, float* frqthr, float* tmpthr ) { int n; float tmp; for ( n = 0; n < PART_LONG; n++ ) { // following calculations relative to threshold in quiet frqthr[n] *= invLtq[n]; tmpthr[n] *= invLtq[n]; // new post-masking 'tmp' via time constant tau, if old post-masking > Ltq (=1) tmp = tmpthr[n] > 1.f ? POW ( tmpthr[n], tau[n] ) : 1.f; // calculate time constant for post-masking in next frame, // if new time constant has to be calculated (new tmpMask < frqMask) a[n] += 0.5f * (frqthr[n] - a[n]); // short time integrator b[n] += 0.15f * (frqthr[n] - b[n]); // long time integrator if (tmp < frqthr[n]) tau[n] = a[n] <= b[n] ? 0.8f : 0.2f + b[n] / a[n] * 0.6f; // use post-masking of (Re-Normalization) tmpthr[n] = maxf (frqthr[n], tmp) * partLtq[n]; } return; } // input : L/R-Masking thresholds in Partitions *thrL, *thrR // L/R-Subband energies *ergL, *ergR // M/S-Subband energies *ergM, *ergS // output: M/S-Masking thresholds in Partitions *thrM, *thrS static void CalcMSThreshold ( PsyModel* m, const float* const ergL, const float* const ergR, const float* const ergM, const float* const ergS, float* const thrL, float* const thrR, float* const thrM, float* const thrS ) { int n; float norm; float tmp; // All hardcoded numbers here should be pulled from somewhere, // the "4.", the -2 dB, the 0.0625 and the 0.9375, as well as all bands where this is done for ( n = 0; n < PART_LONG; n++ ) { // estimate M/S thresholds out of L/R thresholds and M/S and L/R energies thrS[n] = thrM[n] = maxf (ergM[n], ergS[n]) / maxf (ergL[n], ergR[n]) * minf (thrL[n], thrR[n]); switch ( m->MS_Channelmode ) { // preserve 'near-mid' signal components case 3: if ( n > 0 ) { double ratioMS = ergM[n] > ergS[n] ? ergS[n] / ergM[n] : ergM[n] / ergS[n]; double ratioLR = ergL[n] > ergR[n] ? ergR[n] / ergL[n] : ergL[n] / ergR[n]; if ( ratioMS < ratioLR ) { // MS if ( ergM[n] > ergS[n] ) thrS[n] = thrL[n] = thrR[n] = 1.e18f; else thrM[n] = thrL[n] = thrR[n] = 1.e18f; } else { // LR if ( ergL[n] > ergR[n] ) thrR[n] = thrM[n] = thrS[n] = 1.e18f; else thrL[n] = thrM[n] = thrS[n] = 1.e18f; } } break; case 4: if ( n > 0 ) { double ratioMS = ergM[n] > ergS[n] ? ergS[n] / ergM[n] : ergM[n] / ergS[n]; double ratioLR = ergL[n] > ergR[n] ? ergR[n] / ergL[n] : ergL[n] / ergR[n]; if ( ratioMS < ratioLR ) { // MS if ( ergM[n] > ergS[n] ) thrS[n] = 1.e18f; else thrM[n] = 1.e18f; } else { // LR if ( ergL[n] > ergR[n] ) thrR[n] = 1.e18f; else thrL[n] = 1.e18f; } } break; case 5: thrS[n] *= 2.; // +3 dB break; case 6: break; default: fprintf ( stderr, "Unknown stereo mode\n"); case 10: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.70794578f * iw[n]; // -1.5 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = MS2SPAT1 * thrS[n] + (1.f-MS2SPAT1) * tmp; // raises masking threshold by up to 3 dB } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = MS2SPAT1 * thrM[n] + (1.f-MS2SPAT1) * tmp; } } break; case 11: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.63095734f * iw[n]; // -2.0 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = MS2SPAT2 * thrS[n] + (1.f-MS2SPAT2) * tmp; // raises masking threshold by up to 6 dB } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = MS2SPAT2 * thrM[n] + (1.f-MS2SPAT2) * tmp; } } break; case 12: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.56234133f * iw[n]; // -2.5 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = MS2SPAT3 * thrS[n] + (1.f-MS2SPAT3) * tmp; // raises masking threshold by up to 9 dB } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = MS2SPAT3 * thrM[n] + (1.f-MS2SPAT3) * tmp; } } break; case 13: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.50118723f * iw[n]; // -3.0 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = MS2SPAT4 * thrS[n] + (1.f-MS2SPAT4) * tmp; // raises masking threshold by up to 12 dB } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = MS2SPAT4 * thrM[n] + (1.f-MS2SPAT4) * tmp; } } break; case 15: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.50118723f * iw[n]; // -3.0 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = tmp; // raises masking threshold by up to +oo dB an } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = tmp; } } break; case 22: if ( 4. * ergL[n] > ergR[n] && ergL[n] < 4. * ergR[n] ) {// Energy between both channels differs by less than 6 dB norm = 0.56234133f * iw[n]; // -2.5 dB * iwidth if ( ergM[n] > ergS[n] ) { tmp = ergS[n] * norm; if ( thrS[n] > tmp ) thrS[n] = maxf (tmp, ergM[n]*iw[n]*0.025); // +/- 1.414 } else if ( ergS[n] > ergM[n] ) { tmp = ergM[n] * norm; if ( thrM[n] > tmp ) thrM[n] = maxf (tmp, ergS[n]*iw[n]*0.025); // +/- 1.414 } } break; } } return; } // input : Masking thresholds in Partitions *partThr0, *partThr1 // level of threshold in quiet *ltq in FFT-resolution // output: Masking thresholds in FFT-resolution *thr0, *thr1 // inline, because it's called 4x static void ApplyLtq ( float* thr0, float* thr1, const float* partThr0, const float* partThr1, const float AdaptedLTQ, int MSflag ) { int n, k; float ms, ltq, tmp, tmpThr0, tmpThr1; ms = AdaptedLTQ * (MSflag ? 0.125f : 0.25f); for( n = 0; n < PART_LONG; n++ ) { tmpThr0 = sqrt(partThr0[n]); tmpThr1 = sqrt(partThr1[n]); for ( k = wl[n]; k <= wh[n]; k++, thr0++, thr1++ ) { // threshold in quiet (Partition) // Applies a much more gentle ATH rolloff + 6 dB more dynamic ltq = sqrt (ms * fftLtq [k]); tmp = tmpThr0 + ltq; *thr0 = tmp * tmp; tmp = tmpThr1 + ltq; *thr1 = tmp * tmp; } } } // input : Subband energies *erg0, *erg1 // Masking thresholds in FFT-resolution *thr0, *thr1 // output: SMR per Subband *smr0, *smr1 static void CalculateSMR ( const int MaxBand, const float* erg0, const float* erg1, const float* thr0, const float* thr1, float* smr0, float* smr1 ) { int n; int k; float tmp0; float tmp1; // calculation of the masked thresholds in the subbands for (n = 0; n <= MaxBand; n++ ) { tmp0 = *thr0++; tmp1 = *thr1++; for (k=1; k<16; ++k, ++thr0, ++thr1) { if (*thr0 < tmp0) tmp0 = *thr0; if (*thr1 < tmp1) tmp1 = *thr1; } *smr0++ = 0.0625f * *erg0++ / tmp0; *smr1++ = 0.0625f * *erg1++ / tmp1; } return; } // input : energy spectrums erg[4][128] (4 delayed FFTs) // Energy of the last short block *preerg in short partitions // PreechoFac declares allowed traved of the masking threshold // output: masking threshold *thr in short partitions // Energy of the last short block *preerg in short partitions static void CalcShortThreshold ( PsyModel* m, const float erg [4] [128], const float ShortThr, float* thr, float old_erg [2][PART_SHORT], int* transient ) { const int* index_lo = wl_short; // lower FFT-index const int* index_hi = wh_short; // upper FFT-index const float* iwidth = iw_short; // inverse partition-width int k; int n; int l; float new_erg; float th, TransDetect = m->TransDetect; const float* ep; for ( k = 0; k < PART_SHORT; k++ ) { transient [k] = 0; th = old_erg [0][k]; for ( n = 0; n < 4; n++ ) { ep = erg[n] + index_lo [k]; l = index_hi [k] - index_lo [k]; new_erg = *ep++; while (l--) new_erg += *ep++; // e = Short_Partition-energy in piece n if ( new_erg > old_erg [0][k] ) { // bigger than the old? if ( new_erg > old_erg [0][k] * TransDetect || new_erg > old_erg [1][k] * TransDetect*2 ) // is signal transient? transient [k] = 1; } else { th = minf ( th, new_erg ); // assume short threshold = engr*PreechoFac } old_erg [1][k] = old_erg [0][k]; old_erg [0][k] = new_erg; // save the current one } thr [k] = th * ShortThr * *iwidth++; // pull out and multiply only when transient[k]=1 } return; } // input : previous simultaneous masking threshold *preThr, // current simultaneous masking threshold *simThr // output: update of *preThr for next call, // current masking threshold *partThr static void PreechoControl ( float* partThr0, float* preThr0, const float* simThr0, float* partThr1, float* preThr1, const float* simThr1 ) { int n; for ( n = 0; n < PART_LONG; n++ ) { *partThr0++ = minf ( *simThr0, *preThr0 * PREFAC_LONG); *partThr1++ = minf ( *simThr1, *preThr1 * PREFAC_LONG); *preThr0++ = *simThr0++; *preThr1++ = *simThr1++; } return; } void TransientenCalc ( int* T, const int* TL, const int* TR ) { int i; int x1; int x2; memset ( T, 0, 32*sizeof(*T) ); for ( i = 0; i < PART_SHORT; i++ ) if ( TL[i] || TR[i] ) { x1 = wl_short[i] >> 2; x2 = wh_short[i] >> 2; while ( x1 <= x2 ) T [x1++] = 1; } } // input : PCM-Data *data // output: SMRs for the input data SMRTyp Psychoakustisches_Modell ( PsyModel* m, const int MaxBand, const PCMDataTyp* data, int* TransientL, int* TransientR ) { float Xi_L[32], Xi_R[32]; // acoustic pressure per Subband L/R float Xi_M[32], Xi_S[32]; // acoustic pressure per Subband M/S float cw_L[512], cw_R[512]; // unpredictability (only L/R) float erg0[512], erg1[512]; // holds energy spectrum of long FFT float phs0[512], phs1[512]; // holds phase spectrum of long FFT float Thr_L[2*512], Thr_R[2*512]; // masking thresholds L/R, second half for triangle swap float Thr_M[2*512], Thr_S[2*512]; // masking thresholds M/S, second half for triangle swap float F_256[4][128]; // holds energies of short FFTs (L/R only) float Xerg[1024]; // holds energy spectrum of very long FFT float Ls_L[PART_LONG], Ls_R[PART_LONG]; // acoustic pressure in Partition L/R float Ls_M[PART_LONG], Ls_S[PART_LONG]; // acoustic pressure per each partition M/S float PartThr_L[PART_LONG], PartThr_R[PART_LONG]; // masking thresholds L/R (Partition) float PartThr_M[PART_LONG], PartThr_S[PART_LONG]; // masking thresholds M/S (Partition) float sim_Mask_L[PART_LONG], sim_Mask_R[PART_LONG]; // simultaneous masking (only L/R) float clow_L[PART_LONG], clow_R[PART_LONG]; // spread, weighted energy (only L/R) float cLs_L[PART_LONG], cLs_R[PART_LONG]; // weighted partition energy (only L/R) float shortThr_L[PART_SHORT],shortThr_R[PART_SHORT]; // threshold for short FFT (only L/R) int n; int MaxLine = (MaxBand+1)*16; // set FFT-resolution according to MaxBand SMRTyp SMR0; SMRTyp SMR1; // holds SMR's for first and second Analysis int isvoc_L = 0; int isvoc_R = 0; float factorLTQ = 1.f; // Offset after variable LTQ // 'ClearVocalDetection'-Process if ( m->CVD_used ) { memset ( Vocal_L, 0, sizeof Vocal_L ); memset ( Vocal_R, 0, sizeof Vocal_R ); // left channel PowSpec2048 ( &data->L[0], Xerg ); isvoc_L = CVD2048 ( m, Xerg, Vocal_L ); // right channel PowSpec2048 ( &data->R[0], Xerg ); isvoc_R = CVD2048 ( m, Xerg, Vocal_R ); } // calculation of the spectral energy via FFT PolarSpec1024 ( &data->L[0], erg0, phs0 ); // left PolarSpec1024 ( &data->R[0], erg1, phs1 ); // right // calculation of the acoustic pressures per each subband for L/R-signals SubbandEnergy ( MaxBand, Xi_L, Xi_R, erg0, erg1 ); // calculation of the acoustic pressures per each partition PartitionEnergy ( Ls_L, Ls_R, erg0, erg1 ); // calculate the predictability of the signal // left memmove ( Xsave_L+512, Xsave_L, 1024*sizeof(float) ); memmove ( Ysave_L+512, Ysave_L, 1024*sizeof(float) ); CalcUnpred ( m, MaxLine, erg0, phs0, isvoc_L ? Vocal_L : NULL, Xsave_L, Ysave_L, cw_L ); // right memmove ( Xsave_R+512, Xsave_R, 1024*sizeof(float) ); memmove ( Ysave_R+512, Ysave_R, 1024*sizeof(float) ); CalcUnpred ( m, MaxLine, erg1, phs1, isvoc_R ? Vocal_R : NULL, Xsave_R, Ysave_R, cw_R ); // calculation of the weighted acoustic pressures per each partition WeightedPartitionEnergy ( cLs_L, cLs_R, erg0, erg1, cw_L, cw_R ); // Spreading Signal & weighted unpredictability-signal // left memset ( clow_L , 0, sizeof clow_L ); memset ( sim_Mask_L, 0, sizeof sim_Mask_L ); SpreadingSignal ( Ls_L, cLs_L, sim_Mask_L, clow_L ); // right memset ( clow_R , 0, sizeof clow_R ); memset ( sim_Mask_R, 0, sizeof sim_Mask_R ); SpreadingSignal ( Ls_R, cLs_R, sim_Mask_R, clow_R ); // Offset depending on tonality ApplyTonalityOffset ( sim_Mask_L, sim_Mask_R, clow_L, clow_R ); // handling of transient signals // calculate four short FFTs (left) PowSpec256 ( &data->L[ 0+SHORTFFT_OFFSET], F_256[0] ); PowSpec256 ( &data->L[144+SHORTFFT_OFFSET], F_256[1] ); PowSpec256 ( &data->L[288+SHORTFFT_OFFSET], F_256[2] ); PowSpec256 ( &data->L[432+SHORTFFT_OFFSET], F_256[3] ); // calculate short Threshold CalcShortThreshold ( m, F_256, m->ShortThr, shortThr_L, pre_erg_L, TransientL ); // calculate four short FFTs (right) PowSpec256 ( &data->R[ 0+SHORTFFT_OFFSET], F_256[0] ); PowSpec256 ( &data->R[144+SHORTFFT_OFFSET], F_256[1] ); PowSpec256 ( &data->R[288+SHORTFFT_OFFSET], F_256[2] ); PowSpec256 ( &data->R[432+SHORTFFT_OFFSET], F_256[3] ); // calculate short Threshold CalcShortThreshold ( m, F_256, m->ShortThr, shortThr_R, pre_erg_R, TransientR ); // dynamic adjustment of the threshold in quiet to the loudness of the current sequence if ( m->varLtq > 0. ) factorLTQ = AdaptLtq (m, Ls_L, Ls_R ); // utilization of the temporal post-masking if ( m->tmpMask_used ) { CalcTemporalThreshold ( a, b, T_L, sim_Mask_L, tmp_Mask_L ); CalcTemporalThreshold ( c, d, T_R, sim_Mask_R, tmp_Mask_R ); memcpy ( sim_Mask_L, tmp_Mask_L, sizeof sim_Mask_L ); memcpy ( sim_Mask_R, tmp_Mask_R, sizeof sim_Mask_R ); } // transient signal? for ( n = 0; n < PART_SHORT; n++ ) { if ( TransientL [n] ) { sim_Mask_L [3*n ] = minf ( sim_Mask_L [3*n ], shortThr_L [n] ); sim_Mask_L [3*n+1] = minf ( sim_Mask_L [3*n+1], shortThr_L [n] ); sim_Mask_L [3*n+2] = minf ( sim_Mask_L [3*n+2], shortThr_L [n] ); } if ( TransientR[n] ) { sim_Mask_R [3*n ] = minf ( sim_Mask_R [3*n ], shortThr_R [n] ); sim_Mask_R [3*n+1] = minf ( sim_Mask_R [3*n+1], shortThr_R [n] ); sim_Mask_R [3*n+2] = minf ( sim_Mask_R [3*n+2], shortThr_R [n] ); } } // Pre-Echo control PreechoControl ( PartThr_L,PreThr_L, sim_Mask_L, PartThr_R, PreThr_R, sim_Mask_R ); // utilization of the threshold in quiet ApplyLtq ( Thr_L, Thr_R, PartThr_L, PartThr_R, factorLTQ, 0 ); // Consideration of aliasing between the subbands (noise is smeared) // In: Thr[0..511], Out: Thr[512...1023] AdaptThresholds ( MaxLine, Thr_L+512, Thr_R+512 ); memmove ( Thr_L, Thr_L+512, 512*sizeof(float) ); memmove ( Thr_R, Thr_R+512, 512*sizeof(float) ); // calculation of the Signal-to-Mask-Ratio CalculateSMR ( MaxBand, Xi_L, Xi_R, Thr_L, Thr_R, SMR0.L, SMR0.R ); /***************************************************************************************/ /***************************************************************************************/ if ( m->MS_Channelmode > 0 ) { // calculation of the spectral energy via FFT PowSpec1024 ( &data->M[0], erg0 ); // mid PowSpec1024 ( &data->S[0], erg1 ); // side // calculation of the acoustic pressures per each subband for M/S-signals SubbandEnergy ( MaxBand, Xi_M, Xi_S, erg0, erg1 ); // calculation of the acoustic pressures per each partition PartitionEnergy ( Ls_M, Ls_S, erg0, erg1 ); // calculate masking thresholds for M/S CalcMSThreshold ( m, Ls_L, Ls_R, Ls_M, Ls_S, PartThr_L, PartThr_R, PartThr_M, PartThr_S ); ApplyLtq ( Thr_M, Thr_S, PartThr_M, PartThr_S, factorLTQ, 1 ); // Consideration of aliasing between the subbands (noise is smeared) // In: Thr[0..511], Out: Thr[512...1023] AdaptThresholds ( MaxLine, Thr_M+512, Thr_S+512 ); memmove ( Thr_M, Thr_M+512, 512*sizeof(float) ); memmove ( Thr_S, Thr_S+512, 512*sizeof(float) ); // calculation of the Signal-to-Mask-Ratio CalculateSMR ( MaxBand, Xi_M, Xi_S, Thr_M, Thr_S, SMR0.M, SMR0.S ); } if ( m->NS_Order > 0 ) { // providing the Noise Shaping thresholds memcpy ( ANSspec_L, Thr_L, sizeof ANSspec_L ); memcpy ( ANSspec_R, Thr_R, sizeof ANSspec_R ); memcpy ( ANSspec_M, Thr_M, sizeof ANSspec_M ); memcpy ( ANSspec_S, Thr_S, sizeof ANSspec_S ); } /***************************************************************************************/ /***************************************************************************************/ // //-------- second model calculation via shifted FFT ------------------------ // // calculation of the spectral power via FFT PolarSpec1024 ( &data->L[576], erg0, phs0 ); // left PolarSpec1024 ( &data->R[576], erg1, phs1 ); // right // calculation of the acoustic pressures per each subband for L/R-signals SubbandEnergy ( MaxBand, Xi_L, Xi_R, erg0, erg1 ); // calculation of the acoustic pressures per each partition PartitionEnergy ( Ls_L, Ls_R, erg0, erg1 ); // calculate the predictability of the signal // left memmove ( Xsave_L+512, Xsave_L, 1024*sizeof(float) ); memmove ( Ysave_L+512, Ysave_L, 1024*sizeof(float) ); CalcUnpred ( m, MaxLine, erg0, phs0, isvoc_L ? Vocal_L : NULL, Xsave_L, Ysave_L, cw_L ); // right memmove ( Xsave_R+512, Xsave_R, 1024*sizeof(float) ); memmove ( Ysave_R+512, Ysave_R, 1024*sizeof(float) ); CalcUnpred ( m, MaxLine, erg1, phs1, isvoc_R ? Vocal_R : NULL, Xsave_R, Ysave_R, cw_R ); // calculation of the weighted acoustic pressure per each partition WeightedPartitionEnergy ( cLs_L, cLs_R, erg0, erg1, cw_L, cw_R ); // Spreading Signal & weighted unpredictability-signal // left memset ( clow_L , 0, sizeof clow_L ); memset ( sim_Mask_L, 0, sizeof sim_Mask_L ); SpreadingSignal ( Ls_L, cLs_L, sim_Mask_L, clow_L ); // right memset ( clow_R , 0, sizeof clow_R ); memset ( sim_Mask_R, 0, sizeof sim_Mask_R ); SpreadingSignal ( Ls_R, cLs_R, sim_Mask_R, clow_R ); // Offset depending on tonality ApplyTonalityOffset ( sim_Mask_L, sim_Mask_R, clow_L, clow_R ); // Handling of transient signals // calculate four short FFTs (left) PowSpec256 ( &data->L[ 576+SHORTFFT_OFFSET], F_256[0] ); PowSpec256 ( &data->L[ 720+SHORTFFT_OFFSET], F_256[1] ); PowSpec256 ( &data->L[ 864+SHORTFFT_OFFSET], F_256[2] ); PowSpec256 ( &data->L[1008+SHORTFFT_OFFSET], F_256[3] ); // calculate short Threshold CalcShortThreshold ( m, F_256, m->ShortThr, shortThr_L, pre_erg_L, TransientL ); // calculate four short FFTs (right) PowSpec256 ( &data->R[ 576+SHORTFFT_OFFSET], F_256[0] ); PowSpec256 ( &data->R[ 720+SHORTFFT_OFFSET], F_256[1] ); PowSpec256 ( &data->R[ 864+SHORTFFT_OFFSET], F_256[2] ); PowSpec256 ( &data->R[1008+SHORTFFT_OFFSET], F_256[3] ); // calculate short Threshold CalcShortThreshold ( m, F_256, m->ShortThr, shortThr_R, pre_erg_R, TransientR ); // dynamic adjustment of threshold in quiet to loudness of the current sequence if ( m->varLtq > 0. ) factorLTQ = AdaptLtq ( m, Ls_L, Ls_R ); // utilization of temporal post-masking if (m->tmpMask_used) { CalcTemporalThreshold ( a, b, T_L, sim_Mask_L, tmp_Mask_L ); CalcTemporalThreshold ( c, d, T_R, sim_Mask_R, tmp_Mask_R ); memcpy ( sim_Mask_L, tmp_Mask_L, sizeof sim_Mask_L ); memcpy ( sim_Mask_R, tmp_Mask_R, sizeof sim_Mask_R ); } // transient signal? for ( n = 0; n < PART_SHORT; n++ ) { if ( TransientL[n] ) { sim_Mask_L [3*n ] = minf ( sim_Mask_L [3*n ], shortThr_L [n] ); sim_Mask_L [3*n+1] = minf ( sim_Mask_L [3*n+1], shortThr_L [n] ); sim_Mask_L [3*n+2] = minf ( sim_Mask_L [3*n+2], shortThr_L [n] ); } if ( TransientR[n] ) { sim_Mask_R [3*n ] = minf ( sim_Mask_R [3*n ], shortThr_R [n] ); sim_Mask_R [3*n+1] = minf ( sim_Mask_R [3*n+1], shortThr_R [n] ); sim_Mask_R [3*n+2] = minf ( sim_Mask_R [3*n+2], shortThr_R [n] ); } } // Pre-Echo control PreechoControl ( PartThr_L, PreThr_L, sim_Mask_L, PartThr_R, PreThr_R, sim_Mask_R ); // utilization of threshold in quiet ApplyLtq ( Thr_L, Thr_R, PartThr_L, PartThr_R, factorLTQ, 0 ); // Consideration of aliasing between the subbands (noise is smeared) // In: Thr[0..511], Out: Thr[512...1023] AdaptThresholds ( MaxLine, Thr_L+512, Thr_R+512 ); memmove ( Thr_L, Thr_L+512, 512*sizeof(float) ); memmove ( Thr_R, Thr_R+512, 512*sizeof(float) ); // calculation of the Signal-to-Mask-Ratio CalculateSMR ( MaxBand, Xi_L, Xi_R, Thr_L, Thr_R, SMR1.L, SMR1.R ); /***************************************************************************************/ /***************************************************************************************/ if ( m->MS_Channelmode > 0 ) { // calculation of the spectral energy via FFT PowSpec1024 ( &data->M[576], erg0 ); // mid PowSpec1024 ( &data->S[576], erg1 ); // side // calculation of the acoustic pressure per each subband for M/S-signals SubbandEnergy ( MaxBand, Xi_M, Xi_S, erg0, erg1 ); // calculation of the acoustic pressure per each partition PartitionEnergy ( Ls_M, Ls_S, erg0, erg1 ); // calculate masking thresholds for M/S CalcMSThreshold ( m, Ls_L, Ls_R, Ls_M, Ls_S, PartThr_L, PartThr_R, PartThr_M, PartThr_S ); ApplyLtq ( Thr_M, Thr_S, PartThr_M, PartThr_S, factorLTQ, 1 ); // Consideration of aliasing between the subbands (noise is smeared) // In: Thr[0..511], Out: Thr[512...1023] AdaptThresholds ( MaxLine, Thr_M+512, Thr_S+512 ); memmove ( Thr_M, Thr_M+512, 512*sizeof(float) ); memmove ( Thr_S, Thr_S+512, 512*sizeof(float) ); // calculation of the Signal-to-Mask-Ratio CalculateSMR ( MaxBand, Xi_M, Xi_S, Thr_M, Thr_S, SMR1.M, SMR1.S ); } /***************************************************************************************/ /***************************************************************************************/ if ( m->NS_Order > 0 ) { for ( n = 0; n < MAX_ANS_LINES; n++ ) { // providing Noise Shaping thresholds ANSspec_L [n] = minf ( ANSspec_L [n], Thr_L [n] ); ANSspec_R [n] = minf ( ANSspec_R [n], Thr_R [n] ); ANSspec_M [n] = minf ( ANSspec_M [n], Thr_M [n] ); ANSspec_S [n] = minf ( ANSspec_S [n], Thr_S [n] ); } } for ( n = 0; n <= MaxBand; n++ ) { // choose 'worst case'-SMR from shifted analysis windows SMR0.L[n] = maxf ( SMR0.L[n], SMR1.L[n] ); SMR0.R[n] = maxf ( SMR0.R[n], SMR1.R[n] ); SMR0.M[n] = maxf ( SMR0.M[n], SMR1.M[n] ); SMR0.S[n] = maxf ( SMR0.S[n], SMR1.S[n] ); } return SMR0; } musepack_src_r495/libmpcpsy/fft_routines.c0000664000000000000000000001711312231315357017702 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include #include "libmpcpsy.h" #include #define CX0 -1. #define CX1 0.5 #define SX1 -1. #define SX2 (2./9/ 1) #define SX3 (2./9/ 4) #define SX4 (2./9/ 10) #define SX5 (2./9/ 20) #define SX6 (2./9/ 35) #define SX7 (2./9/ 56) #define SX8 (2./9/ 84) #define SX9 (2./9/120) #define SX10 (2./9/165) #ifdef EXTRA_DECONV # define DECONV \ { \ tmp = (CX0*aix[0] + CX1*aix[2]) * (1./(CX0*CX0+CX1*CX1)); \ aix[ 0] -= CX0*tmp; \ aix[ 2] -= CX1*tmp; \ tmp = (SX1*aix[3] + SX2*aix[5] + SX3*aix[7] + SX4*aix[9] + SX5*aix[11]) * (1./(SX1*SX1+SX2*SX2+SX3*SX3+SX4*SX4+SX5*SX5)); \ aix[ 3] -= SX1*tmp; \ aix[ 5] -= SX2*tmp; \ aix[ 7] -= SX3*tmp; \ aix[ 9] -= SX4*tmp; \ aix[11] -= SX5*tmp; \ } #elif 0 # define DECONV \ { \ float A[20]; \ int i; \ memcpy (A, aix, 20*sizeof(aix)); \ tmp = (CX0*aix[0] + CX1*aix[2]) * (1./(CX0*CX0+CX1*CX1)); \ aix[ 0] -= CX0*tmp; \ aix[ 2] -= CX1*tmp; \ tmp = (SX1*aix[3] + SX2*aix[5] + SX3*aix[7] + SX4*aix[9] + SX5*aix[11]) * (1./(SX1*SX1+SX2*SX2+SX3*SX3+SX4*SX4+SX5*SX5)); \ aix[ 3] -= SX1*tmp; \ aix[ 5] -= SX2*tmp; \ aix[ 7] -= SX3*tmp; \ aix[ 9] -= SX4*tmp; \ aix[11] -= SX5*tmp; \ for ( i=0; i<10; i++) \ printf ("%u%9.0f%7.0f%9.0f%7.0f\n",i, A[i+i], A[i+i+1], aix[i+i], aix[i+i+1] ); \ } #else # define DECONV #endif /* V A R I A B L E S */ static int ip [4096]; // bitinverse for maximum 2048 FFT static float w [4096]; // butterfly-coefficient for maximum 2048 FFT static float a [4096]; // holds real input for FFT static float Hann_256 [ 256]; static float Hann_1024 [1024]; static float Hann_1600 [1600]; void Generate_FFT_Tables ( const int, int*, float* ); void rdft ( const int, float*, int*, float* ); ////////////////////////////// // // BesselI0 -- Regular Modified Cylindrical Bessel Function (Bessel I). // static double Bessel_I_0 ( double x ) { double denominator; double numerator; double z; if (x == 0.) return 1.; z = x * x; numerator = z* (z* (z* (z* (z* (z* (z* (z* (z* (z* (z* (z* (z* (z* 0.210580722890567e-22 + 0.380715242345326e-19 ) + 0.479440257548300e-16) + 0.435125971262668e-13 ) + 0.300931127112960e-10) + 0.160224679395361e-07 ) + 0.654858370096785e-05) + 0.202591084143397e-02 ) + 0.463076284721000e+00) + 0.754337328948189e+02 ) + 0.830792541809429e+04) + 0.571661130563785e+06 ) + 0.216415572361227e+08) + 0.356644482244025e+09 ) + 0.144048298227235e+10; denominator = z* (z* (z - 0.307646912682801e+04) + 0.347626332405882e+07) - 0.144048298227235e+10; return - numerator / denominator; } static double residual ( double x ) { return sqrt ( 1. - x*x ); } ////////////////////////////// // // KBDWindow -- Kaiser Bessel Derived Window // fills the input window array with size samples of the // KBD window with the given tuning parameter alpha. // static void KBDWindow ( float* window, unsigned int size, float alpha ) { double sumvalue = 0.; double scale; int i; scale = 0.25 / sqrt (size); for ( i = 0; i < (int)size/2; i++ ) window [i] = sumvalue += Bessel_I_0 ( M_PI * alpha * residual (4.*i/size - 1.) ); // need to add one more value to the nomalization factor at size/2: sumvalue += Bessel_I_0 ( M_PI * alpha * residual (4.*(size/2)/size-1.) ); // normalize the window and fill in the righthand side of the window: for ( i = 0; i < (int)size/2; i++ ) window [size-1-i] = window [i] = /*sqrt*/ ( window [i] / sumvalue ) * scale; } static void CosWindow ( float* window, unsigned int size ) { double x; double scale; int i; scale = 0.25 / sqrt (size); for ( i = 0; i < (int)size/2; i++ ) { x = cos ( (i+0.5) * (M_PI / size) ); window [size/2-1-i] = window [size/2+i] = scale * x * x; } } static void Window ( float* window, unsigned int size, float alpha ) { if ( alpha < 0. ) CosWindow ( window, size ) ; else KBDWindow ( window, size, alpha ); } /* F U N C T I O N S */ // generates FFT lookup-tables void Init_FFT ( PsyModel* m ) { int n; double x; double scale; // normalized hann functions Window ( Hann_256 , 256, m->KBD1 ); Window ( Hann_1024, 1024, m->KBD2 ); scale = 0.25 / sqrt (2048.); for ( n = 0; n < 800; n++ ) x = cos ((n+0.5) * (M_PI/1600)), Hann_1600 [799-n] = Hann_1600 [800+n] = (float)(x * x * scale); Generate_FFT_Tables ( 2048, ip, w ); } // input : Signal *x // output: energy spectrum *erg void PowSpec256 ( const float* x, float* erg ) { int i; // windowing for( i = 0; i < 256; ++i ) a[i] = x[i] * Hann_256[i]; rdft(256, a, ip, w); // perform FFT // calculate power for( i = 0; i < 128; ++i) erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1]; } // input : Signal *x // output: energy spectrum *erg void PowSpec1024 ( const float* x, float* erg ) { int i; // windowing for( i = 0; i < 1024; ++i ) a[i] = x[i] * Hann_1024[i]; rdft(1024, a, ip, w); // perform FFT // calculate power for( i = 0; i < 512; ++i) erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1]; } // input : Signal *x // output: energy spectrum *erg void PowSpec2048 ( const float* x, float* erg ) { int i; // windowing (only 1600 samples available -> centered in 2048!) memset(a, 0, 224 * sizeof *a); for( i = 0; i < 1600; ++i ) a[i+224] = x[i] * Hann_1600[i]; memset(a + 1824, 0, 224 * sizeof *a); rdft(2048, a, ip, w); // perform FFT // calculate power for( i = 0; i < 1024; ++i) erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1]; } // input : Signal *x // output: energy spectrum *erg and phase spectrum *phs void PolarSpec1024 ( const float* x, float* erg, float* phs ) { int i; for( i = 0; i < 1024; i++ ) a[i] = x[i] * Hann_1024[i]; rdft( 1024, a, ip, w); // perform FFT // calculate power and phase for( i = 0; i < 512; ++i ) { erg[i] = a[i*2] * a[i*2] + a[i*2+1] * a[i*2+1]; phs[i] = ATAN2F( a[i*2+1], a[i*2] ); } } // input : logarithmized energy spectrum *cep // output: Cepstrum *cep (in-place) void Cepstrum2048 ( float* cep, const int MaxLine ) { int i, j; // generate real, even spectrum (symmetric around 1024, cep[2048-i] = cep[i]) for( i = 0, j = 1024; i < 1024; ++i, --j ) cep[1024 + j] = cep[i]; rdft(2048, cep, ip, w); // only real part as outcome (all even indexes of cep[]) for( i = 0; i < MaxLine + 1; ++i ) cep[i] = cep[i*2] * (float) (0.9888 / 2048); } musepack_src_r495/libmpcpsy/libmpcpsy.h0000664000000000000000000000763112231315357017206 0ustar rootroot/* * Musepack audio compression * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ // psy_tab.h #define PART_LONG 57 // number of partitions for long #define PART_SHORT (PART_LONG / 3) // number of partitions for short #define MAX_SPL 20 // maximum assumed Sound Pressure Level // psy.c #define SHORTFFT_OFFSET 168 // fft-offset for short FFT's #define PREFAC_LONG 10 // preecho-factor for long partitions #define MAX_CVD_LINE 300 // maximum FFT-Index for CVD #define CVD_UNPRED 0.040f // unpredictability (cw) for CVD-detected bins, e33 (04) #define MIN_ANALYZED_IDX 12 // maximum base-frequency = 44100/MIN_ANALYZED_IDX ^^^^^^ #define MED_ANALYZED_IDX 50 // maximum base-frequency = 44100/MED_ANALYZED_IDX ^^^^^^ #define MAX_ANALYZED_IDX 900 // minimum base-frequency = 44100/MAX_ANALYZED_IDX (816 for Amnesia) #define MAX_NS_ORDER 6 // maximum order of the Adaptive Noise Shaping Filter (IIR) #define MAX_ANS_BANDS 16 #define MAX_ANS_LINES (32 * MAX_ANS_BANDS) // maximum number of noiseshaped FFT-lines ///////// 16 * MAX_ANS_BANDS not sufficient? ////////////////// #define MS2SPAT1 0.5f #define MS2SPAT2 0.25f #define MS2SPAT3 0.125f #define MS2SPAT4 0.0625f typedef struct { float L [32]; float R [32]; float M [32]; float S [32]; } SMRTyp; typedef struct { int Max_Band; // maximum bandwidth float SampleFreq; int MainQual; // main profile quality float FullQual; // full profile quality // profile params float ShortThr; // Factor to calculate the masking threshold with transients int MinValChoice; unsigned int EarModelFlag; float Ltq_offset; // Offset for threshold in quiet float TMN; // Offset for purely sinusoid components float NMT; // Offset for purely noisy components float minSMR; // minimum SMR for all subbands float Ltq_max; // maximum level for threshold in quiet float BandWidth; unsigned char tmpMask_used; // global flag for temporal masking unsigned char CVD_used; // global flag for ClearVoiceDetection float varLtq; // variable threshold in quiet unsigned char MS_Channelmode; int CombPenalities; unsigned int NS_Order; // Maximum order for ANS float PNS; float TransDetect; // minimum slewrate for transient detection // ans.h unsigned int NS_Order_L [32]; unsigned int NS_Order_R [32]; // frame-wise order of the Noiseshaping (0: off, 1...5: on) float FIR_L [32] [MAX_NS_ORDER]; float FIR_R [32] [MAX_NS_ORDER]; // contains FIR-Filter for NoiseShaping float SNR_comp_L [32]; float SNR_comp_R [32]; // SNR-compensation after SCF-combination and ANS-gain float KBD1; // = 2. float KBD2; // = -1. // FIXME : remove this : int * SCF_Index_L; int * SCF_Index_R; // Scalefactor-index for Bitstream } PsyModel; musepack_src_r495/libmpcpsy/cvd.c0000664000000000000000000003350312231315357015750 0ustar rootroot/* * Musepack audio compression * Copyright (c) 2005-2009, The Musepack Development Team * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include #include "mpc/mpc_types.h" #include "mpc/mpcmath.h" #include "libmpcpsy.h" void Cepstrum2048 ( float* cep, const int ); /* C O N S T A N T S */ // from MatLab-Simulation (Fourier-transforms of the Cos-Rolloff) #if 0 static const float Puls [11] = { -0.02724753942504f, -0.10670808991329f, -0.06198987803623f, 0.18006206051664f, 0.49549552704050f, 0.64201253447071f, 0.49549552704050f, 0.18006206051664f, -0.06198987803623f, -0.10670808991329f, -0.02724753942504f }; #endif static const float Puls [ 9] = { -0.10670808991329f, -0.06198987803623f, 0.18006206051664f, 0.49549552704050f, 0.64201253447071f, 0.49549552704050f, 0.18006206051664f, -0.06198987803623f, -0.10670808991329f }; /* // Generating the Cos-Rolloff of the Cepstral-analysis, Cos-Rolloff from 5512,5 Hz to 11025 Hz // for ( k = 0; k <= 1024; k++ ) { // if (k < 256) CosWin [k-256] = 1; // else if (k < 512) CosWin [k-256] = 0.5 + 0.5*cos (M_PI*(k-256)/256); // else CosWin [k-256] = 0; // } */ static const float CosWin [256] = { 1.0000000000000000f, 0.9999623298645020f, 0.9998494386672974f, 0.9996612071990967f, 0.9993977546691895f, 0.9990590810775757f, 0.9986452460289002f, 0.9981563091278076f, 0.9975923895835877f, 0.9969534873962402f, 0.9962397813796997f, 0.9954513311386108f, 0.9945882558822632f, 0.9936507344245911f, 0.9926388263702393f, 0.9915527701377869f, 0.9903926253318787f, 0.9891586899757385f, 0.9878510832786560f, 0.9864699840545654f, 0.9850156307220459f, 0.9834882616996765f, 0.9818880558013916f, 0.9802152514457703f, 0.9784701466560364f, 0.9766530394554138f, 0.9747641086578369f, 0.9728036522865295f, 0.9707720279693604f, 0.9686695337295532f, 0.9664964079856873f, 0.9642530679702759f, 0.9619397521018982f, 0.9595569372177124f, 0.9571048617362976f, 0.9545840024948120f, 0.9519946575164795f, 0.9493372440338135f, 0.9466121792793274f, 0.9438198208808899f, 0.9409606456756592f, 0.9380350708961487f, 0.9350435137748718f, 0.9319864511489868f, 0.9288643002510071f, 0.9256775975227356f, 0.9224267601966858f, 0.9191123247146606f, 0.9157348275184631f, 0.9122946262359619f, 0.9087924361228943f, 0.9052286148071289f, 0.9016037583351135f, 0.8979184627532959f, 0.8941732048988342f, 0.8903686404228210f, 0.8865052461624146f, 0.8825836181640625f, 0.8786044120788574f, 0.8745682239532471f, 0.8704755902290344f, 0.8663271069526672f, 0.8621235489845276f, 0.8578653931617737f, 0.8535534143447876f, 0.8491881489753723f, 0.8447702527046204f, 0.8403005003929138f, 0.8357794880867004f, 0.8312078714370728f, 0.8265864253044128f, 0.8219157457351685f, 0.8171966671943665f, 0.8124297261238098f, 0.8076158165931702f, 0.8027555346488953f, 0.7978496551513672f, 0.7928989529609680f, 0.7879040837287903f, 0.7828658819198608f, 0.7777851223945618f, 0.7726625204086304f, 0.7674987912178040f, 0.7622948288917542f, 0.7570513486862183f, 0.7517691850662231f, 0.7464491128921509f, 0.7410919070243835f, 0.7356983423233032f, 0.7302693724632263f, 0.7248056530952454f, 0.7193081378936768f, 0.7137775421142578f, 0.7082147598266602f, 0.7026206851005554f, 0.6969960331916809f, 0.6913416981697083f, 0.6856585741043091f, 0.6799474954605103f, 0.6742093563079834f, 0.6684449315071106f, 0.6626551747322083f, 0.6568408608436585f, 0.6510030031204224f, 0.6451423168182373f, 0.6392598152160645f, 0.6333563923835754f, 0.6274328231811523f, 0.6214900612831116f, 0.6155290603637695f, 0.6095505952835083f, 0.6035556793212891f, 0.5975451469421387f, 0.5915199518203735f, 0.5854809284210205f, 0.5794290900230408f, 0.5733652114868164f, 0.5672903656959534f, 0.5612053275108337f, 0.5551111102104187f, 0.5490085482597351f, 0.5428986549377441f, 0.5367822647094727f, 0.5306603908538818f, 0.5245338082313538f, 0.5184035897254944f, 0.5122706294059753f, 0.5061357617378235f, 0.5000000000000000f, 0.4938642382621765f, 0.4877294003963471f, 0.4815963804721832f, 0.4754661619663239f, 0.4693396389484406f, 0.4632177054882050f, 0.4571013450622559f, 0.4509914219379425f, 0.4448888897895813f, 0.4387946724891663f, 0.4327096343040466f, 0.4266347587108612f, 0.4205709397792816f, 0.4145190417766571f, 0.4084800481796265f, 0.4024548530578613f, 0.3964443206787109f, 0.3904493749141693f, 0.3844709396362305f, 0.3785099089145660f, 0.3725671768188477f, 0.3666436076164246f, 0.3607401549816132f, 0.3548576533794403f, 0.3489970266819000f, 0.3431591391563416f, 0.3373448550701141f, 0.3315550684928894f, 0.3257906734943390f, 0.3200524747371674f, 0.3143413960933685f, 0.3086582720279694f, 0.3030039668083191f, 0.2973793447017670f, 0.2917852103710175f, 0.2862224578857422f, 0.2806918919086456f, 0.2751943469047546f, 0.2697306573390961f, 0.2643016278743744f, 0.2589081227779388f, 0.2535509169101715f, 0.2482308149337769f, 0.2429486215114594f, 0.2377051562070847f, 0.2325011938810349f, 0.2273375093936920f, 0.2222148776054382f, 0.2171340882778168f, 0.2120959013700485f, 0.2071010768413544f, 0.2021503448486328f, 0.1972444802522659f, 0.1923841983079910f, 0.1875702589750290f, 0.1828033626079559f, 0.1780842244625092f, 0.1734135746955872f, 0.1687921136617661f, 0.1642205268144608f, 0.1596994996070862f, 0.1552297323942184f, 0.1508118808269501f, 0.1464466154575348f, 0.1421345919370651f, 0.1378764659166336f, 0.1336728632450104f, 0.1295244395732880f, 0.1254318058490753f, 0.1213955804705620f, 0.1174163669347763f, 0.1134947761893272f, 0.1096313893795013f, 0.1058267876505852f, 0.1020815446972847f, 0.0983962342143059f, 0.0947714000940323f, 0.0912075936794281f, 0.0877053514122963f, 0.0842651948332787f, 0.0808876454830170f, 0.0775732174515724f, 0.0743224024772644f, 0.0711356922984123f, 0.0680135712027550f, 0.0649565011262894f, 0.0619649514555931f, 0.0590393692255020f, 0.0561801902949810f, 0.0533878505229950f, 0.0506627671420574f, 0.0480053536593914f, 0.0454160086810589f, 0.0428951233625412f, 0.0404430739581585f, 0.0380602329969406f, 0.0357469581067562f, 0.0335035994648933f, 0.0313304923474789f, 0.0292279683053494f, 0.0271963365375996f, 0.0252359099686146f, 0.0233469791710377f, 0.0215298328548670f, 0.0197847411036491f, 0.0181119665503502f, 0.0165117643773556f, 0.0149843730032444f, 0.0135300243273377f, 0.0121489353477955f, 0.0108413146808743f, 0.0096073597669601f, 0.0084472559392452f, 0.0073611787520349f, 0.0063492907211185f, 0.0054117450490594f, 0.0045486823655665f, 0.0037602325901389f, 0.0030465149320662f, 0.0024076367262751f, 0.0018436938989908f, 0.0013547716662288f, 0.0009409435442649f, 0.0006022718735039f, 0.0003388077020645f, 0.0001505906548118f, 0.0000376490788767f, }; /* F U N C T I O N S */ // sets all the harmonics static void SetVoiceLines ( int* VoiceLine, const float base, int val ) { int n; int max = (int) (MAX_CVD_LINE * base / 1024.f); // harmonics up to Index MAX_CVD_LINE (spectral lines outside of that don't make sense) int line; float frq = 1024.f / base; // frq = 1024./i is the Index of the basic harmonic // go through all harmonics for ( n = 1; n <= max; n++ ) { line = (int) (n * frq); VoiceLine [line] = VoiceLine [line+1] = val; } } // Analyze the Cepstrum, search for the basic harmonic static void CEP_Analyse2048 ( PsyModel* m, float* res1, float* res2, float* qual1, float* qual2, float* cep ) { int n; int line; float cc [MAX_ANALYZED_IDX + 3]; // cross correlation float ref; float line_sum; float sum; float kkf; float norm; const float* x; // cross-correlation with pulse shape // Calculate idx = MIN_ANALYZED_IDX-2 to MAX_ANALYZED_IDX+2, // because they are read during search for maximum // 50 -> 882 Hz, 700 -> 63 Hz base frequency *res1 = *res2 = 0. ; memset ( cc, 0, sizeof cc ); for ( n = MIN_ANALYZED_IDX - 2; n <= MAX_ANALYZED_IDX + 2; n++ ) { x = cep + n; if ( x[0] > 0 ) { norm = x[-4] * x[-4] + x[-3] * x[-3] + x[-2] * x[-2] + x[-1] * x[-1] + x[ 0] * x[ 0] + x[ 1] * x[ 1] + x[ 2] * x[ 2] + x[ 3] * x[ 3] + x[ 4] * x[ 4]; kkf = x[-4] * Puls [0] + x[-3] * Puls [1] + x[-2] * Puls [2] + x[-1] * Puls [3] + x[ 0] * Puls [4] + x[ 1] * Puls [5] + x[ 2] * Puls [6] + x[ 3] * Puls [7] + x[ 4] * Puls [8]; cc [n] = kkf * kkf / norm; // calculate the square of ncc to avoid sqrt() } } // search for the (relative) maximum ref = 0.f; line = MED_ANALYZED_IDX; for ( n = MAX_ANALYZED_IDX; n >= MED_ANALYZED_IDX; n-- ) { if ( cc[n] * cep[n] * cep[n] > ref && cc[n] > 0.40f && // e33 (02) 0.85 cep[n] > 0.00f && // e33 (02) cc[n ] >= cc[n+1] && cc[n ] >= cc[n-1] && cc[n+1] >= cc[n+2] && cc[n-1] >= cc[n-2] ) { ref = cc[n] * cep[n] * cep[n]; line = n; } } // Calculating the center of the maximum (Interpolation) x = cep + line; sum = x[-3] + x[-2] + x[-1] + x[0] + x[1] + x[2] + x[3] + 1.e-30f; line_sum = (x[1]-x[-1]) + 2 * (x[2]-x[-2]) + 3 * (x[3]-x[-3]) + sum * line + 1.e-30f; /* e33 (04) */ ref = cc[line ] * cep[line ] * cep[line ] + cc[line-1] * cep[line-1] * cep[line-1] + cc[line+1] * cep[line+1] * cep[line+1]; //{ // static unsigned int x = 0; // // printf ("%7.3f s ", (x/2)*1152./44100 ); // x++; //} //printf ("ref=%5.3f *res1=%7.3f f=%8.3f ", ref, line_sum / sum, 44100. / (line_sum / sum) ); *qual1 = ref; if ( ref > 0.015f ) *res1 = line_sum / sum; if ( m->CVD_used < 2 ) return; // search for the (relative) maximum ref = 0.f; line = MIN_ANALYZED_IDX; for ( n = MED_ANALYZED_IDX + 1; n >= MIN_ANALYZED_IDX - 1; n-- ) { cc [2*n ] += 0.5 * cc [n]; cc [2*n+1] += 0.5 * (cc [n] + cc[n+1]); cep [2*n ] += 0.5 * cep [n]; cep [2*n+1] += 0.5 * (cep [n] + cep[n+1]); } for ( n = 2*MED_ANALYZED_IDX; n >= 2*MIN_ANALYZED_IDX; n-- ) { if ( cc[n] * cep[n] * cep[n] > ref && cc[n] > 0.85f && /* e33 (02) */ cep[n] > 0.00f && /* e33 (02) */ cc[n ] >= cc[n+1] && cc[n ] >= cc[n-1] && cc[n+1] >= cc[n+2] && cc[n-1] >= cc[n-2] ) { ref = cc[n] * cep[n] * cep[n]; line = n; } } // Calculating the center of the maximum (Interpolation) x = cep + line; sum = x[-3] + x[-2] + x[-1] + x[0] + x[1] + x[2] + x[3] + 1.e-30f; line_sum = (x[1]-x[-1]) + 2 * (x[2]-x[-2]) + 3 * (x[3]-x[-3]) + sum * line + 1.e-30f; /* e33 (04) */ ref = cc[line ] * cep[line ] * cep[line ] + cc[line-1] * cep[line-1] * cep[line-1] + cc[line+1] * cep[line+1] * cep[line+1]; //printf ("ref=%5.3f *res2=%8.3f f=%8.3f\n", ref, 0.5 * line_sum / sum, 44100. / (0.5 * line_sum / sum) ); *qual2 = ref; if ( ref >= 0.1f ) *res2 = 0.5 * line_sum / sum; return; } #ifndef CVD_FASTLOG # define logfast(x) ((float) log (x)) #else static mpc_inline float /* This is a rough estimation with an accuracy of |x|<0.0037 */ logfast ( float x ) { mpc_doubleint y; y.d = x * x; y.d *= y.d; y.d *= y.d; return (y.n[1] + (45127.5 - 1072693248.)) * ( M_LN2 / (1L<<23) ); } #endif // ClearVoiceDetection for spectrum *spec // input : Spectrum *spec // output: Array *vocal contains information if the FFT-Line is a harmonic component int CVD2048 ( PsyModel* m, const float* spec, int* vocal ) { static float cep [4096]; // cep[4096] -- array, which is also used for the 2048 FFT const float* win = CosWin; // pointer to cos-roll-off float res1; float res2; float qual1; float qual2; int n; // Calculating logarithmated, windowed spectrum cep[] // cep[512...1024] = 0 -- cep[1025...2047] doesn't matter, because the first have to be filled by fft for ( n = 0; n < 256; n++ ) cep[n] = logfast (*spec++); for ( n = 256; n < 512; n++ ) cep[n] = logfast (*spec++) * *win++; memset ( cep+512, 0, 513*sizeof(*cep) ); // Calculating cepstrum of cep[] (the function Cepstrum() outputs the cepstrum in-place) Cepstrum2048 ( cep, MAX_ANALYZED_IDX ); // search the harmonic CEP_Analyse2048 ( m, &res1, &res2, &qual1, &qual2, cep ); //#include "cvd.h" if ( res1 > 0.f || res2 > 0.f ) { if ( res1 > 0. ) SetVoiceLines ( vocal, res1, 100 ); if ( res2 > 0. ) SetVoiceLines ( vocal, res2, 20 ); return 1; } return 0; } musepack_src_r495/win32/0000775000000000000000000000000012765302355013772 5ustar rootrootmusepack_src_r495/win32/mpcdec.vcproj0000664000000000000000000001012411144566617016453 0ustar rootroot musepack_src_r495/win32/libcommon.vcproj0000664000000000000000000000727311144566617017212 0ustar rootroot musepack_src_r495/win32/libcommon_2005.vcproj0000664000000000000000000000762511154722375017655 0ustar rootroot musepack_src_r495/win32/mpccut.vcproj0000664000000000000000000001027711144566617016524 0ustar rootroot musepack_src_r495/win32/dirent.h0000664000000000000000000001514210715305673015432 0ustar rootroot/* ///////////////////////////////////////////////////////////////////////////// * File: dirent.h * * Purpose: Declaration of the opendir() API functions and types for the * Win32 platform. * * Created: 19th October 2002 * Updated: 12th September 2006 * * Home: http://synesis.com.au/software/ * * Copyright (c) 2002-2006, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the names of Matthew Wilson and Synesis Software nor the names of * any contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////////// */ /** \file dirent.h * * Contains the declarations for the opendir()/readdir() API. */ #ifndef SYNSOFT_UNIXEM_INCL_H_DIRENT #define SYNSOFT_UNIXEM_INCL_H_DIRENT #ifndef UNIXEM_DOCUMENTATION_SKIP_SECTION # define SYNSOFT_UNIXEM_VER_H_DIRENT_MAJOR 3 # define SYNSOFT_UNIXEM_VER_H_DIRENT_MINOR 3 # define SYNSOFT_UNIXEM_VER_H_DIRENT_REVISION 1 # define SYNSOFT_UNIXEM_VER_H_DIRENT_EDIT 29 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ /* ////////////////////////////////////////////////////////////////////////// */ /** \weakgroup unixem Synesis Software UNIX Emulation for Win32 * \brief The UNIX emulation library */ /** \weakgroup unixem_dirent opendir()/readdir() API * \ingroup UNIXem unixem * \brief This API provides facilities for enumerating the contents of directories * @{ */ /* ////////////////////////////////////////////////////////////////////////// */ #ifndef _WIN32 # error This file is only currently defined for compilation on Win32 systems #endif /* _WIN32 */ /* ///////////////////////////////////////////////////////////////////////////// * Includes */ #include /* ///////////////////////////////////////////////////////////////////////////// * Constants and definitions */ #ifndef NAME_MAX # define NAME_MAX (260) /*!< \brief The maximum number of characters (including null terminator) in a directory entry name */ #endif /* !NAME_MAX */ /* ///////////////////////////////////////////////////////////////////////////// * Typedefs */ typedef struct dirent_dir DIR; /*!< \brief Handle type for ANSI directory enumeration. \note dirent_dir is defined internally */ typedef struct wdirent_dir wDIR; /*!< \brief Handle type for Unicode directory enumeration. \note dirent_dir is defined internally */ /** \brief Results structure for readdir() */ struct dirent { char d_name[NAME_MAX + 1]; /*!< file name (null-terminated) */ int d_mode; }; /** \brief Results structure for wreaddir() */ struct wdirent { wchar_t d_name[NAME_MAX + 1]; /*!< file name (null-terminated) */ int d_mode; }; /* ///////////////////////////////////////////////////////////////////////////// * API functions */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** \brief Returns a pointer to the next directory entry. * * This function opens the directory named by filename, and returns a * directory to be used to in subsequent operations. NULL is returned * if name cannot be accessed, or if resources cannot be acquired to * process the request. * * \param name The name of the directory to search * \return The directory handle from which the entries are read or NULL */ DIR *opendir(const char *name); /** \brief Identical semantics to opendir(), but for Unicode searches. */ wDIR *wopendir(const wchar_t *name); /** \brief Closes a directory handle * * This function closes a directory handle that was opened with opendir() * and releases any resources associated with that directory handle. * * \param dir The directory handle from which the entries are read * \return 0 on success, or -1 to indicate error. */ int closedir(DIR *dir); /** \brief Identical semantics to closedir(), but for Unicode searches. */ int wclosedir(wDIR *dir); /** \brief Resets a directory search position * * This function resets the position of the named directory handle to * the beginning of the directory. * * \param dir The directory handle whose position should be reset */ void rewinddir(DIR *dir); /** \brief Identical semantics to rewinddir(), but for Unicode searches. */ void wrewinddir(wDIR *dir); /** \brief Returns a pointer to the next directory entry. * * This function returns a pointer to the next directory entry, or NULL upon * reaching the end of the directory or detecting an invalid seekdir() operation * * \param dir The directory handle from which the entries are read * \return A dirent structure or NULL */ struct dirent *readdir(DIR *dir); /** \brief Identical semantics to readdir(), but for Unicode searches. */ struct wdirent *wreaddir(wDIR *dir); #ifdef __cplusplus } #endif /* __cplusplus */ /* ////////////////////////////////////////////////////////////////////////// */ /** @} // end of group unixem_dirent */ /* ////////////////////////////////////////////////////////////////////////// */ #endif /* SYNSOFT_UNIXEM_INCL_H_DIRENT */ /* ////////////////////////////////////////////////////////////////////////// */ musepack_src_r495/win32/musepack_2005.sln0000664000000000000000000000275011154722375016771 0ustar rootroot Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon_2005", "libcommon_2005.vcproj", "{0B4DF6B1-30B1-42E1-BC54-B62A178609C0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpcdec_2005", "libmpcdec_2005.vcproj", "{7E82CFCF-1B5F-496D-8A1D-863CF574C7AF}" ProjectSection(ProjectDependencies) = postProject {0B4DF6B1-30B1-42E1-BC54-B62A178609C0} = {0B4DF6B1-30B1-42E1-BC54-B62A178609C0} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0B4DF6B1-30B1-42E1-BC54-B62A178609C0}.Debug|Win32.ActiveCfg = Debug|Win32 {0B4DF6B1-30B1-42E1-BC54-B62A178609C0}.Debug|Win32.Build.0 = Debug|Win32 {0B4DF6B1-30B1-42E1-BC54-B62A178609C0}.Release|Win32.ActiveCfg = Release|Win32 {0B4DF6B1-30B1-42E1-BC54-B62A178609C0}.Release|Win32.Build.0 = Release|Win32 {7E82CFCF-1B5F-496D-8A1D-863CF574C7AF}.Debug|Win32.ActiveCfg = Debug|Win32 {7E82CFCF-1B5F-496D-8A1D-863CF574C7AF}.Debug|Win32.Build.0 = Debug|Win32 {7E82CFCF-1B5F-496D-8A1D-863CF574C7AF}.Release|Win32.ActiveCfg = Release|Win32 {7E82CFCF-1B5F-496D-8A1D-863CF574C7AF}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal musepack_src_r495/win32/mpcenc.vcproj0000664000000000000000000001200111144566617016461 0ustar rootroot musepack_src_r495/win32/libmpcdec.vcproj0000664000000000000000000001155311144566617017151 0ustar rootroot musepack_src_r495/win32/libmpcpsy.vcproj0000664000000000000000000001014711144566617017227 0ustar rootroot musepack_src_r495/win32/musepack.sln0000664000000000000000000001561111144566617016327 0ustar rootroot Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpcenc", "mpcenc.vcproj", "{15082E34-9324-469F-8423-F995B4814A37}" ProjectSection(ProjectDependencies) = postProject {49A26D14-0AD0-497E-A982-42BFD4D992FC} = {49A26D14-0AD0-497E-A982-42BFD4D992FC} {7CF31624-B40E-466F-9107-785816C787C4} = {7CF31624-B40E-466F-9107-785816C787C4} {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} = {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon", "libcommon.vcproj", "{49A26D14-0AD0-497E-A982-42BFD4D992FC}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpcpsy", "libmpcpsy.vcproj", "{7CF31624-B40E-466F-9107-785816C787C4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpcenc", "libmpcenc.vcproj", "{44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpcdec", "mpcdec.vcproj", "{A527175B-22A9-41AB-B2E8-580F573CCAFB}" ProjectSection(ProjectDependencies) = postProject {49A26D14-0AD0-497E-A982-42BFD4D992FC} = {49A26D14-0AD0-497E-A982-42BFD4D992FC} {13D176A2-B6BB-403F-A816-AA1F388078B7} = {13D176A2-B6BB-403F-A816-AA1F388078B7} {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} = {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpccut", "mpccut.vcproj", "{ABBF9DD7-650F-48A8-9810-B76F233520F3}" ProjectSection(ProjectDependencies) = postProject {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} = {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} {49A26D14-0AD0-497E-A982-42BFD4D992FC} = {49A26D14-0AD0-497E-A982-42BFD4D992FC} {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} = {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpc2sv8", "mpc2sv8.vcproj", "{36225C6A-FFA3-4E70-928E-1F69F7A3FCE1}" ProjectSection(ProjectDependencies) = postProject {49A26D14-0AD0-497E-A982-42BFD4D992FC} = {49A26D14-0AD0-497E-A982-42BFD4D992FC} {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} = {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96} {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} = {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmpcdec", "libmpcdec.vcproj", "{4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwavformat", "libwavformat.vcproj", "{13D176A2-B6BB-403F-A816-AA1F388078B7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libreplaygain", "..\..\..\libreplaygain\libreplaygain.vcproj", "{CB7A02E8-393A-481B-BD18-E7D041D8C6B1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpcgain", "mpcgain.vcproj", "{76CBB7D4-0524-4569-9150-34BDE4235D04}" ProjectSection(ProjectDependencies) = postProject {49A26D14-0AD0-497E-A982-42BFD4D992FC} = {49A26D14-0AD0-497E-A982-42BFD4D992FC} {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} = {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3} {CB7A02E8-393A-481B-BD18-E7D041D8C6B1} = {CB7A02E8-393A-481B-BD18-E7D041D8C6B1} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {15082E34-9324-469F-8423-F995B4814A37}.Debug|Win32.ActiveCfg = Debug|Win32 {15082E34-9324-469F-8423-F995B4814A37}.Debug|Win32.Build.0 = Debug|Win32 {15082E34-9324-469F-8423-F995B4814A37}.Release|Win32.ActiveCfg = Release|Win32 {15082E34-9324-469F-8423-F995B4814A37}.Release|Win32.Build.0 = Release|Win32 {49A26D14-0AD0-497E-A982-42BFD4D992FC}.Debug|Win32.ActiveCfg = Debug|Win32 {49A26D14-0AD0-497E-A982-42BFD4D992FC}.Debug|Win32.Build.0 = Debug|Win32 {49A26D14-0AD0-497E-A982-42BFD4D992FC}.Release|Win32.ActiveCfg = Release|Win32 {49A26D14-0AD0-497E-A982-42BFD4D992FC}.Release|Win32.Build.0 = Release|Win32 {7CF31624-B40E-466F-9107-785816C787C4}.Debug|Win32.ActiveCfg = Debug|Win32 {7CF31624-B40E-466F-9107-785816C787C4}.Debug|Win32.Build.0 = Debug|Win32 {7CF31624-B40E-466F-9107-785816C787C4}.Release|Win32.ActiveCfg = Release|Win32 {7CF31624-B40E-466F-9107-785816C787C4}.Release|Win32.Build.0 = Release|Win32 {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96}.Debug|Win32.ActiveCfg = Debug|Win32 {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96}.Debug|Win32.Build.0 = Debug|Win32 {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96}.Release|Win32.ActiveCfg = Release|Win32 {44EC1266-D2EE-47B8-ACFC-8BD52E7FFF96}.Release|Win32.Build.0 = Release|Win32 {A527175B-22A9-41AB-B2E8-580F573CCAFB}.Debug|Win32.ActiveCfg = Debug|Win32 {A527175B-22A9-41AB-B2E8-580F573CCAFB}.Debug|Win32.Build.0 = Debug|Win32 {A527175B-22A9-41AB-B2E8-580F573CCAFB}.Release|Win32.ActiveCfg = Release|Win32 {A527175B-22A9-41AB-B2E8-580F573CCAFB}.Release|Win32.Build.0 = Release|Win32 {ABBF9DD7-650F-48A8-9810-B76F233520F3}.Debug|Win32.ActiveCfg = Debug|Win32 {ABBF9DD7-650F-48A8-9810-B76F233520F3}.Debug|Win32.Build.0 = Debug|Win32 {ABBF9DD7-650F-48A8-9810-B76F233520F3}.Release|Win32.ActiveCfg = Release|Win32 {ABBF9DD7-650F-48A8-9810-B76F233520F3}.Release|Win32.Build.0 = Release|Win32 {36225C6A-FFA3-4E70-928E-1F69F7A3FCE1}.Debug|Win32.ActiveCfg = Debug|Win32 {36225C6A-FFA3-4E70-928E-1F69F7A3FCE1}.Debug|Win32.Build.0 = Debug|Win32 {36225C6A-FFA3-4E70-928E-1F69F7A3FCE1}.Release|Win32.ActiveCfg = Release|Win32 {36225C6A-FFA3-4E70-928E-1F69F7A3FCE1}.Release|Win32.Build.0 = Release|Win32 {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3}.Debug|Win32.ActiveCfg = Debug|Win32 {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3}.Debug|Win32.Build.0 = Debug|Win32 {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3}.Release|Win32.ActiveCfg = Release|Win32 {4C5362CD-0BF2-4B3B-971B-8293EB1A1DC3}.Release|Win32.Build.0 = Release|Win32 {13D176A2-B6BB-403F-A816-AA1F388078B7}.Debug|Win32.ActiveCfg = Debug|Win32 {13D176A2-B6BB-403F-A816-AA1F388078B7}.Debug|Win32.Build.0 = Debug|Win32 {13D176A2-B6BB-403F-A816-AA1F388078B7}.Release|Win32.ActiveCfg = Release|Win32 {13D176A2-B6BB-403F-A816-AA1F388078B7}.Release|Win32.Build.0 = Release|Win32 {CB7A02E8-393A-481B-BD18-E7D041D8C6B1}.Debug|Win32.ActiveCfg = Debug|Win32 {CB7A02E8-393A-481B-BD18-E7D041D8C6B1}.Debug|Win32.Build.0 = Debug|Win32 {CB7A02E8-393A-481B-BD18-E7D041D8C6B1}.Release|Win32.ActiveCfg = Release|Win32 {CB7A02E8-393A-481B-BD18-E7D041D8C6B1}.Release|Win32.Build.0 = Release|Win32 {76CBB7D4-0524-4569-9150-34BDE4235D04}.Debug|Win32.ActiveCfg = Debug|Win32 {76CBB7D4-0524-4569-9150-34BDE4235D04}.Debug|Win32.Build.0 = Debug|Win32 {76CBB7D4-0524-4569-9150-34BDE4235D04}.Release|Win32.ActiveCfg = Release|Win32 {76CBB7D4-0524-4569-9150-34BDE4235D04}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal musepack_src_r495/win32/libgen.h0000664000000000000000000000104410721572026015374 0ustar rootroot#ifndef _LIBGEN_H_ /* * libgen.h * * $Id: libgen.h,v 1.2 2007/06/23 07:34:15 dannysmith Exp $ * * This file has no copyright assigned and is placed in the Public Domain. * This file is a part of the mingw-runtime package. * No warranty is given; refer to the file DISCLAIMER within the package. * * Functions for splitting pathnames into dirname and basename components. * */ #define _LIBGEN_H_ #ifdef __cplusplus extern "C" { #endif extern char *basename (char *); #ifdef __cplusplus } #endif #endif /* _LIBGEN_H_: end of file */ musepack_src_r495/win32/basename.c0000664000000000000000000001145410721572026015710 0ustar rootroot/* basename.c * * $Id: basename.c,v 1.2 2007/03/08 23:15:58 keithmarshall Exp $ * * Provides an implementation of the "basename" function, conforming * to SUSv3, with extensions to accommodate Win32 drive designators, * and suitable for use on native Microsoft(R) Win32 platforms. * * Written by Keith Marshall * * This is free software. You may redistribute and/or modify it as you * see fit, without restriction of copyright. * * This software is provided "as is", in the hope that it may be useful, * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no * time will the author accept any form of liability for any damages, * however caused, resulting from the use of this software. * */ #include #include #include #include #include #ifndef __cdecl /* If compiling on any non-Win32 platform ... */ #define __cdecl /* this may not be defined. */ #endif __cdecl char *basename( char *path ) { size_t len; static char *retfail = NULL; /* to handle path names for files in multibyte character locales, * we need to set up LC_CTYPE to match the host file system locale */ char *locale = setlocale( LC_CTYPE, NULL ); if( locale != NULL ) locale = strdup( locale ); setlocale( LC_CTYPE, "" ); if( path && *path ) { /* allocate sufficient local storage space, * in which to create a wide character reference copy of path */ wchar_t * refcopy, * refpath; len = mbstowcs( NULL, path, 0 ); refcopy = malloc((1 + len) * sizeof(wchar_t)); /* create the wide character reference copy of path, * and step over the drive designator, if present ... */ refpath = refcopy; if( ((len = mbstowcs( refpath, path, len )) > 1) && (refpath[1] == L':') ) { /* FIXME: maybe should confirm *refpath is a valid drive designator */ refpath += 2; } /* ensure that our wide character reference path is NUL terminated */ refcopy[ len ] = L'\0'; /* check again, just to ensure we still have a non-empty path name ... */ if( *refpath ) { /* and, when we do, process it in the wide character domain ... * scanning from left to right, to the char after the final dir separator */ wchar_t *refname; for( refname = refpath ; *refpath ; ++refpath ) { if( (*refpath == L'/') || (*refpath == L'\\') ) { /* we found a dir separator ... * step over it, and any others which immediately follow it */ while( (*refpath == L'/') || (*refpath == L'\\') ) ++refpath; /* if we didn't reach the end of the path string ... */ if( *refpath ) /* then we have a new candidate for the base name */ refname = refpath; /* otherwise ... * strip off any trailing dir separators which we found */ else while( (refpath > refname) && ((*--refpath == L'/') || (*refpath == L'\\')) ) *refpath = L'\0'; } } /* in the wide character domain ... * refname now points at the resolved base name ... */ if( *refname ) { /* if it's not empty, * then we transform the full normalised path back into * the multibyte character domain, and skip over the dirname, * to return the resolved basename. */ if( (len = wcstombs( path, refcopy, len )) != (size_t)(-1) ) path[ len ] = '\0'; *refname = L'\0'; if( (len = wcstombs( NULL, refcopy, 0 )) != (size_t)(-1) ) path += len; } else { /* the basename is empty, so return the default value of "/", * transforming from wide char to multibyte char domain, and * returning it in our own buffer. */ retfail = realloc( retfail, len = 1 + wcstombs( NULL, L"/", 0 )); wcstombs( path = retfail, L"/", len ); } /* restore the caller's locale, clean up, and return the result */ setlocale( LC_CTYPE, locale ); free( locale ); return( path ); } free(refcopy); /* or we had an empty residual path name, after the drive designator, * in which case we simply fall through ... */ } /* and, if we get to here ... * the path name is either NULL, or it decomposes to an empty string; * in either case, we return the default value of "." in our own buffer, * reloading it with the correct value, transformed from the wide char * to the multibyte char domain, just in case the caller trashed it * after a previous call. */ retfail = realloc( retfail, len = 1 + wcstombs( NULL, L".", 0 )); wcstombs( retfail, L".", len ); /* restore the caller's locale, clean up, and return the result */ setlocale( LC_CTYPE, locale ); free( locale ); return( retfail ); } /* $RCSfile: basename.c,v $$Revision: 1.2 $: end of file */ musepack_src_r495/win32/getopt.h0000664000000000000000000000053510620613712015436 0ustar rootroot/** * @file getopt.h * @ingroup wbxml2xml_tool * @ingroup xml2wbxml_tool * * @author Kannel Team (http://www.kannel.org/) * * @brief getopt() implementation */ #ifndef WBXML_GETOPT_H #define WBXML_GETOPT_H int getopt(int argc, char **argv, char *opts); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif musepack_src_r495/win32/libwavformat.vcproj0000664000000000000000000000664011144566617017725 0ustar rootroot musepack_src_r495/win32/libmpcdec_2005.vcproj0000664000000000000000000001164111154722375017611 0ustar rootroot musepack_src_r495/win32/libmpcenc.vcproj0000664000000000000000000000764411144566617017171 0ustar rootroot musepack_src_r495/win32/dirent.c0000664000000000000000000002101510721572026015414 0ustar rootroot/* ///////////////////////////////////////////////////////////////////////////// * File: dirent.c * * Purpose: Definition of the opendir() API functions for the Win32 platform. * * Created: 19th October 2002 * Updated: 12th September 2006 * * Home: http://synesis.com.au/software/ * * Copyright (c) 2002-2006, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the names of Matthew Wilson and Synesis Software nor the names of * any contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////////// */ #ifndef UNIXEM_DOCUMENTATION_SKIP_SECTION # define _SYNSOFT_VER_C_DIRENT_MAJOR 2 # define _SYNSOFT_VER_C_DIRENT_MINOR 2 # define _SYNSOFT_VER_C_DIRENT_REVISION 5 # define _SYNSOFT_VER_C_DIRENT_EDIT 32 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ /* ///////////////////////////////////////////////////////////////////////////// * Includes */ #include #include #include #include /* ///////////////////////////////////////////////////////////////////////////// * Compiler differences */ #if defined(__BORLANDC__) # define UNIXEM_opendir_PROVIDED_BY_COMPILER #elif defined(__DMC__) # define UNIXEM_opendir_PROVIDED_BY_COMPILER #elif defined(__GNUC__) # define UNIXEM_opendir_PROVIDED_BY_COMPILER #elif defined(__INTEL_COMPILER) #elif defined(_MSC_VER) #elif defined(__MWERKS__) #elif defined(__WATCOMC__) #else # error Compiler not discriminated #endif /* compiler */ #if defined(UNIXEM_opendir_PROVIDED_BY_COMPILER) && \ !defined(UNIXEM_FORCE_ANY_COMPILER) # error The opendir() API is provided by this compiler, so should not be built here #endif /* !UNIXEM_opendir_PROVIDED_BY_COMPILER */ /* ///////////////////////////////////////////////////////////////////////////// * Constants and definitions */ #ifndef FILE_ATTRIBUTE_ERROR # define FILE_ATTRIBUTE_ERROR (0xFFFFFFFF) #endif /* FILE_ATTRIBUTE_ERROR */ /* ///////////////////////////////////////////////////////////////////////////// * Typedefs */ struct dirent_dir { char directory[_MAX_DIR + 1]; /* . */ WIN32_FIND_DATAA find_data; /* The Win32 FindFile data. */ HANDLE hFind; /* The Win32 FindFile handle. */ struct dirent dirent; /* The handle's entry. */ }; struct wdirent_dir { wchar_t directory[_MAX_DIR + 1]; /* . */ WIN32_FIND_DATAW find_data; /* The Win32 FindFile data. */ HANDLE hFind; /* The Win32 FindFile handle. */ struct wdirent dirent; /* The handle's entry. */ }; /* ///////////////////////////////////////////////////////////////////////////// * Helper functions */ static HANDLE unixem__dirent__findfile_directory(char const *name, LPWIN32_FIND_DATAA data) { char search_spec[_MAX_PATH +1]; /* Simply add the *.*, ensuring the path separator is * included. */ (void)lstrcpyA(search_spec, name); if( '\\' != search_spec[lstrlenA(search_spec) - 1] && '/' != search_spec[lstrlenA(search_spec) - 1]) { (void)lstrcatA(search_spec, "\\*.*"); } else { (void)lstrcatA(search_spec, "*.*"); } return FindFirstFileA(search_spec, data); } #if 0 static HANDLE unixem__dirent__wfindfile_directory(wchar_t const *name, LPWIN32_FIND_DATAW data) { wchar_t search_spec[_MAX_PATH +1]; /* Simply add the *.*, ensuring the path separator is * included. */ lstrcpyW(search_spec, name); if( L'\\' != search_spec[lstrlenW(search_spec) - 1] && L'/' != search_spec[lstrlenW(search_spec) - 1]) { lstrcatW(search_spec, L"\\*.*"); } else { lstrcatW(search_spec, L"*.*"); } return FindFirstFileW(search_spec, data); } #endif /* 0 */ /* ///////////////////////////////////////////////////////////////////////////// * API functions */ DIR *opendir(char const *name) { DIR *result = NULL; DWORD dwAttr; /* Must be a valid name */ if( !name || !*name || (dwAttr = GetFileAttributes(name)) == 0xFFFFFFFF) { errno = ENOENT; } /* Must be a directory */ else if(!(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) { errno = ENOTDIR; } else { result = (DIR*)malloc(sizeof(DIR)); if(result == NULL) { errno = ENOMEM; } else { result->hFind = unixem__dirent__findfile_directory(name, &result->find_data); if(result->hFind == INVALID_HANDLE_VALUE) { free(result); result = NULL; } else { /* Save the directory, in case of rewind. */ (void)lstrcpyA(result->directory, name); (void)lstrcpyA(result->dirent.d_name, result->find_data.cFileName); result->dirent.d_mode = (int)result->find_data.dwFileAttributes; } } } #if 0 if(NULL != dir) { struct dirent *readdir(DIR *dir) } #endif /* 0 */ return result; } int closedir(DIR *dir) { int ret; if(dir == NULL) { errno = EBADF; ret = -1; } else { /* Close the search handle, if not already done. */ if(dir->hFind != INVALID_HANDLE_VALUE) { (void)FindClose(dir->hFind); } free(dir); ret = 0; } return ret; } void rewinddir(DIR *dir) { /* Close the search handle, if not already done. */ if(dir->hFind != INVALID_HANDLE_VALUE) { (void)FindClose(dir->hFind); } dir->hFind = unixem__dirent__findfile_directory(dir->directory, &dir->find_data); if(dir->hFind != INVALID_HANDLE_VALUE) { (void)lstrcpyA(dir->dirent.d_name, dir->find_data.cFileName); } } struct dirent *readdir(DIR *dir) { /* The last find exhausted the matches, so return NULL. */ if(dir->hFind == INVALID_HANDLE_VALUE) { if(FILE_ATTRIBUTE_ERROR == dir->find_data.dwFileAttributes) { errno = EBADF; } else { dir->find_data.dwFileAttributes = FILE_ATTRIBUTE_ERROR; } return NULL; } else { /* Copy the result of the last successful match to * dirent. */ (void)lstrcpyA(dir->dirent.d_name, dir->find_data.cFileName); /* Attempt the next match. */ if(!FindNextFileA(dir->hFind, &dir->find_data)) { /* Exhausted all matches, so close and null the * handle. */ (void)FindClose(dir->hFind); dir->hFind = INVALID_HANDLE_VALUE; } return &dir->dirent; } } /* ////////////////////////////////////////////////////////////////////////// */ musepack_src_r495/win32/mpcgain.vcproj0000664000000000000000000001025211164376513016634 0ustar rootroot musepack_src_r495/win32/attgetopt.c0000664000000000000000000000305710620613712016144 0ustar rootroot/** * @file attgetopt.c * @ingroup wbxml2xml_tool * @ingroup xml2wbxml_tool * * AT&T's public domain implementation of getopt. * * From the mod.sources newsgroup, volume 3, issue 58, with modifications * to bring it up to 21st century C. * * Taken from Kannel Project (http://www.kannel.org/) */ #include #include #define ERR(s, c) if (opterr) (void) fprintf(stderr, "%s: %s\n", argv[0], s) int opterr = 1; int optind = 1; int optopt; char *optarg; int getopt(int argc, char **argv, char *opts) { static int sp = 1; register int c; register char *cp; if(sp == 1) { if(optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(EOF); else if(strcmp(argv[optind], "--") == 0) { optind++; return(EOF); } } optopt = c = argv[optind][sp]; if(c == ':' || (cp=strchr(opts, c)) == NULL) { ERR(": illegal option -- ", c); if(argv[optind][++sp] == '\0') { optind++; sp = 1; } return('?'); } if(*++cp == ':') { if(argv[optind][sp+1] != '\0') optarg = &argv[optind++][sp+1]; else if(++optind >= argc) { ERR(": option requires an argument -- ", c); sp = 1; return('?'); } else optarg = argv[optind++]; sp = 1; } else { if(argv[optind][++sp] == '\0') { sp = 1; optind++; } optarg = NULL; } return(c); } musepack_src_r495/win32/mpc2sv8.vcproj0000664000000000000000000001024311144566617016524 0ustar rootroot musepack_src_r495/mpcgain/0000775000000000000000000000000012765302354014445 5ustar rootrootmusepack_src_r495/mpcgain/mpcgain.c0000664000000000000000000002174712644540266016244 0ustar rootroot/* Copyright (c) 2006-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the The Musepack Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "../libmpcdec/internal.h" #include "../libmpcdec/huffman.h" #include "../libmpcdec/mpc_bits_reader.h" #define MPCGAIN_MAJOR 0 #define MPCGAIN_MINOR 9 #define MPCGAIN_BUILD 3 #define _cat(a,b,c) #a"."#b"."#c #define cat(a,b,c) _cat(a,b,c) #define MPCGAIN_VERSION cat(MPCGAIN_MAJOR,MPCGAIN_MINOR,MPCGAIN_BUILD) #define MAX_HEAD_SIZE 20 // maximum size of the packet header before chapter gain (2 + 9 + 9) const char About [] = "mpcgain - Musepack (MPC) ReplayGain calculator v" MPCGAIN_VERSION " (C) 2006-2009 MDT\nBuilt " __DATE__ " " __TIME__ "\n"; static void usage(const char *exename) { printf("Usage: %s [ ... ]\n", exename); } static mpc_inline MPC_SAMPLE_FORMAT _max(MPC_SAMPLE_FORMAT a, MPC_SAMPLE_FORMAT b) { if (a > b) return a; return b; } static mpc_inline MPC_SAMPLE_FORMAT max_abs(MPC_SAMPLE_FORMAT a, MPC_SAMPLE_FORMAT b) { if (b < 0) b = -b; if (b > a) return b; return a; } static MPC_SAMPLE_FORMAT analyze_get_max(MPC_SAMPLE_FORMAT * sample_buffer, int sample_nb) { Float_t left_samples[MPC_FRAME_LENGTH * sizeof(Float_t)]; Float_t right_samples[MPC_FRAME_LENGTH * sizeof(Float_t)]; MPC_SAMPLE_FORMAT max = 0; int i; for (i = 0; i < sample_nb; i++){ left_samples[i] = sample_buffer[2 * i] * (1 << 15); right_samples[i] = sample_buffer[2 * i + 1] * (1 << 15); max = max_abs(max, sample_buffer[2 * i]); max = max_abs(max, sample_buffer[2 * i + 1]); } gain_analyze_samples(left_samples, right_samples, sample_nb, 2); return max; } static void write_chaps_gain(mpc_demux * demux, const char * file_name, mpc_uint16_t * chap_gain, mpc_uint16_t * chap_peak) { unsigned char buffer[MAX_HEAD_SIZE]; mpc_bits_reader r; mpc_block b; mpc_uint64_t size, dummy; FILE * file; int chap = 0; long next_chap_pos = demux->chap_pos >> 3; file = fopen( file_name, "r+b"); if (file == 0) { fprintf(stderr, "Can't open file \"%s\" for writing\n", file_name); return; } while (1) { fseek(file, next_chap_pos, SEEK_SET); if (0 == fread(buffer, 1, MAX_HEAD_SIZE, file)) break; r.buff = buffer; r.count = 8; size = mpc_bits_get_block(&r, &b); if (memcmp(b.key, "CT", 2) != 0) break; b.size += size; size += mpc_bits_get_size(&r, &dummy); fseek(file, next_chap_pos + size, SEEK_SET); buffer[0] = chap_gain[chap] >> 8; buffer[1] = chap_gain[chap] & 0xFF; buffer[2] = chap_peak[chap] >> 8; buffer[3] = chap_peak[chap] & 0xFF; fwrite(buffer, 1, 4, file); // writing chapter gain / peak chap++; next_chap_pos += b.size; } fclose(file); } int main(int argc, char **argv) { MPC_SAMPLE_FORMAT album_max = 0; mpc_uint16_t album_gain; mpc_uint16_t album_peak; mpc_uint16_t * title_gain; mpc_uint16_t * title_peak; mpc_uint32_t * header_pos; int j; printf(About); if (argc < 2) { usage(argv[0]); return 0; } title_gain = malloc((sizeof(mpc_uint16_t) * 2 + sizeof(mpc_uint32_t)) * (argc - 1)); title_peak = title_gain + (argc - 1); header_pos = (mpc_uint32_t *) (title_peak + (argc - 1)); for (j = 1; j < argc; j++) { MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; MPC_SAMPLE_FORMAT title_max = 0, chap_max = 0; mpc_uint16_t * chap_gain = 0, * chap_peak = 0; mpc_reader reader; mpc_demux* demux; mpc_streaminfo si; mpc_status err; int chap_nb, chap = 0; mpc_uint64_t cur_sample = 1, next_chap_sample = mpc_int64_max; err = mpc_reader_init_stdio(&reader, argv[j]); if (err < 0) return !MPC_STATUS_OK; demux = mpc_demux_init(&reader); if (!demux) return !MPC_STATUS_OK; mpc_demux_get_info(demux, &si); chap_nb = mpc_demux_chap_nb(demux); mpc_demux_seek_sample(demux, 0); if (chap_nb > 0) { const mpc_chap_info * chap_info = mpc_demux_chap(demux, chap); next_chap_sample = chap_info->sample; chap_gain = malloc(sizeof(mpc_uint16_t) * 2 * chap_nb); chap_peak = chap_gain + chap_nb; } if (j == 1) gain_init_analysis ( si.sample_freq ); while (1) { mpc_frame_info frame; int i = 0; frame.buffer = sample_buffer; mpc_demux_decode(demux, &frame); if (frame.bits == -1) break; while (next_chap_sample < cur_sample + frame.samples) { int sample_nb = (int)(next_chap_sample - cur_sample); chap_max = _max(chap_max, analyze_get_max(sample_buffer + 2 * i, sample_nb)); if (chap == 0) // first samples are not in a chapter gain_get_chapter(); else { chap_gain[chap - 1] = (mpc_uint16_t) (gain_get_chapter() * 256); chap_peak[chap - 1] = (mpc_uint16_t) (log10(chap_max * (1 << 15)) * 20 * 256); } chap++; title_max = _max(title_max, chap_max); chap_max = 0; i += sample_nb; cur_sample = next_chap_sample; if (chap < chap_nb) { const mpc_chap_info * chap_info = mpc_demux_chap(demux, chap); next_chap_sample = chap_info->sample; } else next_chap_sample = mpc_int64_max; } chap_max = _max(chap_max, analyze_get_max(sample_buffer + 2 * i, frame.samples - i)); cur_sample += frame.samples - i; } if (chap_nb > 0) { chap_gain[chap - 1] = (mpc_uint16_t) (gain_get_chapter() * 256); chap_peak[chap - 1] = (mpc_uint16_t) (log10(chap_max * (1 << 15)) * 20 * 256); write_chaps_gain(demux, argv[j], chap_gain, chap_peak); } title_max = _max(title_max, chap_max); album_max = _max(album_max, title_max); title_gain[j-1] = (mpc_uint16_t) (gain_get_title() * 256); title_peak[j-1] = (mpc_uint16_t) (log10(title_max * (1 << 15)) * 20 * 256); header_pos[j-1] = si.header_position + 4; mpc_demux_exit(demux); mpc_reader_exit_stdio(&reader); if (chap_nb > 0) free(chap_gain); } album_gain = (mpc_uint16_t) (gain_get_album() * 256); album_peak = (mpc_uint16_t) (log10(album_max * (1 << 15)) * 20 * 256); for (j = 0; j < argc - 1; j++) { unsigned char buffer[64]; mpc_bits_reader r; mpc_block b; mpc_uint64_t size; FILE * file; file = fopen( argv[j + 1], "r+b"); if (file == 0) { fprintf(stderr, "Can't open file \"%s\" for writing\n", argv[j + 1]); continue; } fseek(file, header_pos[j] - 4, SEEK_SET); if (fread(buffer, 1, 16, file) != 16 || memcmp(buffer, "MPCK", 4) != 0) { fprintf(stderr, "Unsupported file format, not a sv8 file : %s\n", argv[j + 1]); fclose(file); continue; } r.buff = buffer + 4; r.count = 8; for(;;) { size = mpc_bits_get_block(&r, &b); if (mpc_check_key(b.key) != MPC_STATUS_OK) break; if (memcmp(b.key, "RG", 2) == 0) break; header_pos[j] += b.size + size; fseek(file, header_pos[j], SEEK_SET); if (0 == fread(buffer, 1, 16, file)) break; r.buff = buffer; r.count = 8; } if (memcmp(b.key, "RG", 2) != 0 || b.size < 9) { //check for the loop above having aborted without finding the packet we want to update fprintf(stderr, "Unsupported file format or corrupted file : %s\n", argv[j + 1]); fclose(file); continue; } header_pos[j] += size; buffer[size] = 1; // replaygain version buffer[size + 1] = title_gain[j] >> 8; buffer[size + 2] = title_gain[j] & 0xFF; buffer[size + 3] = title_peak[j] >> 8; buffer[size + 4] = title_peak[j] & 0xFF; buffer[size + 5] = album_gain >> 8; buffer[size + 6] = album_gain & 0xFF; buffer[size + 7] = album_peak >> 8; buffer[size + 8] = album_peak & 0xFF; fseek(file, header_pos[j], SEEK_SET); fwrite(buffer + size, 1, b.size, file); fclose(file); } free(title_gain); return 0; } musepack_src_r495/mpcgain/Makefile.am0000664000000000000000000000045411234134160016470 0ustar rootrootEXTRA_DIST = CMakeLists.txt AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = -ffast-math if HAVE_VISIBILITY AM_CFLAGS += -fvisibility=hidden endif METASOURCES = AUTO bin_PROGRAMS = mpcgain mpcgain_LDADD = -lm -lreplaygain \ $(top_builddir)/libmpcdec/libmpcdec.la mpcgain_SOURCES = mpcgain.c musepack_src_r495/mpcgain/CMakeLists.txt0000664000000000000000000000141411433773325017206 0ustar rootrootFIND_PATH(REPLAY_GAIN_INCLUDE_DIR replaygain/gain_analysis.h /usr/include /usr/local/include ${libmpc_SOURCE_DIR}/../libreplaygain/include ) FIND_LIBRARY(REPLAY_GAIN_LIBRARY NAMES replaygain replaygain_static PATHS /usr/lib /usr/local/lib ${libmpc_SOURCE_DIR}/../libreplaygain/bin/src/release ) include_directories(${libmpc_SOURCE_DIR}/include) include_directories(${REPLAY_GAIN_INCLUDE_DIR}) link_directories(${libmpc_BINARY_DIR}/libmpcdec) add_executable(mpcgain mpcgain.c) target_link_libraries(mpcgain ${REPLAY_GAIN_LIBRARY}) if(SHARED) target_link_libraries(mpcgain mpcdec) else(SHARED) target_link_libraries(mpcgain mpcdec_static) endif(SHARED) if(NOT MSVC) target_link_libraries(mpcgain m) endif(NOT MSVC) install(TARGETS mpcgain RUNTIME DESTINATION bin) musepack_src_r495/common/0000775000000000000000000000000012765302354014317 5ustar rootrootmusepack_src_r495/common/tags.c0000664000000000000000000021170711103162206015412 0ustar rootroot/* * Encoder tag handling * * (C) Frank Klemm 2002. Janne Hyv�inen 2002. All rights reserved. * * Principles: * * * History: * 2002-06 created * 2002-08-12 added translation method 5 to addtag() * Tags taken from source file can't overwrite already existing items * added Init_Tags() * 2002-08-13 Added all windows code pages * 2002-10-09 Added code to parse tags from filename * * Global functions: * - addtag() * * TODO: * - '/' and '\' should be possible as PATH_SEP */ // #include "mpcenc.h" #include #include #ifdef _WIN32 # include #endif #ifdef _MSC_VER # define strncasecmp strnicmp #endif // Path separator #if defined __unix__ || defined __bsdi__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __APPLE__ # define PATH_SEP '/' # define DRIVE_SEP '\0' #elif defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER # define PATH_SEP '\\' # define DRIVE_SEP ':' #else # define PATH_SEP '/' // Amiga: C:/ # define DRIVE_SEP ':' #endif #ifdef USE_WIDECHAR # include #endif static const char* GenreList [] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror", "Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "SynthPop" }; struct APETagFooterStruct { mpc_uint8_t ID [8]; // should equal 'APETAGEX' mpc_uint8_t Version [4]; // currently 1000 (version 1.000) mpc_uint8_t Length [4]; // the complete size of the tag, including this footer mpc_uint8_t TagCount [4]; // the number of fields in the tag mpc_uint8_t Flags [4]; // the tag flags (none currently defined) mpc_uint8_t Reserved [8]; // reserved for later use }; typedef struct { char* key; size_t keylen; unsigned char* value; size_t valuelen; unsigned int flags; } TagItem_t; static TagItem_t T [256]; // up to 256 items, otherwise program crashs static unsigned int TagCount = 0; #if defined __TURBOC__ static unsigned short CP_850 [256] = { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0, }; #elif defined _WIN32 static unsigned short CP_37 [256] = { // ??? 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A, 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC, 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1, 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4, 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE, 0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, 0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7, 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5, 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF, 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F, }; static unsigned short CP_42 [256] = { // CP_SYMBOLS 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0xF020, 0xF021, 0xF022, 0xF023, 0xF024, 0xF025, 0xF026, 0xF027, 0xF028, 0xF029, 0xF02A, 0xF02B, 0xF02C, 0xF02D, 0xF02E, 0xF02F, 0xF030, 0xF031, 0xF032, 0xF033, 0xF034, 0xF035, 0xF036, 0xF037, 0xF038, 0xF039, 0xF03A, 0xF03B, 0xF03C, 0xF03D, 0xF03E, 0xF03F, 0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF045, 0xF046, 0xF047, 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D, 0xF04E, 0xF04F, 0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055, 0xF056, 0xF057, 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D, 0xF05E, 0xF05F, 0xF060, 0xF061, 0xF062, 0xF063, 0xF064, 0xF065, 0xF066, 0xF067, 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C, 0xF06D, 0xF06E, 0xF06F, 0xF070, 0xF071, 0xF072, 0xF073, 0xF074, 0xF075, 0xF076, 0xF077, 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C, 0xF07D, 0xF07E, 0xF07F, 0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085, 0xF086, 0xF087, 0xF088, 0xF089, 0xF08A, 0xF08B, 0xF08C, 0xF08D, 0xF08E, 0xF08F, 0xF090, 0xF091, 0xF092, 0xF093, 0xF094, 0xF095, 0xF096, 0xF097, 0xF098, 0xF099, 0xF09A, 0xF09B, 0xF09C, 0xF09D, 0xF09E, 0xF09F, 0xF0A0, 0xF0A1, 0xF0A2, 0xF0A3, 0xF0A4, 0xF0A5, 0xF0A6, 0xF0A7, 0xF0A8, 0xF0A9, 0xF0AA, 0xF0AB, 0xF0AC, 0xF0AD, 0xF0AE, 0xF0AF, 0xF0B0, 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xF0B6, 0xF0B7, 0xF0B8, 0xF0B9, 0xF0BA, 0xF0BB, 0xF0BC, 0xF0BD, 0xF0BE, 0xF0BF, 0xF0C0, 0xF0C1, 0xF0C2, 0xF0C3, 0xF0C4, 0xF0C5, 0xF0C6, 0xF0C7, 0xF0C8, 0xF0C9, 0xF0CA, 0xF0CB, 0xF0CC, 0xF0CD, 0xF0CE, 0xF0CF, 0xF0D0, 0xF0D1, 0xF0D2, 0xF0D3, 0xF0D4, 0xF0D5, 0xF0D6, 0xF0D7, 0xF0D8, 0xF0D9, 0xF0DA, 0xF0DB, 0xF0DC, 0xF0DD, 0xF0DE, 0xF0DF, 0xF0E0, 0xF0E1, 0xF0E2, 0xF0E3, 0xF0E4, 0xF0E5, 0xF0E6, 0xF0E7, 0xF0E8, 0xF0E9, 0xF0EA, 0xF0EB, 0xF0EC, 0xF0ED, 0xF0EE, 0xF0EF, 0xF0F0, 0xF0F1, 0xF0F2, 0xF0F3, 0xF0F4, 0xF0F5, 0xF0F6, 0xF0F7, 0xF0F8, 0xF0F9, 0xF0FA, 0xF0FB, 0xF0FC, 0xF0FD, 0xF0FE, 0xF0FF, }; static unsigned short CP_437 [256] = { // MS-DOS: US 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_500 [256] = { // ??? 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A, 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, 0x00E7, 0x00F1, 0x005B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021, 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, 0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E, 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1, 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4, 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE, 0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, 0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7, 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5, 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF, 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F, }; static unsigned short CP_850 [256] = { // MS-DOS Latin 1 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_860 [256] = { // MS-DOS: Portuguese 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_861 [256] = { // MS-DOS: Iceland 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_863 [256] = { // MS-DOS: Canadian French 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x2017, 0x00C0, 0x00A7, 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00B8, 0x00B3, 0x00AF, 0x00CE, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_865 [256] = { // MS-DOS: Nordic 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, }; static unsigned short CP_874 [256] = { // MS-DOS: Thai 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x0082, 0x0083, 0x0084, 0x2026, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0xF8C1, 0xF8C2, 0xF8C3, 0xF8C4, 0x0E3F, 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xF8C5, 0xF8C6, 0xF8C7, 0xF8C8, }; static unsigned short CP_1250 [256] = { // Windows: Latin 2 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0083, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, }; static unsigned short CP_1251 [256] = { // Windows: Cyrillic 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, }; static unsigned short CP_1252 [256] = { // Windows: Latin 1 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, }; static unsigned short CP_1253 [256] = { // Windows: Greek 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x008A, 0x2039, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x009A, 0x203A, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0xF8F9, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0xF8FA, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xF8FB, }; static unsigned short CP_1254 [256] = { // Windows: Latin 5 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x008E, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x009E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF, }; static unsigned short CP_1255 [256] = { // Windows: Hebrew 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x008A, 0x2039, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x009A, 0x203A, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0xF88D, 0xF88E, 0xF88F, 0xF890, 0xF891, 0xF892, 0xF893, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0xF894, 0xF895, 0x200E, 0x200F, 0xF896, }; static unsigned short CP_1256 [256] = { // Windows: Arabic 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2, }; static unsigned short CP_1257 [256] = { // Windows: Baltic 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0083, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x008A, 0x2039, 0x008C, 0x00A8, 0x02C7, 0x00B8, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x009A, 0x203A, 0x009C, 0x00AF, 0x02DB, 0x009F, 0x00A0, 0xF8FC, 0x00A2, 0x00A3, 0x00A4, 0xF8FD, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9, }; static unsigned short CP_1258 [256] = { // Windows: Vietnam 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x008A, 0x2039, 0x0152, 0x008D, 0x008E, 0x008F, 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x009A, 0x203A, 0x0153, 0x009D, 0x009E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF, }; static unsigned short CP_10000 [256] = { // Apple Macintosh 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7, }; static unsigned short CP_10079 [256] = { // ??? 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 0x00DD, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x00A4, 0x00D0, 0x00F0, 0x00DE, 0x00FE, 0x00FD, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7, }; #endif /* * Resets Item Counter * Do frees any memory. */ void Init_Tags ( void ) { int i; for ( i = 0; i < (int)TagCount; i++ ) { if ( T[i].key != NULL ) free ( T[i].key ); T[i].key = NULL; if ( T[i].value != NULL ) free ( T[i].value ); T[i].value = NULL; } TagCount = 0; } int gettag ( const char* key, char* dst, size_t len ) { size_t valuelen; size_t keylen = strlen (key); int i; for ( i = 0; i < (int)TagCount; i++ ) if ( keylen == T[i].keylen && 0 == memcmp (T[i].key, key, keylen) ) { valuelen = len-1 > T[i].valuelen ? T[i].valuelen : len-1 ; memcpy ( dst, T[i].value, valuelen ); dst [valuelen] = '\0'; return 0; } memset ( dst, 0, len ); return -1; } static unsigned char* utf8char ( unsigned char* dst, unsigned long value ) { if ( value == '\r' || value == 0xFFFE || value == 0xFFFF ) { ; } else if ( value < 0x80 ) { *dst++ = value; } else if ( value < 0x800 ) { *dst++ = 0xC0 + ((value >> 6) & 0x1F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x10000 ) { *dst++ = 0xE0 + ((value >> 12) & 0x0F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x200000 ) { *dst++ = 0xF0 + ((value >> 18) & 0x07); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x4000000 ) { *dst++ = 0xF8 + ((value >> 24) & 0x03); *dst++ = 0x80 + ((value >> 18) & 0x3F); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } else if ( value < 0x80000000 ) { *dst++ = 0xFC + ((value >> 30) & 0x01); *dst++ = 0x80 + ((value >> 24) & 0x3F); *dst++ = 0x80 + ((value >> 18) & 0x3F); *dst++ = 0x80 + ((value >> 12) & 0x3F); *dst++ = 0x80 + ((value >> 6) & 0x3F); *dst++ = 0x80 + ((value >> 0) & 0x3F); } return dst; } /* * IsUnicode() * * Gets a memory block and tries to find out whether this is binary data or a valid Windows Unicode file. * When return 1, it is very likely (but not 100% secure) that the content is Unicode encoded. */ static int IsUnicode ( const char* src, size_t len ) { if ( len <= 2 ) return 0; if ( len & 1 ) // odd number of bytes? return 0; if ( src [0] != (char)0xFF || src [1] != (char)0xFE ) // Microsoft Unicode preample (also useful to detect endianess, but currently only little endian is supported) return 0; for ( len >>= 1; len > 0; len--, src += 2 ) { // Check for invalid codes (FFFE, FFFF, DC00...DFFF without a prepend D800...DBFF, D800...DBFF without a n appended DC00...DFFF) if ( ( src [1] & 0xFC ) == 0xDC ) return 0; if ( src [1] == (char)0xFF && ( src [0] & 0xFE ) == 0xFE ) return 0; if ( ( src [1] & 0xFC ) == 0xD8 ) { if ( len < 2 || ( src [3] & 0xFC ) != 0xDC ) return 0; } else { len--; src += 2; } } return 1; // good chance to be a UTF-8 } /* * addtag() * * Add a item to the item list of a tag. Item key is given by (key,keylen), item value by (value,valuelen). * * The following value translation modes are possible: * 0: no translation at all * 1: translate from console charset to UTF-8 (currently ISO-8859-1 for non-Windows and non-DOS OS) * 2: auto detect: contents is a valid Window Unicode File => translate to UTF-8, else no translation at all * 3: like 1), but convert ';' to null character * 4: UTF-16 LE => translate to UTF-8 * 5: translate from ISO-8859-1 to UTF-8 * 6: like 1), but convert from OEM codepage (Win32) * (should become an enum) * * Note: * Windows 95/98/ME has no usable NLS support * */ int addtag ( const char* key, // the item key size_t keylen, // length of item key, or 0 for auto-determine const char* value, // the item value size_t valuelen, // the length of the item value (before any possible translation) int converttoutf8, // convert flags of item value int flags ) // item flags proposal { unsigned char* p; unsigned char* q; char ch; size_t i; #ifdef _WIN32 const unsigned short* CP_ptr; unsigned int Codepage; if ( converttoutf8 == 6 ) { Codepage = GetOEMCP (); converttoutf8 = 1; } else { Codepage = GetACP (); } switch ( Codepage ) { case CP_ACP: CP_ptr = CP_1252; break; case CP_OEMCP: CP_ptr = CP_850; break; case CP_MACCP: CP_ptr = CP_10000; break; case CP_THREAD_ACP: CP_ptr = CP_1252; break; default: CP_ptr = CP_850; break; case 37: CP_ptr = CP_37; break; case 42: CP_ptr = CP_42; break; case 437: CP_ptr = CP_437; break; case 500: CP_ptr = CP_500; break; case 850: CP_ptr = CP_850; break; case 860: CP_ptr = CP_860; break; case 861: CP_ptr = CP_861; break; case 863: CP_ptr = CP_863; break; case 865: CP_ptr = CP_865; break; case 874: CP_ptr = CP_874; break; case 1250: CP_ptr = CP_1250; break; case 1251: CP_ptr = CP_1251; break; case 1252: CP_ptr = CP_1252; break; case 1253: CP_ptr = CP_1253; break; case 1254: CP_ptr = CP_1254; break; case 1255: CP_ptr = CP_1255; break; case 1256: CP_ptr = CP_1256; break; case 1257: CP_ptr = CP_1257; break; case 1258: CP_ptr = CP_1258; break; case 10000: CP_ptr = CP_10000; break; case 10079: CP_ptr = CP_10079; break; } #endif if ( converttoutf8 == 2 && IsUnicode ( value, valuelen ) ) { converttoutf8 = 4; value += 2; // remove first two bytes (zero width space 0xFEFF) valuelen = ( valuelen - 2) >> 1; flags &= ~2; // reset binary flag (it's now text) } if ( keylen == 0 ) keylen = strlen ( key ); p = malloc ( keylen ); memcpy ( p, key, keylen ); T [TagCount] . key = (char*) p; T [TagCount] . keylen = keylen; switch ( converttoutf8 ) { default: p = malloc ( 1 * valuelen ); // copy break; case 1: // at most 1 native character => 3 UTF bytes case 4: // at 1 wide => 3, 2 wide => 4 p = malloc ( 3 * valuelen ); break; } q = p; for ( i = 0; i < valuelen; i++ ) { ch = value [i]; switch ( converttoutf8 ) { default: // 0: no translation at all --or-- 2: auto detect: contents is a valid Window Unicode File => translate to UTF-8, else no translation at all *q++ = ch; break; case 5: // 5: translate from ISO-8859-1 to UTF-8 q = utf8char ( q, ch ); break; case 3: // 3: like 1), but convert ';' to null character if ( ch == ';' ) ch = '\0'; /* fall through */ case 1: // 1: translate from console charset to UTF-8 (currently ISO-8859-1 for non-Windows and non-DOS OS) #if defined __TURBOC__ q = utf8char ( q, CP_850 [ch] ); #elif defined _WIN32 // fprintf ( stderr, "%c %02X U+%04X\n", ch, ch, CP_ptr [ch] ); q = utf8char ( q, CP_ptr [ch] ); #elif defined USE_WIDECHAR { int ret; wchar_t wch = 0; ret = mbtowc ( &wch, value + i, valuelen - i ); if ( ret > 0 ) q = utf8char ( q, wch ), i += ret - 1; } #else q = utf8char ( q, ch ); #endif break; case 4: // 4: UTF-16 LE => translate to UTF-8 if ( (value [i+i+1] & 0xFC ) == 0xD8 && (value [i+i+3] & 0xFC ) == 0xDC ) { // UTF-16 code (2x16 bit for Unicodes 0x010000...0x10FFFF) q = utf8char ( q, ((value [i+i] + (value [i+i+1] << 8) - 0xD800) << 10) + (value [i+i+2] + (value [i+i+3] << 8) - 0xDC00) + 0x10000 ); i++; } else { q = utf8char ( q, value [i+i] + (value [i+i+1] << 8) ); } break; } } p = realloc ( p, valuelen = q-p ); for ( i = 0; i < TagCount; i++ ) if ( T [i].keylen == T [TagCount].keylen && 0 == strncasecmp (T [i].key, T [TagCount].key, T [i].keylen ) ) { // found old tag with the same name => replace free ( T [TagCount].key ); free ( T [i].value ); goto set; } i = TagCount++; set: T [i] . value = p; T [i] . valuelen = valuelen; T [i] . flags = flags; return 0; } static int mpc_cdecl cmpfn2 ( const void* p1, const void* p2 ) { const TagItem_t* q1 = (TagItem_t*) p1; const TagItem_t* q2 = (TagItem_t*) p2; return q1 -> valuelen - q2 -> valuelen; } #define TAG_NO_HEADER 1 #define TAG_NO_FOOTER 2 #define TAG_NO_PREAMBLE 4 /** * Writes collect tag items and write it to a file. * Items are destroyed, so tags can only be written once. * @param fp * @param Version * @param flags options for writing header / footer : * 1 : do not write header * 2 : do not write footer * 4 : do not write "APETAGEX" * @return */ int FinalizeTags ( FILE* fp, unsigned int Version, unsigned int flags ) { static unsigned char H [32] = "APETAGEX"; unsigned char dw [8]; unsigned long estimatedbytes = 32; // 32 byte footer + all items, these are the 32 bytes footer, the items are added later unsigned long writtenbytes = -32; // actually writtenbytes-32, which should be equal to estimatedbytes (= footer + all items) unsigned int i; if ( TagCount == 0 ) return 0; if (flags & TAG_NO_PREAMBLE) { estimatedbytes -= 8; writtenbytes += 8; } if (flags & TAG_NO_FOOTER) estimatedbytes = 0; if (flags & TAG_NO_HEADER) writtenbytes = 0; qsort ( T, TagCount, sizeof (*T), cmpfn2 ); for ( i = 0; i < TagCount; i++ ) estimatedbytes += 9 + T[i] . keylen + T[i] . valuelen; if ( estimatedbytes >= 8192 + 103 ) fprintf (stderr, "\nTag is %.1f Kbyte long. This is longer than the maximum recommended 8 KByte.\n\a", estimatedbytes/1024. ); H [ 8] = Version >> 0; H [ 9] = Version >> 8; H [10] = Version >> 16; H [11] = Version >> 24; H [12] = estimatedbytes >> 0; H [13] = estimatedbytes >> 8; H [14] = estimatedbytes >> 16; H [15] = estimatedbytes >> 24; H [16] = TagCount >> 0; H [17] = TagCount >> 8; H [18] = TagCount >> 16; H [19] = TagCount >> 24; H [23] = 0x80 | 0x20; if (!(flags & TAG_NO_HEADER)) { if (flags & TAG_NO_PREAMBLE) writtenbytes += fwrite ( H + 8, 1, 24, fp ); else writtenbytes += fwrite ( H, 1, 32, fp ); } for ( i = 0; i < TagCount; i++ ) { dw [0] = T [i] . valuelen >> 0; dw [1] = T [i] . valuelen >> 8; dw [2] = T [i] . valuelen >> 16; dw [3] = T [i] . valuelen >> 24; dw [4] = T [i] . flags >> 0; dw [5] = T [i] . flags >> 8; dw [6] = T [i] . flags >> 16; dw [7] = T [i] . flags >> 24; writtenbytes += fwrite ( dw , 1, 8 , fp ); writtenbytes += fwrite ( T[i].key , 1, T[i].keylen , fp ); writtenbytes += fwrite ( "" , 1, 1 , fp ); if ( T[i].valuelen > 0 ) writtenbytes += fwrite ( T[i].value, 1, T[i].valuelen, fp ); } H [23] = 0x80; if (!(flags & TAG_NO_FOOTER)) { if (flags & TAG_NO_PREAMBLE) writtenbytes += fwrite ( H + 8, 1, 24, fp ); else writtenbytes += fwrite ( H, 1, 32, fp ); } if ( estimatedbytes != writtenbytes ) fprintf (stderr, "\nError writing APE tag.\n" ); TagCount = 0; return 0; } static int TagKeyExists ( const char* key, size_t keylen ) { unsigned int i; if ( keylen == 0 ) keylen = strlen ( key ); for ( i = 0; i < TagCount; i++ ) if ( T [i].keylen == keylen && 0 == strncasecmp (T [i].key, key, keylen ) ) return 1; return 0; } /* * Copies src to dst. Copying is stopped at `\0' char is detected or if * len chars are copied. * Trailing blanks are removed and the string is `\0` terminated. */ static void memcpy_crop ( const char* key, char* src, size_t len, int flags ) { while ( len > 0 && ( src [len-1] == ' ' || src [len-1] == '\0' ) ) len--; if ( len > 0 ) if ( ! TagKeyExists ( key, 0 ) ) addtag ( key, 0, src, len, 1, flags ); } static int CopyTags_ID3 ( FILE* fp ) { mpc_uint8_t tmp [128]; if ( -1 == fseek ( fp, -128L, SEEK_END ) ) return -1; if ( 128 != fread(tmp, 1, 128, fp) ) return -1; if ( 0 != memcmp ( tmp, "TAG", 3 ) ) { return -1; } if ( !tmp[3] && !tmp[33] && !tmp[63] && !tmp[93] && !tmp[97] ) return -1; memcpy_crop ( "Title" , (char*)tmp + 3, 30, 0 ); memcpy_crop ( "Artist" , (char*)tmp + 33, 30, 0 ); memcpy_crop ( "Album" , (char*)tmp + 63, 30, 0 ); memcpy_crop ( "Year" , (char*)tmp + 93, 4, 0 ); memcpy_crop ( "Comment", (char*)tmp + 97, 30, 0 ); if ( tmp[127] < sizeof(GenreList)/sizeof(*GenreList) ) if ( ! TagKeyExists ( "Genre", 0 ) ) addtag ("Genre", 0, GenreList [tmp[127]], strlen (GenreList [tmp[127]]), 0, 0 ); if ( tmp[125] == 0 && tmp[126] != 0 ) if ( ! TagKeyExists ( "Track", 0 ) ) { sprintf ( (char*)tmp, "%u", tmp[126] ); addtag ("Track", 0, (char*)tmp, strlen ((char*)tmp), 0, 0 ); } return 0; } static unsigned int Read_LE_Uint32 ( const unsigned char* p ) { return ((mpc_uint32_t)p[0] << 0) | ((mpc_uint32_t)p[1] << 8) | ((mpc_uint32_t)p[2] << 16) | ((mpc_uint32_t)p[3] << 24); } static int CopyTags_APE ( FILE* fp ) { mpc_uint32_t len; mpc_uint32_t flags; mpc_uint32_t version; unsigned char buff [32768]; unsigned char key [257]; unsigned char* p; struct APETagFooterStruct T; mpc_uint32_t TagLen; mpc_uint32_t TagCount; if ( -1 == fseek ( fp, -(long)sizeof T, SEEK_END ) ) return -1; if ( sizeof(T) != fread (&T, 1, sizeof T, fp) ) return -1; if ( memcmp ( T.ID, "APETAGEX", sizeof(T.ID) ) != 0 ) return -1; version = Read_LE_Uint32 (T.Version); if ( version != 1000 && version != 2000 ) return -1; TagLen = Read_LE_Uint32 (T.Length); if ( TagLen <= sizeof T ) return -1; if ( -1 == fseek ( fp, -(long)TagLen, SEEK_END ) ) return -1; memset ( buff, 0, sizeof(buff) ); if ( TagLen - sizeof T != fread (buff, 1, TagLen - sizeof T, fp) ) return -1; TagCount = Read_LE_Uint32 (T.TagCount); for ( p = buff; TagCount--; ) { len = Read_LE_Uint32 ( p ); p += 4; flags = Read_LE_Uint32 ( p ); p += 4; strcpy ( (char*)key, (char*)p ); p += strlen ((char*)key) + 1; if ( ! TagKeyExists ( (char*)key, 0 ) ) addtag ( (char*)key, 0, (char*)p, len > 0 && p [len-1] == '\0' ? len-1 : len, version >= 2000 ? 0 : 5, flags ); p += len; } return 0; } /********************************************************************************************/ /* " " ' ' " - " '-' "." '.' "/" '/' " -- " '_' "[#0]" '0' "[#n]" [number] 'n' "#n" number 'M' "(#N)" (CD x) 'N' it should also be possible: (CD x/x), (DVD x), (DVD x/x) "#A" Artist 'A' "#C" CD/Album 'C' "#T" Title 'T' "#x" extention 'x' /#C -- [#n] #A -- #T#x | Acid Jazz/100% Acid Jazz -- [04] Leena Conquest (and Hip Hop Fingers) -- Boundaries (Radio Edit).pac /#C -- [#n] #A -- #C -- #T#x| Meditation/Jade Collection (1998) -- [10] Rhian -- Red Sun, Blue River -- The Miracle Song.mpc /#A/#C -- [#n] #T#x | Andreas Vollenweider/Eolian Minstrel -- [02] Across the Iron River.pac /#A/#C#N -- [#n] #T#x | Barbra Streisand/The Concert (CD 1) -- [01] Overture /#A -- #C -- [#n] #T#x | Friedemann/Friedemann -- Aquamarin -- [09] In the Court of the Mermaid.pac /#C/[#n] #A -- #T#x | Jazz Lyrik Prosa/[11] Eberhard Esche -- Anektode.pac /#A -- #T#x | Lais/Lais -- 06.pac /#C/(#N) -- [#n] #A -- #T#x | Tanz- und Folkfest 2001 -- Klingende Post/(CD 2) -- [09] Andy Irvine -- Gladiators.pac /#A -- #C -- [#0]#x | Friedemann/Friedemann -- Aquamarin -- [00].pac /#A/#C (#N) -- [#0]#x | Tangerine Dream/The Warsaw Concert (CD 2) -- [00].pac /#A/#T#x | Heinz-Rudolf Kunze/Dein ist mein ganzes Herz.pac /#A/#C -- [#0]#x | Sting/Nada como el Sol -- [00].mpc */ static const char* const parser_strings [] = { "/A_Tx", "/A/Tx", "/A_C_0x", "/C_n A_Tx", "/C_n A_C_Tx", // new "/A/C_n Tx", "/A/C N_n Tx", "/A_C_n Tx", "/C/n A_Tx", "/C/N_n A_Tx", "/A/C N_0x", "/A/C_0x", }; /* * dst[0] = Artist * dst[1] = CD * dst[2] = Title * dst[3] = +CD * dst[4] = number * dst[5] = ext */ #ifndef isdigit # define isdigit(x) ((unsigned int)((x) - '0') < 10) #endif int CopyTags ( const char* filename ) { FILE* fp; if ( 0 == strncmp (filename, "/dev/", 5 ) ) return 0; fp = fopen ( filename, "rb" ); if ( fp == NULL ) return -1; CopyTags_APE (fp); // APE tags have higher priority than ID3V1 tags CopyTags_ID3 (fp); fclose (fp); return 0; } /* end of tags.c */ musepack_src_r495/common/huffman-bcl.c0000664000000000000000000001747610576623550016666 0ustar rootroot/************************************************************************* * Huffman codes generation, part of the code from the Basic Compression * Library ( http://bcl.sourceforge.net ) * * Modified by Nicolas BOTTI rududu at laposte.net * *------------------------------------------------------------------------- * Copyright (c) 2003-2006 Marcus Geelnard * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would * be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * * Marcus Geelnard * marcus.geelnard at home.se *************************************************************************/ #include #include typedef struct { int Symbol; unsigned int Count; unsigned int Code; unsigned int Bits; } huff_sym_t; typedef struct huff_node huff_node_t; struct huff_node { huff_node_t * ChildA; union { huff_node_t * ChildB; huff_sym_t * Symbol; }; int Count; }; static void _Huffman_StoreTree( huff_node_t *node, unsigned int bits ) { /* Is this a leaf node? */ if( node->ChildA == 0 ) { /* Store code info in symbol array */ node->Symbol->Bits = bits; return; } /* Branch A */ _Huffman_StoreTree( node->ChildA, bits+1 ); /* Branch B */ _Huffman_StoreTree( node->ChildB, bits+1 ); } /** * Compare 2 symbols to sort as canonical huffman (more bits first) * @param sym1 * @param sym2 * @return */ static int _Huffman_CompBits(const huff_sym_t * sym1, const huff_sym_t * sym2) { if (sym1->Bits == sym2->Bits){ if (sym1->Symbol == sym2->Symbol) return 0; else return ((sym1->Symbol > sym2->Symbol) << 1) - 1; } else return ((sym1->Bits < sym2->Bits) << 1) - 1; } /** * Compare 2 symbols to sort in symbol order * @param sym1 * @param sym2 * @return */ static int _Huffman_CompSym(const huff_sym_t * sym1, const huff_sym_t * sym2) { return ((sym1->Symbol > sym2->Symbol) << 1) - 1; } /** * Generate canonical huffman codes from symbols and bit lengths * @param sym * @param num_symbols */ static void _Huffman_MakeCodes(huff_sym_t * sym, unsigned int num_symbols) { unsigned int code = 0, i; int bits; qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompBits); bits = sym[0].Bits; sym[0].Code = 0; for( i = 1; i < num_symbols; i++){ code >>= bits - sym[i].Bits; bits = sym[i].Bits; code++; sym[i].Code = code; } } /** * Make a canonical huffman tree from symbols and counts * @param sym * @param num_symbols */ void _Huffman_MakeTree( huff_sym_t * sym, unsigned int num_symbols) { huff_node_t * nodes, * node_1, * node_2, * root; unsigned int k, nodes_left, next_idx; nodes = malloc(sizeof(huff_node_t) * (num_symbols * 2 - 1)); /* Initialize all leaf nodes */ for( k = 0; k < num_symbols; ++ k ) { nodes[k].Symbol = & sym[k]; nodes[k].Count = sym[k].Count; nodes[k].ChildA = (huff_node_t *) 0; } /* Build tree by joining the lightest nodes until there is only one node left (the root node). */ root = (huff_node_t *) 0; nodes_left = num_symbols; next_idx = num_symbols; while( nodes_left > 1 ) { /* Find the two lightest nodes */ node_1 = (huff_node_t *) 0; node_2 = (huff_node_t *) 0; for( k = 0; k < next_idx; ++ k ) { if( nodes[k].Count >= 0 ) { if( !node_1 || (nodes[k].Count <= node_1->Count) ) { node_2 = node_1; node_1 = &nodes[k]; } else if( !node_2 || (nodes[k].Count <= node_2->Count) ) node_2 = &nodes[k]; } } /* Join the two nodes into a new parent node */ root = &nodes[next_idx]; root->ChildA = node_1; root->ChildB = node_2; root->Count = node_1->Count + node_2->Count; node_1->Count = -1; node_2->Count = -1; ++ next_idx; -- nodes_left; } /* Store the tree in the output stream, and in the sym[] array (the latter is used as a look-up-table for faster encoding) */ if( root ) { _Huffman_StoreTree( root, 0 ); } else { /* Special case: only one symbol => no binary tree */ root = &nodes[0]; _Huffman_StoreTree( root, 1 ); } free(nodes); _Huffman_MakeCodes(sym, num_symbols); } #ifdef __GNUC__ /** * Print the huffman tables * print_type = 0 => print the coding table * print_type = 1 => print the decoding table * print_type = 2 => print the full codes in symbols order * print_type = 3 => print the full codes in codes order * @param sym * @param num_symbols * @param print_type * @param offset */ void _Huffman_PrintCodes(huff_sym_t * sym, unsigned int num_symbols, int print_type, int offset) { unsigned int total_cnt = 0, total_size = 0, optim_size = 0, i; int packs[4]; switch( print_type ) { case 0 : qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompSym); printf("{\n "); for( i = 0; i < num_symbols; i++) { if (i != 0) printf(", "); printf("{%u, %u}", sym[i].Code, sym[i].Bits); } printf("\n}\n"); break; case 1: qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompBits); printf("{\n "); for( i = num_symbols - 1; i >= 0; i--) { printf("{0x%.8x, %u, %i}", sym[i].Code << (32 - sym[i].Bits), sym[i].Bits, sym[i].Symbol - offset); if (i != 0) printf(", "); } printf("\n}\n"); break; case 4: qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompBits); printf("{\n "); for( i = num_symbols - 1; i >= 0; i--) { int symbol = sym[i].Symbol; packs[3] = symbol / (offset * offset * offset); packs[2] = (symbol - packs[3] * offset * offset * offset) / (offset * offset); packs[1] = (symbol - (packs[3] * offset + packs[2]) * offset * offset) / offset; packs[0] = symbol - ((packs[3] * offset + packs[2]) * offset + packs[1] * offset); packs[0] -= offset >> 1; packs[1] -= offset >> 1; packs[2] -= offset >> 1; packs[3] -= offset >> 1; symbol = ((packs[3] & 15) << 12) | ((packs[2] & 15) << 8) | ((packs[1] & 15) << 4) | (packs[0] & 15); printf("{0x%.8x, %u, %i}", sym[i].Code << (32 - sym[i].Bits), sym[i].Bits, symbol); if (i != 0) printf(", "); } printf("\n}\n"); break; default: if (print_type == 2) qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompSym); else qsort(sym, num_symbols, sizeof(huff_sym_t), (int (*)(const void *, const void *)) _Huffman_CompBits); printf("Symbol Count Lenth Code\n"); for( i = 0; i < num_symbols; i++) { int k = sym[i].Bits - 1; printf("%-10i %-10u %-10u ", sym[i].Symbol - offset, sym[i].Count, sym[i].Bits); for (; k >= 0 ; k--) printf("%u", (sym[i].Code >> k) & 1 ); printf("\n"); total_cnt += sym[i].Count; total_size += sym[i].Count * sym[i].Bits; if (sym[i].Count != 0) optim_size += sym[i].Count * __builtin_log2(sym[i].Count); } optim_size = total_cnt * __builtin_log2(total_cnt) - optim_size; printf("\ncount : %u huff : %f bps ", total_cnt, (float)total_size / total_cnt); printf("opt : %f bps ", (float)optim_size / total_cnt); printf("loss : %f bps (%f %%)\n", (float)(total_size - optim_size) / total_cnt, (float)(total_size - optim_size) * 100 / optim_size); break; } } #endif musepack_src_r495/common/fastmath.c0000664000000000000000000000406212231315357016267 0ustar rootroot/* * Musepack audio compression * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see */ #include "mpc/mpcmath.h" #ifdef FAST_MATH const float tabatan2 [ 2*TABSTEP+1] [2]; const float tabcos [26*TABSTEP+1] [2]; const float tabsqrt_ex [256]; const float tabsqrt_m [ TABSTEP+1] [2]; void Init_FastMath ( void ) { int i; mpc_floatint X; double xm, x0, xp, x, y; float* p; p = (float*) tabatan2; for ( i = -TABSTEP; i <= TABSTEP; i++ ) { xm = atan ((i-0.5)/TABSTEP); x0 = atan ((i+0.0)/TABSTEP); xp = atan ((i+0.5)/TABSTEP); x = x0/2 + (xm + xp)/4; y = xp - xm; *p++ = x; *p++ = y; } p = (float*) tabcos; for ( i = -13*TABSTEP; i <= 13*TABSTEP; i++ ) { xm = cos ((i-0.5)/TABSTEP); x0 = cos ((i+0.0)/TABSTEP); xp = cos ((i+0.5)/TABSTEP); x = x0/2 + (xm + xp)/4; y = xp - xm; *p++ = x; *p++ = y; } p = (float*) tabsqrt_ex; for ( i = 0; i < 255; i++ ) { X.n = (i << 23); *p++ = sqrt(X.f); } X.n = (255 << 23) - 1; *p++ = sqrt(X.f); p = (float*) tabsqrt_m; for ( i = 1*TABSTEP; i <= 2*TABSTEP; i++ ) { xm = sqrt ((i-0.5)/TABSTEP); x0 = sqrt ((i+0.0)/TABSTEP); xp = sqrt ((i+0.5)/TABSTEP); x = x0/2 + (xm + xp)/4; y = xp - xm; *p++ = x; *p++ = y; } } #endif musepack_src_r495/common/crc32.c0000664000000000000000000000226211220505350015363 0ustar rootroot/* * C Implementation: crc32 * * code from http://www.w3.org/TR/PNG/#D-CRCAppendix * */ /* Table of CRCs of all 8-bit messages. */ static unsigned long crc_table[256]; /* Flag: has the table been computed? Initially false. */ static int crc_table_computed = 0; /* Make the table for a fast CRC. */ static void make_crc_table(void) { unsigned long c; int n, k; for (n = 0; n < 256; n++) { c = (unsigned long) n; for (k = 0; k < 8; k++) { if (c & 1) c = 0xedb88320L ^ (c >> 1); else c = c >> 1; } crc_table[n] = c; } crc_table_computed = 1; } /* Update a running CRC with the bytes buf[0..len-1]--the CRC should be initialized to all 1's, and the transmitted value is the 1's complement of the final running CRC (see the crc() routine below). */ static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len) { unsigned long c = crc; int n; if (!crc_table_computed) make_crc_table(); for (n = 0; n < len; n++) { c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); } return c; } /* Return the CRC of the bytes buf[0..len-1]. */ unsigned long mpc_crc32(unsigned char *buf, int len) { return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; } musepack_src_r495/configure.in0000664000000000000000000000167611234134160015336 0ustar rootrootAC_INIT([libmpcs], [0.1]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([libmpcdec/mpc_reader.c]) AM_CONFIG_HEADER([include/config.h]) AM_INIT_AUTOMAKE AC_LANG_C AC_PROG_CC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_CHECK_HEADERS([replaygain/gain_analysis.h]) AM_CONDITIONAL([MPC_GAIN], [test "x$ac_cv_header_replaygain_gain_analysis_h" = xyes]) AC_CANONICAL_HOST() case $host_os in *mingw32* ) LDFLAGS="${LDFLAGS} -mwindows" EXTRALIBS="-lwinmm" ;; * ) EXTRALIBS="" ;; esac AC_SUBST([EXTRALIBS]) AC_ARG_ENABLE([mpcchap], [AS_HELP_STRING([--enable-mpcchap], [enable building mpcchap])]) AM_CONDITIONAL([MPC_CHAP], [test "x$enable_mpcchap" = xyes]) CHECK_VISIBILITY AC_CONFIG_FILES([ Makefile include/Makefile libmpcdec/Makefile libmpcenc/Makefile libmpcpsy/Makefile libwavformat/Makefile mpc2sv8/Makefile mpcchap/Makefile mpccut/Makefile mpcdec/Makefile mpcenc/Makefile mpcgain/Makefile wavcmp/Makefile ]) AC_OUTPUT musepack_src_r495/libwavformat/0000775000000000000000000000000012765302354015524 5ustar rootrootmusepack_src_r495/libwavformat/output.c0000664000000000000000000002633210613175506017233 0ustar rootroot#include "libwaveformat.h" __inline static void write_int24(t_wav_uint8 * p_output,t_wav_int32 p_value) { p_output[0] = (t_wav_uint8)(p_value); p_output[1] = (t_wav_uint8)(p_value>>8); p_output[2] = (t_wav_uint8)(p_value>>16); } __inline static void write_int32(t_wav_uint8 * p_output,t_wav_int32 p_value) { p_output[0] = (t_wav_uint8)(p_value); p_output[1] = (t_wav_uint8)(p_value>>8); p_output[2] = (t_wav_uint8)(p_value>>16); p_output[3] = (t_wav_uint8)(p_value>>24); } __inline static void write_float(t_wav_uint8 * p_output,t_wav_float32 p_value) { t_wav_conv bah; bah.f = p_value; p_output[0] = (t_wav_uint8)bah.n; p_output[1] = (t_wav_uint8)(bah.n >> 8); p_output[2] = (t_wav_uint8)(bah.n >> 16); p_output[3] = (t_wav_uint8)(bah.n >> 24); } static void g_convert_float32_to_uint8(t_wav_float32 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n 0x7F) temp = 0x7F; *(p_output++) = (t_wav_uint8)temp ^ 0x80; } } static void g_convert_int16_to_uint8(t_wav_int16 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n> 8) ^ 0x80; } } static void g_convert_float32_to_int16(t_wav_float32 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n 0x7FFF) temp = 0x7FFF; *(p_output++) = (t_wav_uint8)((t_wav_uint32)temp); *(p_output++) = (t_wav_uint8)((t_wav_uint32)temp >> 8); } } static void g_convert_int16_to_int16(t_wav_int16 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n> 8); } } static void g_convert_float32_to_int24(t_wav_float32 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;nm_callback.m_write(p_file->m_callback.m_user_data,p_buffer,p_buffer_size); } static t_wav_uint32 waveformat_seek(t_wav_output_file * p_file,t_wav_uint32 p_position) { return p_file->m_callback.m_seek(p_file->m_callback.m_user_data,p_position); } static t_wav_uint32 waveformat_write_riff(t_wav_output_file * p_file,t_riff_header p_riff) { return waveformat_write(p_file,&p_riff,sizeof(p_riff)) / sizeof(p_riff); } static t_wav_uint32 waveformat_write_uint32(t_wav_output_file * p_file,t_wav_uint32 p_val) { t_wav_uint8 temp[4] = { (t_wav_uint8)(p_val & 0xFF), (t_wav_uint8)((p_val >> 8) & 0xFF), (t_wav_uint8)((p_val >> 16) & 0xFF), (t_wav_uint8)((p_val >> 24) & 0xFF) }; return waveformat_write(p_file,temp,4) / 4; } static t_wav_uint32 waveformat_write_uint16(t_wav_output_file * p_file,t_wav_uint16 p_val) { t_wav_uint8 temp[2] = { (t_wav_uint8)(p_val & 0xFF), (t_wav_uint8)((p_val >> 8) & 0xFF) }; return waveformat_write(p_file,temp,2) / 2; } static t_wav_uint32 calculate_riff_size(t_wav_output_file * p_file,t_wav_uint32 p_samples_written) { t_wav_uint32 bytes_written = p_samples_written * p_file->m_bytes_per_sample, bytes_written_padded = bytes_written; if (bytes_written & 1)//padding bytes_written_padded++; return bytes_written_padded + 4 + 8 + 2+2+4+4+2+2 + 8; } static t_wav_uint32 calculate_data_size(t_wav_output_file * p_file,t_wav_uint32 p_samples_written) { return p_samples_written * p_file->m_bytes_per_sample; } t_wav_uint32 waveformat_output_open(t_wav_output_file * p_file,t_wav_output_file_callback p_callback,t_wav_uint32 p_channels,t_wav_uint32 p_bits_per_sample,t_wav_uint32 p_float,t_wav_uint32 p_sample_rate,t_wav_uint32 p_samples_written_expected) { p_file->m_callback = p_callback; p_file->m_channels = p_channels; p_file->m_bits_per_sample = p_bits_per_sample; p_file->m_float = p_float; p_file->m_sample_rate = p_sample_rate; p_file->m_bytes_per_sample = p_bits_per_sample >> 3; if (p_file->m_bytes_per_sample == 0) return 0; p_file->m_buffer_size = sizeof(p_file->m_workbuffer) / p_file->m_bytes_per_sample; p_file->m_samples_written_expected = p_samples_written_expected; if (p_float) { switch(p_bits_per_sample) { case 32: p_file->m_output_handler = g_wav_output_handler_float32; break; default: return 0; } } else { switch(p_bits_per_sample) { case 8: p_file->m_output_handler = g_wav_output_handler_uint8; break; case 16: p_file->m_output_handler = g_wav_output_handler_int16; break; case 24: p_file->m_output_handler = g_wav_output_handler_int24; break; case 32: p_file->m_output_handler = g_wav_output_handler_int32; break; default: return 0; } } if (waveformat_write_riff(p_file,g_header_riff) != 1) return 0; if (waveformat_write_uint32(p_file,calculate_riff_size(p_file,p_file->m_samples_written_expected)) != 1) return 0; //to be possibly rewritten later, offset : 4 if (waveformat_write_riff(p_file,g_header_wave) != 1) return 0; //offset: 12 if (waveformat_write_riff(p_file,g_header_fmt) != 1) return 0; if (waveformat_write_uint32(p_file,2+2+4+4+2+2) != 1) return 0; //offset: 12 + 8 if (waveformat_write_uint16(p_file,p_float ? waveformat_tag_float : waveformat_tag_int) != 1) return 0; if (waveformat_write_uint16(p_file,(t_wav_uint16) p_channels) != 1) return 0; if (waveformat_write_uint32(p_file,p_sample_rate) != 1) return 0; if (waveformat_write_uint32(p_file,(t_wav_uint32)(p_sample_rate * p_file->m_bytes_per_sample * p_channels)) != 1) return 0; if (waveformat_write_uint16(p_file,(t_wav_uint16)(p_file->m_bytes_per_sample * p_channels)) != 1) return 0; if (waveformat_write_uint16(p_file,(t_wav_uint16)p_bits_per_sample) != 1) return 0; //offset: 12 + 8 + 2+2+4+4+2+2 if (waveformat_write_riff(p_file,g_header_data) != 1) return 0; if (waveformat_write_uint32(p_file,calculate_data_size(p_file,p_file->m_samples_written_expected)) != 1) return 0; //to be possibly rewritten later, offset : 12 + 8 + 2+2+4+4+2+2 + 4 //total header size: 12 + 8 + 2+2+4+4+2+2 + 8 p_file->m_samples_written = 0; return 1; } t_wav_uint32 waveformat_output_process_float32(t_wav_output_file * p_file,t_wav_float32 const * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 samples_done; samples_done = 0; while(samples_done < p_sample_count) { t_wav_uint32 delta = p_sample_count - samples_done, delta_written; if (delta > p_file->m_buffer_size) delta = p_file->m_buffer_size; p_file->m_output_handler.m_convert_float32(p_sample_buffer + samples_done,p_file->m_workbuffer,delta); delta_written = waveformat_write(p_file,p_file->m_workbuffer,delta * p_file->m_bytes_per_sample) / p_file->m_bytes_per_sample; if (delta_written > 0) { samples_done += delta_written; } if (delta_written != delta) break; } p_file->m_samples_written += samples_done; return samples_done; } t_wav_uint32 waveformat_output_process_int16(t_wav_output_file * p_file,t_wav_int16 const * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 samples_done; samples_done = 0; while(samples_done < p_sample_count) { t_wav_uint32 delta = p_sample_count - samples_done, delta_written; if (delta > p_file->m_buffer_size) delta = p_file->m_buffer_size; p_file->m_output_handler.m_convert_int16(p_sample_buffer + samples_done,p_file->m_workbuffer,delta); delta_written = waveformat_write(p_file,p_file->m_workbuffer,delta * p_file->m_bytes_per_sample) / p_file->m_bytes_per_sample; if (delta_written > 0) { samples_done += delta_written; } if (delta_written != delta) break; } p_file->m_samples_written += samples_done; return samples_done; } t_wav_uint32 waveformat_output_close(t_wav_output_file * p_file) { if ((p_file->m_samples_written * p_file->m_bytes_per_sample) & 1)//padding { t_wav_uint8 meh = 0; if (waveformat_write(p_file,&meh,1) != 1) return 0; } if (p_file->m_samples_written != p_file->m_samples_written_expected) { if (!waveformat_seek(p_file,4)) return 0; if (waveformat_write_uint32(p_file,calculate_riff_size(p_file,p_file->m_samples_written)) != 1) return 0; if (!waveformat_seek(p_file,12 + 8 + 2+2+4+4+2+2 + 4)) return 0; if (waveformat_write_uint32(p_file,calculate_data_size(p_file,p_file->m_samples_written)) != 1) return 0; } return 1; } musepack_src_r495/libwavformat/Makefile.am0000664000000000000000000000031111234134160017537 0ustar rootrootEXTRA_DIST = CMakeLists.txt if HAVE_VISIBILITY AM_CFLAGS = -fvisibility=hidden endif METASOURCES = AUTO noinst_LIBRARIES = libwavformat.a libwavformat_a_SOURCES = input.c output.c libwaveformat.h musepack_src_r495/libwavformat/CMakeLists.txt0000664000000000000000000000006210601544104020246 0ustar rootrootadd_library(wavformat_static STATIC input output) musepack_src_r495/libwavformat/input.c0000664000000000000000000003016710613175506017033 0ustar rootroot#include "libwaveformat.h" typedef struct { t_wav_uint8 m_data[4]; } t_riff_header; static t_wav_uint32 riff_compare(t_riff_header p_chunk,t_wav_uint8 a,t_wav_uint8 b,t_wav_uint8 c,t_wav_uint8 d) { return (p_chunk.m_data[0] == a && p_chunk.m_data[1] == b && p_chunk.m_data[2] == c && p_chunk.m_data[3] == d) ? 1 : 0; } static void g_convert_float32_to_float32(t_wav_uint8 const * p_input,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n 0x7FFF) tempi = 0x7FFF; p_sample_buffer[n] = (t_wav_int16) tempi; } } static void g_convert_int32_to_float32(t_wav_uint8 const * p_input,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n> 16 ); } } static void g_convert_int24_to_float32(t_wav_uint8 const * p_input,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;n> 8 ); } } static void g_convert_int16_to_float32(t_wav_uint8 const * p_input,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 n; for(n=0;nm_callback.m_read(p_file->m_callback.m_user_data,p_buffer,p_bytes); } static t_wav_uint32 waveformat_skip(t_wav_input_file * p_file,t_wav_uint32 p_bytes) { t_wav_uint8 dummy[256]; t_wav_uint32 delta,done,delta_done; done = 0; while(done < p_bytes) { delta = p_bytes - done; if (delta > sizeof(dummy)) delta = sizeof(dummy); delta_done = waveformat_read(p_file,dummy,delta); done += delta_done; if (delta_done != delta) break; } return done; } static t_wav_uint32 waveformat_read_riff(t_wav_input_file * p_file,t_riff_header * p_header) { return waveformat_read(p_file,p_header,sizeof(t_riff_header)) / sizeof(t_riff_header); } static t_wav_uint32 waveformat_read_uint32(t_wav_input_file * p_file,t_wav_uint32 * p_value) { t_wav_uint8 temp[4]; if (waveformat_read(p_file,&temp,sizeof(temp)) != sizeof(temp)) return 0; * p_value = ((t_wav_uint32)temp[0]) | ((t_wav_uint32)temp[1] << 8) | ((t_wav_uint32)temp[2] << 16) | ((t_wav_uint32)temp[3] << 24); return 1; } static t_wav_uint32 waveformat_read_uint16(t_wav_input_file * p_file,t_wav_uint16 * p_value) { t_wav_uint8 temp[2]; if (waveformat_read(p_file,&temp,sizeof(temp)) != sizeof(temp)) return 0; * p_value = ((t_wav_uint16)temp[0]) | ((t_wav_uint16)temp[1] << 8); return 1; } t_wav_uint32 waveformat_input_open(t_wav_input_file * p_file,t_wav_input_file_callback p_callback) { t_riff_header header; t_wav_uint32 main_size,main_offset,chunk_size; t_wav_uint8 found_fmt; found_fmt = 0; p_file->m_callback = p_callback; if (waveformat_read_riff(p_file,&header) != 1) return 0; if (!riff_compare(header,'R','I','F','F')) return 0; if (waveformat_read_uint32(p_file,&main_size) != 1) return 0; if (main_size < 4) return 0; if (waveformat_read_riff(p_file,&header) != 1) return 0; if (!riff_compare(header,'W','A','V','E')) return 0; main_offset = 4; for(;;) { if (main_size - main_offset < 8) return 0; if (waveformat_read_riff(p_file,&header) != 1) return 0; if (waveformat_read_uint32(p_file,&chunk_size) != 1) return 0; main_offset += 8; if (main_size - main_offset < chunk_size) return 0; if (riff_compare(header,'f','m','t',' ')) { t_wav_uint32 fmt_remaining; if (found_fmt) return 0;//duplicate fmt chunk fmt_remaining = chunk_size; if (fmt_remaining < 2+2+4+4+2+2) return 0; if (waveformat_read_uint16(p_file,&p_file->m_format_tag ) != 1) return 0; if (waveformat_read_uint16(p_file,&p_file->m_channels ) != 1) return 0; if (waveformat_read_uint32(p_file,&p_file->m_samples_per_sec ) != 1) return 0; if (waveformat_read_uint32(p_file,&p_file->m_avg_bytes_per_sec ) != 1) return 0; if (waveformat_read_uint16(p_file,&p_file->m_block_align ) != 1) return 0; if (waveformat_read_uint16(p_file,&p_file->m_bits_per_sample ) != 1) return 0; p_file->m_bytes_per_sample = p_file->m_bits_per_sample / 8; if (p_file->m_bytes_per_sample == 0) return 0; p_file->m_buffer_size = sizeof(p_file->m_workbuffer) / p_file->m_bytes_per_sample; fmt_remaining -= 2+2+4+4+2+2; switch(p_file->m_format_tag) { case waveformat_tag_int: switch(p_file->m_bits_per_sample) { case 8: p_file->m_input_handler = g_input_handler_uint8; break; case 16: p_file->m_input_handler = g_input_handler_int16; break; case 24: p_file->m_input_handler = g_input_handler_int24; break; case 32: p_file->m_input_handler = g_input_handler_int32; break; default: //unsupported format return 0; } break; case waveformat_tag_float: switch(p_file->m_bits_per_sample) { case 32: p_file->m_input_handler = g_input_handler_float32; break; #if 0 case 64: break; #endif default: //unsupported format return 0; } break; default: //unsupported format return 0; } if (chunk_size & 1) fmt_remaining++; if (fmt_remaining > 0) { if (waveformat_skip(p_file,fmt_remaining) != fmt_remaining) return 0; } main_offset += chunk_size; if (chunk_size & 1) main_offset++; found_fmt = 1; } else if (riff_compare(header,'d','a','t','a')) { if (!found_fmt) return 0;//found data before fmt, don't know how to handle data //found parsable data chunk, ok to proceed p_file->m_data_size = chunk_size / p_file->m_bytes_per_sample; p_file->m_data_position = 0; break; } else {//unknown chunk, let's skip over t_wav_uint32 toskip = chunk_size; if (toskip & 1) toskip++; if (waveformat_skip(p_file,toskip) != toskip) return 0; main_offset += toskip; } } return 1; } t_wav_uint32 waveformat_input_process_float32(t_wav_input_file * p_file,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 samples_read; samples_read = 0; if (p_file->m_data_position + p_sample_count > p_file->m_data_size) p_sample_count = p_file->m_data_size - p_file->m_data_position; while(samples_read < p_sample_count) { t_wav_uint32 delta, deltaread; delta = p_sample_count - samples_read; if (delta > p_file->m_buffer_size) delta = p_file->m_buffer_size; deltaread = waveformat_read(p_file,p_file->m_workbuffer,delta * p_file->m_bytes_per_sample) / p_file->m_bytes_per_sample; if (deltaread > 0) { p_file->m_input_handler.m_convert_float32(p_file->m_workbuffer,p_sample_buffer + samples_read,deltaread); samples_read += deltaread; } if (deltaread != delta) break; } p_file->m_data_position += samples_read; return samples_read; } t_wav_uint32 waveformat_input_process_int16(t_wav_input_file * p_file,t_wav_int16 * p_sample_buffer,t_wav_uint32 p_sample_count) { t_wav_uint32 samples_read; samples_read = 0; if (p_file->m_data_position + p_sample_count > p_file->m_data_size) p_sample_count = p_file->m_data_size - p_file->m_data_position; while(samples_read < p_sample_count) { t_wav_uint32 delta, deltaread; delta = p_sample_count - samples_read; if (delta > p_file->m_buffer_size) delta = p_file->m_buffer_size; deltaread = waveformat_read(p_file,p_file->m_workbuffer,delta * p_file->m_bytes_per_sample) / p_file->m_bytes_per_sample; if (deltaread > 0) { p_file->m_input_handler.m_convert_int16(p_file->m_workbuffer,p_sample_buffer + samples_read,deltaread); samples_read += deltaread; } if (deltaread != delta) break; } p_file->m_data_position += samples_read; return samples_read; } void waveformat_input_close(t_wav_input_file * p_file) { } t_wav_uint32 waveformat_input_query_sample_rate(t_wav_input_file * p_file) { return p_file->m_samples_per_sec; } t_wav_uint32 waveformat_input_query_channels(t_wav_input_file * p_file) { return p_file->m_channels; } t_wav_uint32 waveformat_input_query_length(t_wav_input_file * p_file) { return p_file->m_data_size; } musepack_src_r495/libwavformat/libwaveformat.h0000664000000000000000000001011710613175506020534 0ustar rootroot#ifndef __LIBWAVEFORMAT_H__ #define __LIBWAVEFORMAT_H__ #ifdef WIN32 #pragma once #endif #ifdef __cplusplus extern "C" { #endif //general declarations #ifdef _MSC_VER typedef __int8 t_wav_int8; typedef unsigned __int8 t_wav_uint8; typedef __int16 t_wav_int16; typedef unsigned __int16 t_wav_uint16; typedef __int32 t_wav_int32; typedef unsigned __int32 t_wav_uint32; typedef __int64 t_wav_int64; typedef unsigned __int64 t_wav_uint64; typedef float t_wav_float32; typedef double t_wav_float64; #else #include typedef int8_t t_wav_int8; typedef uint8_t t_wav_uint8; typedef int16_t t_wav_int16; typedef uint16_t t_wav_uint16; typedef int32_t t_wav_int32; typedef uint32_t t_wav_uint32; typedef int64_t t_wav_int64; typedef uint64_t t_wav_uint64; typedef float t_wav_float32; typedef double t_wav_float64; #endif typedef union { t_wav_float32 f; t_wav_uint32 n; } t_wav_conv; #define waveformat_tag_int 1 #define waveformat_tag_float 3 //WAV file reader typedef struct { t_wav_uint32 (*m_read)(void * p_user_data,void * p_buffer,t_wav_uint32 p_bytes); void * m_user_data; } t_wav_input_file_callback; typedef struct { void (*m_convert_float32)(t_wav_uint8 const * p_input,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count); void (*m_convert_int16)(t_wav_uint8 const * p_input,t_wav_int16 * p_sample_buffer,t_wav_uint32 p_sample_count); } t_wav_input_handler; typedef struct { t_wav_input_file_callback m_callback; t_wav_input_handler m_input_handler; t_wav_uint16 m_format_tag; t_wav_uint16 m_channels; t_wav_uint32 m_samples_per_sec; t_wav_uint32 m_avg_bytes_per_sec; t_wav_uint16 m_block_align; t_wav_uint16 m_bits_per_sample; t_wav_uint32 m_bytes_per_sample, m_buffer_size; t_wav_uint32 m_data_size; t_wav_uint32 m_data_position; t_wav_uint8 m_workbuffer[512]; } t_wav_input_file; t_wav_uint32 waveformat_input_open(t_wav_input_file * p_file,t_wav_input_file_callback p_callback); t_wav_uint32 waveformat_input_process_float32(t_wav_input_file * p_file,t_wav_float32 * p_sample_buffer,t_wav_uint32 p_sample_count); t_wav_uint32 waveformat_input_process_int16(t_wav_input_file * p_file,t_wav_int16 * p_sample_buffer,t_wav_uint32 p_sample_count); void waveformat_input_close(t_wav_input_file * p_file); t_wav_uint32 waveformat_input_query_sample_rate(t_wav_input_file * p_file); t_wav_uint32 waveformat_input_query_channels(t_wav_input_file * p_file); t_wav_uint32 waveformat_input_query_length(t_wav_input_file * p_file); //WAV file writer typedef struct { t_wav_uint32 (*m_write)(void * p_user_data,void const * p_buffer,t_wav_uint32 p_bytes); t_wav_uint32 (*m_seek)(void * p_user_data,t_wav_uint32 p_position); void * m_user_data; } t_wav_output_file_callback; typedef struct { void (*m_convert_float32)(t_wav_float32 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count); void (*m_convert_int16)(t_wav_int16 const * p_sample_buffer,t_wav_uint8 * p_output,t_wav_uint32 p_sample_count); } t_wav_output_handler; typedef struct { t_wav_output_file_callback m_callback; t_wav_output_handler m_output_handler; t_wav_uint32 m_channels; t_wav_uint32 m_bits_per_sample; t_wav_uint32 m_float; t_wav_uint32 m_sample_rate; t_wav_uint32 m_samples_written,m_samples_written_expected; t_wav_uint32 m_bytes_per_sample, m_buffer_size; t_wav_uint8 m_workbuffer[512]; } t_wav_output_file; t_wav_uint32 waveformat_output_open(t_wav_output_file * p_file,t_wav_output_file_callback p_callback,t_wav_uint32 p_channels,t_wav_uint32 p_bits_per_sample,t_wav_uint32 p_float,t_wav_uint32 p_sample_rate,t_wav_uint32 p_expected_samples); t_wav_uint32 waveformat_output_process_float32(t_wav_output_file * p_file,t_wav_float32 const * p_sample_buffer,t_wav_uint32 p_sample_count); t_wav_uint32 waveformat_output_process_int16(t_wav_output_file * p_file,t_wav_int16 const * p_sample_buffer,t_wav_uint32 p_sample_count); t_wav_uint32 waveformat_output_close(t_wav_output_file * p_file); #ifdef __cplusplus } //extern "C" #endif #endif //__LIBWAVEFORMAT_H__ musepack_src_r495/docs/0000775000000000000000000000000012765302355013760 5ustar rootrootmusepack_src_r495/docs/mainpage.txt0000664000000000000000000000350610511462255016277 0ustar rootroot/** \mainpage libmpcdec documentation \section whats what is libmpcdec libmpcdec is a library that decodes musepack compressed audio data. Musepack is a free, high performance, high quality lossy audio compression codec. For more information on musepack visit http://www.musepack.net. \section using using libmpcdec Using libmpcdec is very straightforward. There are typically four things you must do to use libmpcdec in your application. \subsection step1 step 1: implement an mpc_reader to provide raw data to the decoder library The role of the mpc_reader is to provide raw mpc stream data to the mpc decoding library. This data can come from a file, a network socket, or any other source you wish. See the documentation of \link mpc_reader_t mpc_reader \endlink for more information. \subsection step2 step2: read the streaminfo properties structure from the stream This is a simple matter of calling the streaminfo_init() and streaminfo_read() functions, supplying your mpc_reader as a source of raw data. This reads the stream properties header from the mpc stream. This information will be used to prime the decoder for decoding in the next step. \subsection step3 step 3: initialize an mpc_decoder with your mpc_reader source This is just a matter of calling the mpc_decoder_setup() and mpc_decoder_initialize() functions with your mpc_decoder, mpc_reader data source and streaminfo information. \subsection step4 step 4: iteratively read raw sample data from the mpc decoder Once you've initialized the decoding library you just iteratively call the mpc_decoder_decode routine until it indicates that the entire stream has been read. For a simple example of all of these steps see the sample application distributed with libmpcdec in src/sample.cpp. */ musepack_src_r495/docs/Doxyfile0000664000000000000000000013507110467353433015475 0ustar rootroot# Doxyfile 1.3.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libmpcdec # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.2.2 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of source # files, where putting all generated files in the same directory would otherwise # cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is used # as the annotated text. Otherwise, the brief description is used as-is. If left # blank, the following values are used ("$name" is automatically replaced with the # name of the entity): "The $name class" "The $name widget" "The $name file" # "is" "provides" "specifies" "contains" "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited # members of a class in the documentation of that class as if those members were # ordinary class members. Constructors, destructors and assignment operators of # the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. SHOW_DIRECTORIES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = include src # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = include/config.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # that are symbolic links (a Unix filesystem feature) are excluded from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = docs/custom.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse the # parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or # super classes. Setting the tag to NO turns the diagrams off. Note that this # option is superseded by the HAVE_DOT option below. This is only a fallback. It is # recommended to install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes that # lay further from the root node will be omitted. Note that setting this option to # 1 or 2 may greatly reduce the computation time needed for large code bases. Also # note that a graph may be further truncated if the graph's image dimensions are # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). # If 0 is used for the depth value (the default), the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO musepack_src_r495/docs/custom.css0000664000000000000000000001157710467352013016010 0ustar rootrootBODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: sans-serif; } h1 { text-align: center; text-transform: lowercase; margin: 0.5em 0; } h2, h2 a { color: #f90; margin: 1em 0 0.25em 0; } h3, h3 a { color: #88f; margin: 1em 0 0.25em 0; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #eeeeff; border: 1px solid #b0b0b0; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { text-align: center; padding: 0.25em 0; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; text-transform: lowercase; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; text-transform: lowercase; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindex, A.qindexHL { padding: 0.1em 0.5em; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold; color: #d66; font-style: italic } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } hr { display: none } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } TD.md { font-weight: bold; } TD.mdname1, TD.mdname { color: #088; font-weight: bold; } TABLE[cellspacing="5"] { margin-left: 2em; } TABLE[cellspacing="5"] dl em { color: #088; font-weight: bold; } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 14px } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey, TD.indexvalue { padding: 0.1em 1em 0.1em 0.1em; } TD.indexkey { font-weight: bold; } TD.indexvalue { font-style: italic; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdTable { } .mdRow { } .mdescLeft, .mdescRight { font-style: italic; font-size: 80%; } .mdescRight { } .memItemLeft { font-style: italic; } .memItemLeft, .memItemRight { font-size: 80%; } .memItemRight { } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 12px; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 13px; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 12px; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #eeeeff; } TD.tiny { font-size: 75%; } a { color: #252E78; } a:visited { color: #3D2185; }