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