Coverage Report

Created: 2026-11-12 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/contrib/contrib-build/game-music-emu/gme/Multi_Buffer.cpp
Line
Count
Source
1
// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
2
3
#include "Multi_Buffer.h"
4
5
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
6
can redistribute it and/or modify it under the terms of the GNU Lesser
7
General Public License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version. This
9
module is distributed in the hope that it will be useful, but WITHOUT ANY
10
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12
details. You should have received a copy of the GNU Lesser General Public
13
License along with this module; if not, write to the Free Software Foundation,
14
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15
16
#include "blargg_source.h"
17
18
#ifdef BLARGG_ENABLE_OPTIMIZER
19
  #include BLARGG_ENABLE_OPTIMIZER
20
#endif
21
22
3.00k
Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
23
3.00k
{
24
3.00k
  length_ = 0;
25
3.00k
  sample_rate_ = 0;
26
3.00k
  channels_changed_count_ = 1;
27
3.00k
}
28
29
3.04k
blargg_err_t Multi_Buffer::set_channel_count( int ) { return 0; }
30
31
// Silent_Buffer
32
33
0
Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
34
0
{
35
  // TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
36
0
  chan.left   = 0;
37
0
  chan.center = 0;
38
0
  chan.right  = 0;
39
0
}
40
41
// Mono_Buffer
42
43
0
Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
44
0
{
45
0
  chan.center = &buf;
46
0
  chan.left   = &buf;
47
0
  chan.right  = &buf;
48
0
}
49
50
0
Mono_Buffer::~Mono_Buffer() { }
51
52
blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
53
0
{
54
0
  RETURN_ERR( buf.set_sample_rate( rate, msec ) );
55
0
  return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
56
0
}
57
58
// Stereo_Buffer
59
60
0
Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
61
0
{
62
0
  chan.center = &bufs [0];
63
0
  chan.left = &bufs [1];
64
0
  chan.right = &bufs [2];
65
0
}
66
67
0
Stereo_Buffer::~Stereo_Buffer() { }
68
69
blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
70
0
{
71
0
  for ( int i = 0; i < buf_count; i++ )
72
0
    RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
73
0
  return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
74
0
}
75
76
void Stereo_Buffer::clock_rate( uint32_t rate )
77
0
{
78
0
  for ( int i = 0; i < buf_count; i++ )
79
0
    bufs [i].clock_rate( rate );
80
0
}
81
82
void Stereo_Buffer::bass_freq( int bass )
83
0
{
84
0
  for ( int i = 0; i < buf_count; i++ )
85
0
    bufs [i].bass_freq( bass );
86
0
}
87
88
void Stereo_Buffer::clear()
89
0
{
90
0
  stereo_added = 0;
91
0
  was_stereo   = false;
92
0
  for ( int i = 0; i < buf_count; i++ )
93
0
    bufs [i].clear();
94
0
}
95
96
void Stereo_Buffer::end_frame( blip_time_t clock_count )
97
0
{
98
0
  stereo_added = 0;
99
0
  for ( int i = 0; i < buf_count; i++ )
100
0
  {
101
0
    stereo_added |= bufs [i].clear_modified() << i;
102
0
    bufs [i].end_frame( clock_count );
103
0
  }
104
0
}
105
106
long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
107
0
{
108
0
  require( !(count & 1) ); // count must be even
109
0
  count = (unsigned) count / 2;
110
111
0
  long avail = bufs [0].samples_avail();
112
0
  if ( count > avail )
113
0
    count = avail;
114
0
  if ( count )
115
0
  {
116
0
    int bufs_used = stereo_added | was_stereo;
117
    //debug_printf( "%X\n", bufs_used );
118
0
    if ( bufs_used <= 1 )
119
0
    {
120
0
      mix_mono( out, count );
121
0
      bufs [0].remove_samples( count );
122
0
      bufs [1].remove_silence( count );
123
0
      bufs [2].remove_silence( count );
124
0
    }
125
0
    else if ( bufs_used & 1 )
126
0
    {
127
0
      mix_stereo( out, count );
128
0
      bufs [0].remove_samples( count );
129
0
      bufs [1].remove_samples( count );
130
0
      bufs [2].remove_samples( count );
131
0
    }
132
0
    else
133
0
    {
134
0
      mix_stereo_no_center( out, count );
135
0
      bufs [0].remove_silence( count );
136
0
      bufs [1].remove_samples( count );
137
0
      bufs [2].remove_samples( count );
138
0
    }
139
140
    // to do: this might miss opportunities for optimization
141
0
    if ( !bufs [0].samples_avail() )
142
0
    {
143
0
      was_stereo   = stereo_added;
144
0
      stereo_added = 0;
145
0
    }
146
0
  }
147
148
0
  return count * 2;
149
0
}
150
151
void Stereo_Buffer::mix_stereo( blip_sample_t* out_, int32_t count )
152
0
{
153
0
  blip_sample_t* BLIP_RESTRICT out = out_;
154
0
  int const bass = BLIP_READER_BASS( bufs [1] );
155
0
  BLIP_READER_BEGIN( left, bufs [1] );
156
0
  BLIP_READER_BEGIN( right, bufs [2] );
157
0
  BLIP_READER_BEGIN( center, bufs [0] );
158
159
0
  for ( ; count; --count )
160
0
  {
161
0
    int c = BLIP_READER_READ( center );
162
0
    int32_t l = c + BLIP_READER_READ( left );
163
0
    int32_t r = c + BLIP_READER_READ( right );
164
0
    if ( (int16_t) l != l )
165
0
      l = 0x7FFF - (l >> 24);
166
167
0
    BLIP_READER_NEXT( center, bass );
168
0
    if ( (int16_t) r != r )
169
0
      r = 0x7FFF - (r >> 24);
170
171
0
    BLIP_READER_NEXT( left, bass );
172
0
    BLIP_READER_NEXT( right, bass );
173
174
0
    out [0] = l;
175
0
    out [1] = r;
176
0
    out += 2;
177
0
  }
178
179
0
  BLIP_READER_END( center, bufs [0] );
180
0
  BLIP_READER_END( right, bufs [2] );
181
0
  BLIP_READER_END( left, bufs [1] );
182
0
}
183
184
void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, int32_t count )
185
0
{
186
0
  blip_sample_t* BLIP_RESTRICT out = out_;
187
0
  int const bass = BLIP_READER_BASS( bufs [1] );
188
0
  BLIP_READER_BEGIN( left, bufs [1] );
189
0
  BLIP_READER_BEGIN( right, bufs [2] );
190
191
0
  for ( ; count; --count )
192
0
  {
193
0
    int32_t l = BLIP_READER_READ( left );
194
0
    if ( (int16_t) l != l )
195
0
      l = 0x7FFF - (l >> 24);
196
197
0
    int32_t r = BLIP_READER_READ( right );
198
0
    if ( (int16_t) r != r )
199
0
      r = 0x7FFF - (r >> 24);
200
201
0
    BLIP_READER_NEXT( left, bass );
202
0
    BLIP_READER_NEXT( right, bass );
203
204
0
    out [0] = l;
205
0
    out [1] = r;
206
0
    out += 2;
207
0
  }
208
209
0
  BLIP_READER_END( right, bufs [2] );
210
0
  BLIP_READER_END( left, bufs [1] );
211
0
}
212
213
void Stereo_Buffer::mix_mono( blip_sample_t* out_, int32_t count )
214
0
{
215
0
  blip_sample_t* BLIP_RESTRICT out = out_;
216
0
  int const bass = BLIP_READER_BASS( bufs [0] );
217
0
  BLIP_READER_BEGIN( center, bufs [0] );
218
219
0
  for ( ; count; --count )
220
0
  {
221
0
    int32_t s = BLIP_READER_READ( center );
222
0
    if ( (int16_t) s != s )
223
0
      s = 0x7FFF - (s >> 24);
224
225
0
    BLIP_READER_NEXT( center, bass );
226
0
    out [0] = s;
227
0
    out [1] = s;
228
0
    out += 2;
229
0
  }
230
231
0
  BLIP_READER_END( center, bufs [0] );
232
0
}