Mercurial > otakunoraifu
comparison music2/koedec_ogg.cc @ 52:15a18fbe6f21
* Known bugs added to the README
* Code cleaning (0 -> NULL when needed, indentation, spaces, ...)
author | thib |
---|---|
date | Sat, 18 Apr 2009 18:35:39 +0000 |
parents | 53a311ea8289 |
children | 4416cfac86ae |
comparison
equal
deleted
inserted
replaced
51:cbb301016a4e | 52:15a18fbe6f21 |
---|---|
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #include<stdio.h> | 28 #include <stdio.h> |
29 #include<string.h> | 29 #include <string.h> |
30 #include<stdlib.h> | 30 #include <stdlib.h> |
31 #include"music.h" | 31 #include "music.h" |
32 #include"wavfile.h" | 32 #include "wavfile.h" |
33 | 33 |
34 extern int is_koe_ogg(char* head); | 34 extern int is_koe_ogg(char* head); |
35 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len); | 35 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len); |
36 | 36 |
37 extern int is_koe_ogg(char* head) { | 37 extern int is_koe_ogg(char* head) { |
43 } | 43 } |
44 | 44 |
45 #if HAVE_LIBVORBISFILE || HAVE_LIBVORBISIDEC | 45 #if HAVE_LIBVORBISFILE || HAVE_LIBVORBISIDEC |
46 | 46 |
47 #if HAVE_LIBVORBISFILE | 47 #if HAVE_LIBVORBISFILE |
48 #include<vorbis/vorbisfile.h> | 48 #include <vorbis/vorbisfile.h> |
49 #else /* HAVE_LIBVORBISIDEC */ | 49 #else /* HAVE_LIBVORBISIDEC */ |
50 #include<tremor/ivorbiscodec.h> | 50 #include <tremor/ivorbiscodec.h> |
51 #include<tremor/ivorbisfile.h> | 51 #include <tremor/ivorbisfile.h> |
52 #endif | 52 #endif |
53 | 53 |
54 #define INITSIZE 65536 | 54 #define INITSIZE 65536 |
55 | 55 |
56 static int cur_size = 0; | 56 static int cur_size = 0; |
57 static char* out = 0; | 57 static char* out = NULL; |
58 static void Resize(void) { | 58 static void Resize(void) { |
59 char* new_out = (char*)realloc(out, cur_size+INITSIZE); | 59 char* new_out = (char*)realloc(out, cur_size+INITSIZE); |
60 if (new_out == 0) { | 60 if (new_out == NULL) { |
61 new_out = (char*)malloc(cur_size+INITSIZE); | 61 new_out = (char*)malloc(cur_size+INITSIZE); |
62 memcpy(new_out, out, cur_size); | 62 memcpy(new_out, out, cur_size); |
63 free(out); | 63 free(out); |
64 } | 64 } |
65 out = new_out; | 65 out = new_out; |
69 struct OggInfo { | 69 struct OggInfo { |
70 FILE* stream; | 70 FILE* stream; |
71 int length; | 71 int length; |
72 int offset; | 72 int offset; |
73 }; | 73 }; |
74 | |
74 /* ogg stream 読み込み用の dummy callback */ | 75 /* ogg stream 読み込み用の dummy callback */ |
75 static size_t ogg_readfunc(void* ptr, size_t size, size_t nmemb, void* datasource) { | 76 static size_t ogg_readfunc(void* ptr, size_t size, size_t nmemb, void* datasource) { |
76 OggInfo* info = (OggInfo*)datasource; | 77 OggInfo* info = (OggInfo*)datasource; |
77 int pt = ftell(info->stream) - info->offset; | 78 int pt = ftell(info->stream) - info->offset; |
78 if (pt+size*nmemb > info->length) { | 79 if (pt+size*nmemb > info->length) { |
79 nmemb = (info->length-pt) / size; | 80 nmemb = (info->length-pt) / size; |
80 } | 81 } |
81 return fread(ptr, size, nmemb, info->stream); | 82 return fread(ptr, size, nmemb, info->stream); |
82 } | 83 } |
84 | |
83 static int ogg_seekfunc(void* datasource, ogg_int64_t new_offset, int whence) { | 85 static int ogg_seekfunc(void* datasource, ogg_int64_t new_offset, int whence) { |
84 int pt; | 86 int pt; |
85 OggInfo* info = (OggInfo*)datasource; | 87 OggInfo* info = (OggInfo*)datasource; |
86 if (whence == SEEK_SET) pt = info->offset + new_offset; | 88 if (whence == SEEK_SET) pt = info->offset + new_offset; |
87 else if (whence == SEEK_CUR) pt = ftell(info->stream) + new_offset; | 89 else if (whence == SEEK_CUR) pt = ftell(info->stream) + new_offset; |
88 else if (whence == SEEK_END) pt = info->offset + info->length + new_offset; | 90 else if (whence == SEEK_END) pt = info->offset + info->length + new_offset; |
89 int r = fseek(info->stream, pt, 0); | 91 int r = fseek(info->stream, pt, SEEK_SET); |
90 return r; | 92 return r; |
91 } | 93 } |
94 | |
92 static long ogg_tellfunc(void* datasource) { | 95 static long ogg_tellfunc(void* datasource) { |
93 OggInfo* info = (OggInfo*)datasource; | 96 OggInfo* info = (OggInfo*)datasource; |
94 int pos = ftell(info->stream); | 97 int pos = ftell(info->stream); |
95 if (pos == -1) return -1; | 98 if (pos == -1) return -1; |
96 return pos-info->offset; | 99 return pos-info->offset; |
97 } | 100 } |
101 | |
98 static int ogg_closefunc(void* datasource) { | 102 static int ogg_closefunc(void* datasource) { |
99 return 0; | 103 return 0; |
100 } | 104 } |
101 | 105 |
102 static int fseek_wrap(FILE *f,ogg_int64_t off,int whence){ | 106 static int fseek_wrap(FILE *f,ogg_int64_t off,int whence){ |
103 if(f==NULL)return(-1); | 107 if (f == NULL) return(-1); |
104 return fseek(f,off,whence); | 108 return fseek(f, off, whence); |
105 } | 109 } |
106 | 110 |
107 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len) { | 111 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len) { |
108 if (info.stream == 0) return 0; | 112 if (info.stream == NULL) return NULL; |
109 // Voice ファイルを直接指定すると全ストリームを再生してしまうので | 113 // Voice ファイルを直接指定すると全ストリームを再生してしまうので |
110 // 必要な部分だけ切り出して callback 経由で帰す | 114 // 必要な部分だけ切り出して callback 経由で帰す |
111 fseek(info.stream, info.offset, 0); | 115 fseek(info.stream, info.offset, SEEK_SET); |
112 | 116 |
113 ov_callbacks callback; | 117 ov_callbacks callback; |
114 callback.read_func = &ogg_readfunc; | 118 callback.read_func = &ogg_readfunc; |
115 callback.seek_func = &ogg_seekfunc; | 119 callback.seek_func = &ogg_seekfunc; |
116 callback.close_func = &ogg_closefunc; | 120 callback.close_func = &ogg_closefunc; |
123 | 127 |
124 OggVorbis_File vf; | 128 OggVorbis_File vf; |
125 int r = ov_open_callbacks((void*)&oinfo, &vf, 0, 0, callback); | 129 int r = ov_open_callbacks((void*)&oinfo, &vf, 0, 0, callback); |
126 if (r != 0) { | 130 if (r != 0) { |
127 fprintf(stderr,"ogg stream err: %d\n",r); | 131 fprintf(stderr,"ogg stream err: %d\n",r); |
128 return 0; | 132 return NULL; |
129 } | 133 } |
130 vorbis_info* vinfo = ov_info(&vf, 0); | 134 vorbis_info* vinfo = ov_info(&vf, 0); |
131 info.rate = vinfo->rate; | 135 info.rate = vinfo->rate; |
132 int channels = vinfo->channels; | 136 int channels = vinfo->channels; |
133 | 137 |
150 *dest_len = cur; // うまくコンバートできてるのかなあ…… | 154 *dest_len = cur; // うまくコンバートできてるのかなあ…… |
151 const char* header = MakeWavHeader(info.rate, channels, 2, cur); | 155 const char* header = MakeWavHeader(info.rate, channels, 2, cur); |
152 memcpy(out, header, 0x2c); | 156 memcpy(out, header, 0x2c); |
153 | 157 |
154 char* ret = out; | 158 char* ret = out; |
155 out = 0; | 159 out = NULL; |
156 | 160 |
157 return ret; | 161 return ret; |
158 } | 162 } |
163 | |
159 struct OggFILE_impl { | 164 struct OggFILE_impl { |
160 OggVorbis_File vf; | 165 OggVorbis_File vf; |
161 ov_callbacks callback; | 166 ov_callbacks callback; |
162 OggInfo oinfo; | 167 OggInfo oinfo; |
163 OggFILE_impl(FILE*, int); | 168 OggFILE_impl(FILE*, int); |
176 OggFILE::OggFILE(FILE* stream, int len) { | 181 OggFILE::OggFILE(FILE* stream, int len) { |
177 pimpl = new OggFILE_impl(stream, len); | 182 pimpl = new OggFILE_impl(stream, len); |
178 int r = ov_open_callbacks( (void*)&(pimpl->oinfo), &(pimpl->vf), 0, 0, pimpl->callback); | 183 int r = ov_open_callbacks( (void*)&(pimpl->oinfo), &(pimpl->vf), 0, 0, pimpl->callback); |
179 if (r != 0) { | 184 if (r != 0) { |
180 delete pimpl; | 185 delete pimpl; |
181 pimpl = 0; | 186 pimpl = NULL; |
182 return; | 187 return; |
183 } | 188 } |
184 vorbis_info* vinfo = ov_info(&(pimpl->vf), 0); | 189 vorbis_info* vinfo = ov_info(&(pimpl->vf), 0); |
185 wavinfo.SamplingRate = vinfo->rate; | 190 wavinfo.SamplingRate = vinfo->rate; |
186 wavinfo.Channels = vinfo->channels; | 191 wavinfo.Channels = vinfo->channels; |
187 wavinfo.DataBits = 16; | 192 wavinfo.DataBits = 16; |
188 } | 193 } |
194 | |
189 OggFILE::~OggFILE() { | 195 OggFILE::~OggFILE() { |
190 if (pimpl) { | 196 if (pimpl != NULL) { |
191 ov_clear(&(pimpl->vf)); | 197 ov_clear(&(pimpl->vf)); |
192 fclose(pimpl->oinfo.stream); | 198 fclose(pimpl->oinfo.stream); |
193 delete pimpl; | 199 delete pimpl; |
194 } | 200 } |
195 } | 201 } |
202 | |
196 int OggFILE::Read(char* buf, int blksize, int blklen) { | 203 int OggFILE::Read(char* buf, int blksize, int blklen) { |
197 if (pimpl == 0) return -1; | 204 if (pimpl == NULL) return -1; |
198 #if HAVE_LIBVORBISFILE | 205 #if HAVE_LIBVORBISFILE |
199 int r = ov_read( &(pimpl->vf), buf, blksize*blklen, 0, 2, 1, NULL); | 206 int r = ov_read( &(pimpl->vf), buf, blksize*blklen, 0, 2, 1, NULL); |
200 #else /* HAVE_LIBVORBISIDEC */ | 207 #else /* HAVE_LIBVORBISIDEC */ |
201 int r = ov_read( &(pimpl->vf), buf, blksize*blklen, NULL); | 208 int r = ov_read( &(pimpl->vf), buf, blksize*blklen, NULL); |
202 #endif | 209 #endif |
212 if (dr <= 0) break; | 219 if (dr <= 0) break; |
213 r += dr; | 220 r += dr; |
214 } | 221 } |
215 return r / blksize; | 222 return r / blksize; |
216 } | 223 } |
224 | |
217 void OggFILE::Seek(int count) { | 225 void OggFILE::Seek(int count) { |
218 ov_pcm_seek(&(pimpl->vf), count); | 226 ov_pcm_seek(&(pimpl->vf), count); |
219 return; | 227 return; |
220 } | 228 } |
229 | |
221 #else | 230 #else |
222 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len) { | 231 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len) { |
223 return 0; | 232 return NULL; |
224 } | 233 } |
225 OggFILE::OggFILE(FILE* stream, int a) {pimpl = 0;} | 234 |
235 OggFILE::OggFILE(FILE* stream, int a) {pimpl = NULL;} | |
226 OggFILE::~OggFILE(){} | 236 OggFILE::~OggFILE(){} |
227 void OggFILE::Seek(int count){} | 237 void OggFILE::Seek(int count){} |
228 int OggFILE::Read(char* buf, int blksize, int blklen){return -1;} | 238 int OggFILE::Read(char* buf, int blksize, int blklen){return -1;} |
229 #endif | 239 #endif |