added audio
[laserbrain_demo] / src / audio / ovstream.cc
1 #include <stdio.h>
2 #include <assert.h>
3 #include "logger.h"
4 #include "ovstream.h"
5
6 OggVorbisStream::OggVorbisStream()
7 {
8         vfopen = false;
9
10         pthread_mutex_init(&vflock, 0);
11 }
12
13 OggVorbisStream::~OggVorbisStream()
14 {
15         close();
16 }
17
18 bool OggVorbisStream::open(const char *fname)
19 {
20         close();
21
22         pthread_mutex_lock(&vflock);
23
24         if(ov_fopen(fname, &vf) != 0) {
25                 error_log("failed to open ogg/vorbis stream: %s\n", fname ? fname : "<not found>");
26                 pthread_mutex_unlock(&vflock);
27                 return false;
28         }
29
30         vfopen = true;
31         pthread_mutex_unlock(&vflock);
32         return true;
33 }
34
35 void OggVorbisStream::close()
36 {
37         pthread_mutex_lock(&vflock);
38         if(vfopen) {
39                 ov_clear(&vf);
40                 vfopen = false;
41         }
42         pthread_mutex_unlock(&vflock);
43 }
44
45 void OggVorbisStream::rewind()
46 {
47         pthread_mutex_lock(&vflock);
48         if(vfopen) {
49                 ov_raw_seek(&vf, 0);
50         }
51         pthread_mutex_unlock(&vflock);
52 }
53
54 bool OggVorbisStream::more_samples(AudioStreamBuffer *buf)
55 {
56         pthread_mutex_lock(&vflock);
57
58         vorbis_info *vinfo = ov_info(&vf, -1);
59         buf->channels = vinfo->channels;
60         buf->sample_rate = vinfo->rate;
61         assert(buf->channels == 2);
62         assert(buf->sample_rate == 44100);
63
64         long bufsz = AUDIO_BUFFER_BYTES;
65         long total_read = 0;
66         while(total_read < bufsz) {
67                 int bitstream;
68                 long rd = ov_read(&vf, buf->samples + total_read, bufsz - total_read, 0, 2, 1, &bitstream);
69
70                 if(!rd) {
71                         bufsz = total_read;
72                 } else {
73                         total_read += rd;
74                 }
75         }
76
77         if(!total_read) {
78                 buf->num_samples = 0;
79                 pthread_mutex_unlock(&vflock);
80                 return false;
81         }
82
83         buf->num_samples = bufsz / vinfo->channels / 2;
84         pthread_mutex_unlock(&vflock);
85         return true;
86 }