DSF2FLAC
|
00001 /* 00002 * dsf2flac - http://code.google.com/p/dsf2flac/ 00003 * 00004 * A file conversion tool for translating dsf dsd audio files into 00005 * flac pcm audio files. 00006 * 00007 * Copyright (c) 2013 by respective authors. 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 * 00023 * 00024 * Acknowledgements 00025 * 00026 * Many thanks to the following authors and projects whose work has greatly 00027 * helped the development of this tool. 00028 * 00029 * 00030 * Sebastian Gesemann - dsd2pcm (http://code.google.com/p/dsd2pcm/) 00031 * SACD Ripper (http://code.google.com/p/sacd-ripper/) 00032 * Maxim V.Anisiutkin - foo_input_sacd (http://sourceforge.net/projects/sacddecoder/files/) 00033 * Vladislav Goncharov - foo_input_sacd_hq (http://vladgsound.wordpress.com) 00034 * Jesus R - www.sonore.us 00035 * 00036 */ 00037 00038 #include "dop_packer.h" 00039 00040 dsf2flac_int32 odd_marker = 0x00050000; 00041 dsf2flac_int32 even_marker = 0xFFFA0000; 00042 00043 DopPacker::DopPacker(DsdSampleReader *r) { 00044 reader = r; 00045 // buffer length needs to be at least 2 chars long 00046 if (2 > reader->getBufferLength()) 00047 reader->setBufferLength(2); 00048 } 00049 00050 DopPacker::~DopPacker() { 00051 00052 } 00053 00054 //unsigned char reverse(unsigned char b) { 00055 // b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; 00056 // b = (b & 0xCC) >> 2 | (b & 0x33) << 2; 00057 // b = (b & 0xAA) >> 1 | (b & 0x55) << 1; 00058 // return b; 00059 //} 00060 00061 unsigned char reverse(unsigned char x) 00062 { 00063 static const unsigned char table[] = { 00064 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 00065 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 00066 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 00067 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 00068 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 00069 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 00070 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 00071 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 00072 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 00073 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 00074 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 00075 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 00076 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 00077 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 00078 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 00079 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 00080 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 00081 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 00082 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 00083 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 00084 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 00085 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 00086 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 00087 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 00088 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 00089 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 00090 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 00091 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 00092 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 00093 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 00094 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 00095 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 00096 }; 00097 return table[x]; 00098 } 00099 00100 void DopPacker::pack_buffer(dsf2flac_int32 *buffer, dsf2flac_uint32 bufferLen) { 00101 // check the buffer seems sensible 00102 div_t d = div(bufferLen,reader->getNumChannels()); 00103 if (d.rem) { 00104 fputs("Buffer length is not a multiple of getNumChannels()",stderr); 00105 exit(EXIT_FAILURE); 00106 } 00107 // get the sample buffer 00108 boost::circular_buffer<dsf2flac_uint8>* buff = reader->getBuffer(); 00109 for (int i=0; i<d.quot ; i++) { 00110 00111 dsf2flac_int32 packed_sample; 00112 dsf2flac_uint8 byte1; 00113 dsf2flac_uint8 byte2; 00114 00115 // step the buffer right away so that the first sample sits in position 1 in the buffer (second in position 0) 00116 reader->step(); 00117 00118 for (dsf2flac_uint32 c=0; c<reader->getNumChannels(); c++) { 00119 00120 if ((reader->getPosition(8) % 32) != 0) 00121 packed_sample = even_marker; 00122 else 00123 packed_sample = odd_marker; 00124 00125 byte1 = buff[c][1]; 00126 byte2 = buff[c][0]; 00127 00128 if (reader->msbIsPlayedFirst()) { 00129 byte1 = reverse(byte1); 00130 byte2 = reverse(byte2); 00131 } 00132 00133 packed_sample += ((dsf2flac_int32) byte1) << 8; 00134 packed_sample += ((dsf2flac_int32) byte2); 00135 00136 buffer[i*reader->getNumChannels()+c] = packed_sample; 00137 } 00138 00139 reader->step(); 00140 } 00141 } 00142