Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/quicknes/nes_emu/Multi_Buffer.h
2 views
1
2
// Multi-channel sound buffer interface, and basic mono and stereo buffers
3
4
// Blip_Buffer 0.4.0
5
6
#ifndef MULTI_BUFFER_H
7
#define MULTI_BUFFER_H
8
9
#include "blargg_common.h"
10
#include "Blip_Buffer.h"
11
12
// Interface to one or more Blip_Buffers mapped to one or more channels
13
// consisting of left, center, and right buffers.
14
class Multi_Buffer {
15
public:
16
Multi_Buffer( int samples_per_frame );
17
virtual ~Multi_Buffer() { }
18
19
// Set the number of channels available
20
virtual blargg_err_t set_channel_count( int );
21
22
// Get indexed channel, from 0 to channel count - 1
23
struct channel_t {
24
Blip_Buffer* center;
25
Blip_Buffer* left;
26
Blip_Buffer* right;
27
};
28
virtual channel_t channel( int index ) = 0;
29
30
// See Blip_Buffer.h
31
virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) = 0;
32
virtual void clock_rate( long ) = 0;
33
virtual void bass_freq( int ) = 0;
34
virtual void clear() = 0;
35
long sample_rate() const;
36
37
// Length of buffer, in milliseconds
38
int length() const;
39
40
// See Blip_Buffer.h. For optimal operation, pass false for 'added_stereo'
41
// if nothing was added to the left and right buffers of any channel for
42
// this time frame.
43
virtual void end_frame( blip_time_t, bool added_stereo = true ) = 0;
44
45
// Number of samples per output frame (1 = mono, 2 = stereo)
46
int samples_per_frame() const;
47
48
// Count of changes to channel configuration. Incremented whenever
49
// a change is made to any of the Blip_Buffers for any channel.
50
unsigned channels_changed_count() { return channels_changed_count_; }
51
52
// See Blip_Buffer.h
53
virtual long read_samples( blip_sample_t*, long ) = 0;
54
virtual long samples_avail() const = 0;
55
56
protected:
57
void channels_changed() { channels_changed_count_++; }
58
private:
59
// noncopyable
60
Multi_Buffer( const Multi_Buffer& );
61
Multi_Buffer& operator = ( const Multi_Buffer& );
62
63
unsigned channels_changed_count_;
64
long sample_rate_;
65
int length_;
66
int const samples_per_frame_;
67
};
68
69
// Uses a single buffer and outputs mono samples.
70
class Mono_Buffer : public Multi_Buffer {
71
Blip_Buffer buf;
72
public:
73
Mono_Buffer();
74
~Mono_Buffer();
75
76
// Buffer used for all channels
77
Blip_Buffer* center() { return &buf; }
78
79
// See Multi_Buffer
80
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
81
void clock_rate( long );
82
void bass_freq( int );
83
void clear();
84
channel_t channel( int );
85
void end_frame( blip_time_t, bool unused = true );
86
long samples_avail() const;
87
long read_samples( blip_sample_t*, long );
88
};
89
90
// Uses three buffers (one for center) and outputs stereo sample pairs.
91
class Stereo_Buffer : public Multi_Buffer {
92
public:
93
Stereo_Buffer();
94
~Stereo_Buffer();
95
96
// Buffers used for all channels
97
Blip_Buffer* center() { return &bufs [0]; }
98
Blip_Buffer* left() { return &bufs [1]; }
99
Blip_Buffer* right() { return &bufs [2]; }
100
101
// See Multi_Buffer
102
blargg_err_t set_sample_rate( long, int msec = blip_default_length );
103
void clock_rate( long );
104
void bass_freq( int );
105
void clear();
106
channel_t channel( int index );
107
void end_frame( blip_time_t, bool added_stereo = true );
108
109
long samples_avail() const;
110
long read_samples( blip_sample_t*, long );
111
112
private:
113
enum { buf_count = 3 };
114
Blip_Buffer bufs [buf_count];
115
channel_t chan;
116
bool stereo_added;
117
bool was_stereo;
118
119
void mix_stereo( blip_sample_t*, long );
120
void mix_mono( blip_sample_t*, long );
121
};
122
123
// Silent_Buffer generates no samples, useful where no sound is wanted
124
class Silent_Buffer : public Multi_Buffer {
125
channel_t chan;
126
public:
127
Silent_Buffer();
128
129
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
130
void clock_rate( long ) { }
131
void bass_freq( int ) { }
132
void clear() { }
133
channel_t channel( int ) { return chan; }
134
void end_frame( blip_time_t, bool unused = true ) { }
135
long samples_avail() const { return 0; }
136
long read_samples( blip_sample_t*, long ) { return 0; }
137
};
138
139
140
// End of public interface
141
142
inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
143
{
144
sample_rate_ = rate;
145
length_ = msec;
146
return 0;
147
}
148
149
inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
150
{
151
return Multi_Buffer::set_sample_rate( rate, msec );
152
}
153
154
inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
155
156
inline long Stereo_Buffer::samples_avail() const { return bufs [0].samples_avail() * 2; }
157
158
inline Stereo_Buffer::channel_t Stereo_Buffer::channel( int ) { return chan; }
159
160
inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
161
162
inline int Multi_Buffer::length() const { return length_; }
163
164
inline void Mono_Buffer::clock_rate( long rate ) { buf.clock_rate( rate ); }
165
166
inline void Mono_Buffer::clear() { buf.clear(); }
167
168
inline void Mono_Buffer::bass_freq( int freq ) { buf.bass_freq( freq ); }
169
170
inline long Mono_Buffer::read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
171
172
inline long Mono_Buffer::samples_avail() const { return buf.samples_avail(); }
173
174
#endif
175
176
177