在完全不知道MP3格式和libmpg123如何使用的情况下,竟然转换出了可以“听清楚”的Wave文件,惊喜啊~~
通过foobar2000转换和播放验证,未发现错误,奇迹啊~~代码如下,完成的练习代码,表找错了,能工作就好啊~~
1
2 #include <iostream>
3 #include <fstream>
4
5 #include "mpg123.h"
6
7 struct WAVE_HEADER
8 {
9 char riff_sig[4]; // 'RIFF'
10 long waveform_chunk_size; // 8
11 char wave_sig[4]; // 'WAVE'
12 char format_sig[4]; // 'fmt ' (notice space after)
13 long format_chunk_size; // 16;
14 short format_tag; // WAVE_FORMAT_PCM
15 short channels; // # of channels
16 long sample_rate; // sampling rate
17 long bytes_per_sec; // bytes per second
18 short block_align; // sample block alignment
19 short bits_per_sample; // bits per second
20 char data_sig[4]; // 'data'
21 long data_size; // size of waveform data
22 };
23
24 void InitWaveHeader(WAVE_HEADER& header, int channels, int sample, int size)
25 {
26 memset(&header, 0, sizeof(header));
27 memcpy(&header.riff_sig, "RIFF", 4);
28 header.waveform_chunk_size = 8;
29 memcpy(&header.wave_sig, "WAVE", 4);
30 memcpy(&header.format_sig, "fmt ", 4);
31 header.format_chunk_size = 16;
32 header.format_tag = 1;
33 header.channels = channels;
34 header.sample_rate = sample;
35 header.bytes_per_sec = sample * channels * (16 / 8);
36 header.block_align = 2 * channels;
37 header.bits_per_sample = 16;
38 memcpy(&header.data_sig, "data", 4);
39 header.data_size = size;
40 }
41
42 std::ofstream ofs;
43
44 int OpenWaveFile()
45 {
46 ofs.open(".\\test.wav", std::ios::out | std::ios::binary);
47 return ofs.is_open() ? 0 : -1;
48 }
49
50 int UpdateWaveHeader(const WAVE_HEADER& header, bool create)
51 {
52 if(!create)
53 ofs.seekp(0, std::ios::beg);
54 ofs.write((char*)&header, sizeof(header));
55 return ofs.good() ? 0 : -1;
56 }
57
58 int AppendWaveData(const char* data, size_t size)
59 {
60 ofs.write(data, size);
61 return ofs.good() ? 0 : -1;
62 }
63
64 void CloseWaveFile()
65 {
66 ofs.close();
67 }
68
69 int main()
70 {
71 int ret = -1;
72
73 OpenWaveFile();
74
75 while(true)
76 {
77 ret = mpg123_init();
78 if(ret != MPG123_OK)
79 break;
80
81 char ** ch = mpg123_decoders();
82
83 mpg123_pars* mp = mpg123_new_pars(&ret);
84 if(mp == NULL || ret != MPG123_OK)
85 break;
86 mpg123_delete_pars(mp);
87 mpg123_handle *h = mpg123_new("auto", &ret);
88 if(h == NULL)
89 break;
90 ret = mpg123_open(h, ".\\orgrimmar_intro-moment.mp3");
91 if(ret != MPG123_OK)
92 break;
93
94 off_t framenum = mpg123_seek_frame(h, 0, SEEK_SET);
95
96 WAVE_HEADER header;
97 unsigned char *audio = NULL;
98 size_t bytes = 0;
99 int mc = mpg123_decode_frame(h, &framenum, &audio, &bytes);
100 if(mc == MPG123_NEW_FORMAT)
101 {
102 long rate = 0;
103 int channel = 0, format = 0;
104 ret = mpg123_getformat(h, &rate, &channel, &format);
105 if(ret != MPG123_OK)
106 break;
107 mpg123_frameinfo fi;
108 ret = mpg123_info(h, &fi);
109 if(ret != MPG123_OK)
110 break;
111
112 InitWaveHeader(header, channel, rate, 0);
113 }
114 header.data_size = 0;
115
116 UpdateWaveHeader(header, true);
117
118 ++ framenum;
119 mc = mpg123_decode_frame(h, &framenum, &audio, &bytes);
120 while(mc == MPG123_OK && bytes > 0)
121 {
122 header.data_size += bytes;
123
124 AppendWaveData((const char*)audio, bytes);
125
126 mc = mpg123_decode_frame(h, &framenum, &audio, &bytes);
127 ++ framenum;
128 }
129
130 mpg123_delete(h);
131 mpg123_exit();
132
133 header.waveform_chunk_size = header.data_size + 36;
134
135 UpdateWaveHeader(header, false);
136
137 break;
138 }
139
140 if(ret != MPG123_OK)
141 {
142 std::cout << "error : " << mpg123_plain_strerror(ret) << std::endl;
143 return -1;
144 }
145
146 CloseWaveFile();
147
148 return 0;
149 }
150
收工,睡觉,心满意足~~:)