DSF2FLAC
dop_packer.cpp
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 
 All Classes Files Functions Variables