nuclear@55: #include nuclear@55: #include nuclear@53: #include "ovstream.h" nuclear@53: nuclear@53: OggVorbisStream::OggVorbisStream() nuclear@53: { nuclear@55: vfopen = false; nuclear@53: } nuclear@53: nuclear@53: OggVorbisStream::~OggVorbisStream() nuclear@53: { nuclear@55: close(); nuclear@53: } nuclear@53: nuclear@55: bool OggVorbisStream::open(const char *fname) nuclear@53: { nuclear@55: close(); nuclear@55: nuclear@55: std::lock_guard lock(vflock); nuclear@55: nuclear@55: printf("opening ogg/vorbis stream: %s\n", fname ? fname : ""); nuclear@55: nuclear@55: if(!fname || ov_fopen(fname, &vf) != 0) { nuclear@55: fprintf(stderr, "failed to open ogg/vorbis stream: %s\n", fname ? fname : ""); nuclear@55: return false; nuclear@55: } nuclear@55: vfopen = true; nuclear@55: return true; nuclear@53: } nuclear@55: nuclear@55: void OggVorbisStream::close() nuclear@55: { nuclear@55: std::lock_guard lock(vflock); nuclear@55: nuclear@55: if(vfopen) { nuclear@55: ov_clear(&vf); nuclear@55: vfopen = false; nuclear@55: } nuclear@55: } nuclear@55: nuclear@55: void OggVorbisStream::rewind() nuclear@55: { nuclear@55: std::lock_guard lock(vflock); nuclear@55: nuclear@55: if(vfopen) { nuclear@55: ov_raw_seek(&vf, 0); nuclear@55: } nuclear@55: } nuclear@55: nuclear@55: bool OggVorbisStream::more_samples(AudioStreamBuffer *buf) nuclear@55: { nuclear@55: std::lock_guard lock(vflock); nuclear@55: nuclear@55: vorbis_info *vinfo = ov_info(&vf, -1); nuclear@55: buf->channels = vinfo->channels; nuclear@55: buf->sample_rate = vinfo->rate; nuclear@55: nuclear@55: assert(buf->channels == 2); nuclear@55: assert(buf->sample_rate == 44100); nuclear@55: nuclear@55: long bufsz = AUDIO_BUFFER_BYTES; nuclear@55: long total_read = 0; nuclear@55: while(total_read < bufsz) { nuclear@55: int bitstream; nuclear@56: long rd = ov_read(&vf, buf->samples + total_read, bufsz - total_read, 0, 2, 1, &bitstream); nuclear@55: if(!rd) { nuclear@55: bufsz = total_read; nuclear@55: } else { nuclear@55: total_read += rd; nuclear@55: } nuclear@55: } nuclear@55: nuclear@55: if(!total_read) { nuclear@55: buf->num_samples = 0; nuclear@55: return false; nuclear@55: } nuclear@55: nuclear@55: buf->num_samples = bufsz / vinfo->channels / 2; nuclear@55: return true; nuclear@55: }