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 #ifndef DSDIFFFILEREADER_H 00039 #define DSDIFFFILEREADER_H 00040 00041 #include "dsd_sample_reader.h" // Base class: dsdSampleReader 00042 #include "fstream_plus.h" 00043 #include <boost/ptr_container/ptr_vector.hpp> 00044 00045 00046 // this struct holds comments 00047 typedef struct{ 00048 dsf2flac_uint16 timeStampYear; 00049 dsf2flac_uint8 timeStampMonth; 00050 dsf2flac_uint8 timeStampDay; 00051 dsf2flac_uint8 timeStampHour; 00052 dsf2flac_uint8 timeStampMinutes; 00053 dsf2flac_uint16 cmtType; 00054 dsf2flac_uint16 cmtRef; 00055 dsf2flac_uint32 count; 00056 dsf2flac_int8* commentText; 00057 } DsdiffComment; 00058 00059 // this struct holds absolute start time 00060 typedef struct{ 00061 dsf2flac_uint16 hours; 00062 dsf2flac_uint8 minutes; 00063 dsf2flac_uint8 seconds; 00064 dsf2flac_uint32 samples; 00065 } DsdiffAst; 00066 00067 // this struct holds markers 00068 typedef struct{ 00069 dsf2flac_uint16 hours; 00070 dsf2flac_uint8 minutes; 00071 dsf2flac_uint8 seconds; 00072 dsf2flac_uint32 samples; 00073 dsf2flac_int32 offset; 00074 dsf2flac_uint16 markType; 00075 dsf2flac_uint16 markChannel; 00076 dsf2flac_uint16 trackFlags; 00077 dsf2flac_uint32 count; 00078 dsf2flac_int8* markerText; 00079 } DsdiffMarker; 00080 00081 // this struct holds DST frame indexes 00082 typedef struct{ 00083 dsf2flac_uint64 offset; 00084 dsf2flac_uint32 length; 00085 } DSTFrameIndex; 00086 00087 // this struct holds DST frame info 00088 typedef struct { 00089 dsf2flac_uint32 numFrames; 00090 dsf2flac_uint16 frameRate; 00091 dsf2flac_uint32 frameSizeInSamplesPerChan; 00092 dsf2flac_uint32 frameSizeInBytesPerChan; 00093 } DSTFrameInformation; 00094 00095 00096 00097 class dsdiffFileReader : public DsdSampleReader 00098 { 00099 public: 00100 // constructor and destructor 00101 dsdiffFileReader(char* filePath); 00102 virtual ~dsdiffFileReader(); 00103 public: 00104 // public overriden from dsdSampleReader 00105 bool step(); 00106 void rewind(); 00107 dsf2flac_int64 getLength() {return sampleCountPerChan;}; 00108 dsf2flac_uint32 getNumChannels() {return chanNum;}; 00109 dsf2flac_uint32 getSamplingFreq() {return samplingFreq;}; 00110 bool msbIsPlayedFirst() { return false;} 00111 bool samplesAvailable() { return !file.eof() && DsdSampleReader::samplesAvailable(); }; // false when no more samples left 00112 ID3_Tag getID3Tag(dsf2flac_uint32 trackNum); 00113 dsf2flac_uint32 getNumTracks() {return numTracks;}; // the number of audio tracks in the dsd data 00114 dsf2flac_uint64 getTrackStart(dsf2flac_uint32 trackNum);// return the index to the first sample of the nth track 00115 dsf2flac_uint64 getTrackEnd(dsf2flac_uint32 trackNum); // return the index to the first sample of the nth track 00116 public: 00117 // other public methods 00118 void dispFileInfo(); 00119 private: 00120 // private variables 00121 fstreamPlus file; 00122 // read from the file - these are always present... 00123 dsf2flac_uint32 dsdiffVersion; 00124 dsf2flac_uint32 samplingFreq; 00125 dsf2flac_uint16 chanNum; 00126 dsf2flac_int8** chanIdents; 00127 dsf2flac_int8 compressionType[5]; 00128 dsf2flac_int8* compressionName; 00129 DsdiffAst ast; 00130 dsf2flac_uint64 sampleDataPointer; 00131 dsf2flac_uint64 dstChunkEnd; 00132 dsf2flac_uint64 sampleCountPerChan; 00133 dsf2flac_uint16 lsConfig; 00134 // from optional chunks 00135 std::vector<DsdiffComment> comments; 00136 std::vector<ID3_Tag> tags; 00137 std::vector<DsdiffMarker> markers; 00138 bool isEm; 00139 char* emid; 00140 std::vector<DSTFrameIndex> dstFrameIndices; 00141 DSTFrameInformation dstInfo; 00142 // track info 00143 dsf2flac_uint32 numTracks; 00144 std::vector<dsf2flac_uint64> trackStartPositions; 00145 std::vector<dsf2flac_uint64> trackEndPositions; 00146 00147 // vars to hold the data 00148 dsf2flac_uint8* sampleBuffer; 00149 dsf2flac_uint32 sampleBufferLenPerChan; 00150 dsf2flac_int64 bufferCounter; // stores the index to the current blockBuffer 00151 dsf2flac_int64 bufferMarker; // stores the current position in the blockBuffer 00152 // private methods 00153 void allocateSampleBuffer(); 00154 bool readNextBlock(); 00155 void processTracks(); 00156 // all below here are for reading the headers 00157 bool readHeaders(); 00158 static bool checkIdent(dsf2flac_int8* a, dsf2flac_int8* b); // MUST be used with the char[4]s or you'll get segfaults! 00159 bool readChunkHeader(dsf2flac_int8* ident, dsf2flac_uint64 chunkStart); 00160 bool readChunkHeader(dsf2flac_int8* ident, dsf2flac_uint64 chunkStart, dsf2flac_uint64 *chunkSz); 00161 // readers for specific types of chunk (return true if loaded ok) 00162 bool readChunk_FRM8(dsf2flac_uint64 chunkStart); 00163 bool readChunk_FVER(dsf2flac_uint64 chunkStart); 00164 bool readChunk_PROP(dsf2flac_uint64 chunkStart); 00165 bool readChunk_FS(dsf2flac_uint64 chunkStart); 00166 bool readChunk_CHNL(dsf2flac_uint64 chunkStart); 00167 bool readChunk_CMPR(dsf2flac_uint64 chunkStart); 00168 bool readChunk_ABSS(dsf2flac_uint64 chunkStart); 00169 bool readChunk_DSD(dsf2flac_uint64 chunkStart); 00170 bool readChunk_DST(dsf2flac_uint64 chunkStart); 00171 bool readChunk_DSTF(dsf2flac_uint64 chunkStart); 00172 bool readChunk_COMT(dsf2flac_uint64 chunkStart); 00173 bool readChunk_LSCO(dsf2flac_uint64 chunkStart); 00174 bool readChunk_ID3(dsf2flac_uint64 chunkStart); 00175 bool readChunk_DIIN(dsf2flac_uint64 chunkStart); 00176 bool readChunk_EMID(dsf2flac_uint64 chunkStart); 00177 bool readChunk_MARK(dsf2flac_uint64 chunkStart); 00178 bool readChunk_DSTI(dsf2flac_uint64 chunkStart); 00179 bool readChunk_FRTE(dsf2flac_uint64 chunkStart); 00180 00181 void dispComment(DsdiffComment c); 00182 void dispMarker(DsdiffMarker m); 00183 00184 }; 00185 00186 #endif // DSDIFFFILEREADER_H