nuclear@0: #include nuclear@0: #include nuclear@0: #include "datapath.h" nuclear@0: #include "logger.h" nuclear@0: #include "ovstream.h" nuclear@0: nuclear@0: OggVorbisStream::OggVorbisStream() nuclear@0: { nuclear@0: vfopen = false; nuclear@0: nuclear@0: pthread_mutex_init(&vflock, 0); nuclear@0: } nuclear@0: nuclear@0: OggVorbisStream::~OggVorbisStream() nuclear@0: { nuclear@0: close(); nuclear@0: } nuclear@0: nuclear@0: bool OggVorbisStream::open(const char *fname) nuclear@0: { nuclear@0: close(); nuclear@0: nuclear@0: pthread_mutex_lock(&vflock); nuclear@0: nuclear@0: std::string fpath = datafile_path(fname); nuclear@0: info_log("opening ogg/vorbis stream: %s -> %s\n", (fname && *fname) ? fname : "", (!fpath.empty()) ? fpath.c_str() : ""); nuclear@0: nuclear@0: if(fpath.empty() || ov_fopen(fpath.c_str(), &vf) != 0) { nuclear@0: error_log("failed to open ogg/vorbis stream: %s\n", fname ? fname : ""); nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: vfopen = true; nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void OggVorbisStream::close() nuclear@0: { nuclear@0: pthread_mutex_lock(&vflock); nuclear@0: if(vfopen) { nuclear@0: ov_clear(&vf); nuclear@0: vfopen = false; nuclear@0: } nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: } nuclear@0: nuclear@0: void OggVorbisStream::play(AUDIO_PLAYMODE mode) nuclear@0: { nuclear@0: if (vfopen) nuclear@0: { nuclear@0: AudioStream::play(mode); nuclear@0: } else { nuclear@0: error_log("failed to play audio track.\n"); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void OggVorbisStream::rewind() nuclear@0: { nuclear@0: pthread_mutex_lock(&vflock); nuclear@0: if(vfopen) { nuclear@0: ov_raw_seek(&vf, 0); nuclear@0: } nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: } nuclear@0: nuclear@0: bool OggVorbisStream::more_samples(AudioStreamBuffer *buf) nuclear@0: { nuclear@0: pthread_mutex_lock(&vflock); nuclear@0: nuclear@0: vorbis_info *vinfo = ov_info(&vf, -1); nuclear@0: buf->channels = vinfo->channels; nuclear@0: buf->sample_rate = vinfo->rate; nuclear@0: assert(buf->channels == 2); nuclear@0: assert(buf->sample_rate == 44100); nuclear@0: nuclear@0: long bufsz = AUDIO_BUFFER_BYTES; nuclear@0: long total_read = 0; nuclear@0: while(total_read < bufsz) { nuclear@0: int bitstream; nuclear@0: long rd = ov_read(&vf, buf->samples + total_read, bufsz - total_read, 0, 2, 1, &bitstream); nuclear@0: nuclear@0: if(!rd) { nuclear@0: bufsz = total_read; nuclear@0: } else { nuclear@0: total_read += rd; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(!total_read) { nuclear@0: buf->num_samples = 0; nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: buf->num_samples = bufsz / vinfo->channels / 2; nuclear@0: pthread_mutex_unlock(&vflock); nuclear@0: return true; nuclear@0: }