static int _read_eco_header(stream_id nst) { int i, res; /* * temporarily limit buffering to the header size because * we may have to switch to SSCRAMBLE mode for the rest! */ int bufsize = StreamSize(nst); StreamSize(nst) = MAGIC_LEN+1; /* check for eco header and skip if present */ res = _skip_header_if_present(nst, eco_magic, MAGIC_LEN); StreamSize(nst) = bufsize; if (res != PSUCCEED) return PFAIL; /* next byte indicates the eco version */ res = ec_getch(nst); if (res < 0) return res; if (res != ECO_CURRENT_VERSION) return BAD_DUMP_VERSION; StreamMode(nst) |= SSCRAMBLE; StreamRand(nst) = 73540 ^ 0x9bc33c86; /* read the rest of the header */ for(i=0; i<8; ++i) res = ec_getch(nst); return res < 0 ? res : PSUCCEED; }
int main(int argc, char *argv[]) { if( argc != 4 ) { io::cerr << "Usage: \t lpcm2wav sample_rate:channels:bps file.lpcm out_file.wav" << io::endl; io::cerr << "\t lpcm2wav makes wav from dvd lpcm stream." << io::endl; return 1; } PCMWaveHeader hdr; if( !ParsePcmTriple(argv[1], hdr) ) { io::cerr << "Can't get correct sample_rate:channels:bps triple!" << io::endl; return 2; } uint32_t samplerate = hdr.sampleRate; uint16_t channels = hdr.channels; uint16_t bits = hdr.bits; io::cerr << "Sample rate (Hz):\t " << samplerate << io::endl; io::cerr << "Number of channels:\t " << channels << io::endl; io::cerr << "Sample size (bit):\t " << bits << io::endl; io::stream strm(argv[2], iof::in); if( !strm ) { io::cerr << "Can't open file: " << argv[2] << io::endl; return 3; } io::pos file_big_sz = StreamSize(strm); if( file_big_sz > UINT32_MAX-100 ) // ограничение размера wav-файла 32битами { io::cerr << "Can't do wav-file because " << argv[2] << " is too big, > 3,9Gb." << io::endl; return 4; } uint32_t file_sz = file_big_sz; // заполняем оставшееся, c учетом little endian hdr.riff = le2me_32(WAV_ID_RIFF); hdr.fileLen = le2me_32(file_sz + PCM_WAVE_HEADER_SIZE - 8); hdr.wave = le2me_32(WAV_ID_WAVE); hdr.frmt = le2me_32(WAV_ID_FMT); hdr.frmtLen = le2me_32(16); hdr.frmtTag = le2me_16(WAV_ID_PCM); hdr.channels = le2me_16(channels); hdr.sampleRate = le2me_32(samplerate); hdr.bytesPerSecond = le2me_32(channels * samplerate * bits / 8); hdr.blockAlign = le2me_16(channels * bits / 8); hdr.bits = le2me_16(bits); hdr.data = le2me_32(WAV_ID_DATA); hdr.dataLen = le2me_32(file_sz); // запись io::stream wav_strm(argv[3], iof::out); if( !wav_strm ) { io::cerr << "Can't write to file: " << argv[3] << io::endl; return 5; } wav_strm.raw_write((const char*)&hdr, PCM_WAVE_HEADER_SIZE); const char* incomplete_samples = "Error: Number of PCM samples is incomplete."; switch( bits ) { case 16: { if( file_sz%2 ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Swap16AndWrite, bl::_1, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; case 20: { if( file_sz%(5*channels) ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Reconstruct20bitLPCM, bl::_1, channels, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; case 24: { if( file_sz%(6*channels) ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Reconstruct24bitLPCM, bl::_1, channels, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; default: ASSERT(0); } return 0; }