📄 sample.cpp
字号:
#include <stdio.h>#include <assert.h>#include <time.h>#include "mpc_dec.h"class MPC_reader_impl : public MPC_reader{public: MPC_reader_impl(FILE * p_file,bool p_seekable) : m_file(p_file), m_seekable(p_seekable) { fseek(m_file,0,SEEK_END); m_size = ftell(m_file); fseek(m_file,0,SEEK_SET); } mpc_int32_t read ( void *ptr, mpc_int32_t size ) {return fread(ptr,1,size,m_file);} bool seek ( mpc_int32_t offset ) {return m_seekable ? !fseek(m_file,offset,SEEK_SET) : false;} mpc_int32_t tell () {return ftell(m_file);} mpc_int32_t get_size () {return m_size;} bool canseek() {return m_seekable;}private: FILE * m_file; long m_size; bool m_seekable;};#define WFX_SIZE (2+2+4+4+2+2)#ifdef MPC_FIXED_POINTstatic int shift_signed(MPC_SAMPLE_FORMAT val,int shift){ if (shift>0) val <<= shift; else if (shift<0) val >>= -shift; return (int)val;}#endifclass WavWriter{public: WavWriter(FILE * p_output,unsigned p_nch,unsigned p_bps,unsigned p_srate) : m_file(p_output), m_nch(p_nch), m_bps(p_bps), m_srate(p_srate) { assert(m_bps == 16 || m_bps == 24); WriteRaw("RIFF",4); WriteDword(0);//fix this in destructor WriteRaw("WAVE",4); WriteRaw("fmt ",4); WriteDword(WFX_SIZE); WriteWord(1);//WAVE_FORMAT_PCM WriteWord(m_nch); WriteDword(m_srate); WriteDword(m_srate*m_nch*(m_bps>>3)); WriteWord(m_nch*(m_bps>>3)); WriteWord(m_bps); /* WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; */ WriteRaw("data",4); WriteDword(0);//fix this in destructor m_data_bytes_written = 0; } bool WriteSamples(const MPC_SAMPLE_FORMAT * p_buffer,unsigned p_size) { unsigned n; int clip_min = - 1<<(m_bps-1), clip_max = (1<<(m_bps-1)) - 1, float_scale = 1<<(m_bps-1); for(n=0;n<p_size;n++) { int val;#ifdef MPC_FIXED_POINT val = shift_signed( p_buffer[n], m_bps - MPC_FIXED_POINT_SCALE_SHIFT ) ;#else val = (int)( p_buffer[n] * float_scale );#endif if (val<clip_min) val = clip_min; else if (val>clip_max) val = clip_max; if (!WriteInt(val,m_bps)) return false; } m_data_bytes_written += p_size * (m_bps >> 3); return true; } ~WavWriter() { if (m_data_bytes_written&1) { char blah = 0; WriteRaw(&blah,1); m_data_bytes_written++; } Seek(4); WriteDword((unsigned long)(m_data_bytes_written + 4+8+WFX_SIZE+8)); Seek(8+4+8+WFX_SIZE+4); WriteDword(m_data_bytes_written); } private: bool Seek(unsigned p_offset) { return !fseek(m_file,p_offset,SEEK_SET); } bool WriteRaw(const void * p_buffer,unsigned p_bytes) { return fwrite(p_buffer,1,p_bytes,m_file) == p_bytes; } bool WriteDword(unsigned long p_val) {return WriteInt(p_val,32);} bool WriteWord(unsigned short p_val) {return WriteInt(p_val,16);} bool WriteInt(unsigned int p_val,unsigned p_width_bits)//write a little-endian number properly { unsigned char temp; unsigned shift = 0; assert((p_width_bits % 8) == 0); do { temp = (unsigned char)( (p_val >> shift) & 0xFF ); if (!WriteRaw(&temp,1)) return false; shift += 8; } while(shift < p_width_bits); return true; } unsigned m_nch,m_bps,m_srate; FILE * m_file; unsigned m_data_bytes_written;};static void usage(const char * exename){ printf("Usage: %s <infile.mpc> [<outfile.wav>]\nIf <outfile.wav> is not specified, decoder will run in benchmark mode.\n",exename);}int main(int argc,char** argv){ if (argc != 2 && argc != 3) { if (argc>0) usage(argv[0]); return 0; } FILE * input = fopen(argv[1],"rb"); FILE * output = 0; if (input == 0) { usage(argv[0]); printf("Error opening input file: \"%s\"\n",argv[1]); return 0; } if (argc == 3) { output = fopen(argv[2],"wb"); if (output == 0) { fclose(input); usage(argv[0]); printf("Error opening output file: \"%s\"\n",argv[2]); return 0; } } { MPC_reader_impl reader(input,true); StreamInfo info; if (info.ReadStreamInfo(&reader) != ERROR_CODE_OK) { printf("Not a valid musepack file: \"%s\"\n",argv[1]); } else { //todo, print some info MPC_decoder decoder(&reader); if (!decoder.Initialize(&info)) { printf("Error initializing decoder.\n",argv[1]); } else { printf("Decoding from:\n%s\nTo:\n%s\n",argv[1],output ? argv[2] : "N/A"); WavWriter * wavwriter = output ? new WavWriter(output,2,16,info.simple.SampleFreq) : 0; MPC_SAMPLE_FORMAT sample_buffer[MPC_decoder::DecodeBufferLength]; clock_t begin, end; begin = clock(); unsigned total_samples = 0; bool successful = false; for(;;) { unsigned status = decoder.Decode(sample_buffer); if (status == (unsigned)(-1)) { //decode error printf("Error decoding file.\n"); break; } else if (status == 0) //EOF { successful = true; break; } else//status>0 { total_samples += status; if (wavwriter) { if (!wavwriter->WriteSamples(sample_buffer,status * /* stereo */ 2 )) { printf("Write error.\n"); break; } } } } end = clock(); if (wavwriter) delete wavwriter; if (successful) { printf("\nFinished.\nTotal samples decoded: %u.\n",total_samples); unsigned ms = (end - begin) * 1000 / CLOCKS_PER_SEC; unsigned ratio = (unsigned) ( (double) total_samples / (double)info.simple.SampleFreq / ((double)ms / 1000.0 ) * 100.0); printf("Time: %u ms (%u.%02ux).\n",ms,ratio/100,ratio%100); } } } } fclose(input); if (output) fclose(output); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -