15 MemorySource(const void *d, unsigned l): data(d), length(l), pos(0) { }
18 size_t memory_read(void *ptr, size_t size, size_t nmemb, void *src)
20 MemorySource &memsrc = *reinterpret_cast<MemorySource *>(src);
21 unsigned len = min(size*nmemb, memsrc.length-memsrc.pos);
22 memcpy(ptr, reinterpret_cast<const char *>(memsrc.data)+memsrc.pos, len);
28 int memory_seek(void *src, ogg_int64_t offset, int whence)
30 MemorySource &memsrc = *reinterpret_cast<MemorySource *>(src);
33 else if(whence==SEEK_CUR)
35 else if(whence==SEEK_END)
36 memsrc.pos = memsrc.length-offset;
37 memsrc.pos = min(memsrc.pos, memsrc.length);
42 int memory_close(void *src)
44 delete reinterpret_cast<MemorySource *>(src);
48 long memory_tell(void *src)
50 MemorySource &memsrc = *reinterpret_cast<MemorySource *>(src);
54 ov_callbacks memory_callbacks=
71 ovfile.datasource = 0;
81 void Sound::open_file(const string &fn)
84 throw logic_error("Sound has already been opened");
85 if(ov_fopen(const_cast<char *>(fn.c_str()), &ovfile)<0)
86 throw runtime_error("Could not open ogg vorbis file "+fn);
91 void Sound::open_memory(const void *d, unsigned len)
94 throw logic_error("Sound has already been opened");
96 MemorySource *src = new MemorySource(d, len);
97 if(ov_open_callbacks(src, &ovfile, 0, 0, memory_callbacks)<0)
100 throw runtime_error("Could not open ogg vorbis memory block");
106 void Sound::load_data()
109 throw logic_error("Data has already been loaded");
111 size = ov_pcm_total(&ovfile, 0)*4;
112 char *dptr = new char[size];
114 while(unsigned len = read(dptr+pos, size-pos))
121 void Sound::load_file(const std::string &fn)
128 void Sound::load_memory(const void *d, unsigned len)
137 if(ovfile.datasource)
146 ov_pcm_seek(&ovfile, 0);
149 unsigned Sound::read(char *buf, unsigned len)
153 len = min(len, size-read_pos);
154 memcpy(buf, data+read_pos, len);
158 else if(ovfile.datasource)
161 int res = ov_read(&ovfile, buf, len, 0, 2, 1, §ion);
163 throw runtime_error("Error reading ogg vorbis file");
169 throw logic_error("No data available");
172 const char *Sound::get_data() const
175 throw logic_error("Data has not been loaded");
179 void Sound::open_common()
184 vorbis_info *info = ov_info(&ovfile, -1);
186 switch(info->channels)
188 case 1: format = MONO16; break;
189 case 2: format = STEREO16; break;
190 default: throw runtime_error("Unsupported number of channels");