Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/lynx/sound/Stereo_Buffer.cpp
2 views
1
2
// Blip_Buffer 0.3.0. http://www.slack.net/~ant/nes-emu/
3
4
#include "Stereo_Buffer.h"
5
6
/* Library Copyright (C) 2004 Shay Green. Blip_Buffer is free software;
7
you can redistribute it and/or modify it under the terms of the GNU
8
General Public License as published by the Free Software Foundation;
9
either version 2 of the License, or (at your option) any later version.
10
Stereo_Buffer is distributed in the hope that it will be useful, but
11
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
for more details. You should have received a copy of the GNU General
14
Public License along with Stereo_Buffer; if not, write to the Free Software
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
17
Stereo_Buffer::Stereo_Buffer() {
18
stereo_added = false;
19
was_stereo = false;
20
}
21
22
Stereo_Buffer::~Stereo_Buffer() {
23
}
24
25
bool Stereo_Buffer::set_sample_rate( long rate, int msec )
26
{
27
for ( int i = 0; i < buf_count; i++ ) {
28
if ( bufs [i].set_sample_rate( rate, msec ) )
29
{
30
return false;
31
}
32
}
33
34
return true;
35
}
36
37
void Stereo_Buffer::clock_rate( long rate )
38
{
39
for ( int i = 0; i < buf_count; i++ )
40
bufs [i].clock_rate( rate );
41
}
42
43
void Stereo_Buffer::bass_freq( int bass )
44
{
45
for ( unsigned i = 0; i < buf_count; i++ )
46
bufs [i].bass_freq( bass );
47
}
48
49
void Stereo_Buffer::clear()
50
{
51
stereo_added = false;
52
was_stereo = false;
53
for ( int i = 0; i < buf_count; i++ )
54
bufs [i].clear();
55
}
56
57
void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo )
58
{
59
for ( unsigned i = 0; i < buf_count; i++ )
60
{
61
bufs [i].end_frame( clock_count );
62
}
63
stereo_added |= stereo;
64
}
65
66
67
68
long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
69
{
70
long count = bufs [0].samples_avail();
71
if ( count > max_samples / 2 )
72
count = max_samples / 2;
73
if ( count )
74
{
75
if ( stereo_added || was_stereo )
76
{
77
mix_stereo( out, count );
78
79
bufs [0].remove_samples( count );
80
bufs [1].remove_samples( count );
81
bufs [2].remove_samples( count );
82
}
83
else
84
{
85
mix_mono( out, count );
86
87
bufs [0].remove_samples( count );
88
89
bufs [1].remove_silence( count );
90
bufs [2].remove_silence( count );
91
}
92
93
// to do: this might miss opportunities for optimization
94
if ( !bufs [0].samples_avail() ) {
95
was_stereo = stereo_added;
96
stereo_added = false;
97
}
98
}
99
100
return count * 2;
101
}
102
103
void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
104
{
105
Blip_Reader l_left;
106
Blip_Reader l_right;
107
Blip_Reader l_center;
108
109
l_left.begin( bufs [1] );
110
l_right.begin( bufs [2] );
111
int bass = l_center.begin( bufs [0] );
112
113
while ( count-- )
114
{
115
int c = l_center.read();
116
out [0] = c + l_left.read();
117
out [1] = c + l_right.read();
118
out += 2;
119
120
l_center.next( bass );
121
l_left.next( bass );
122
l_right.next( bass );
123
}
124
125
l_center.end( bufs [0] );
126
l_right.end( bufs [2] );
127
l_left.end( bufs [1] );
128
}
129
130
void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
131
{
132
Blip_Reader in;
133
int bass = in.begin( bufs [0] );
134
135
while ( count-- )
136
{
137
int sample = in.read();
138
out [0] = sample;
139
out [1] = sample;
140
out += 2;
141
in.next( bass );
142
}
143
144
in.end( bufs [0] );
145
}
146
147
148