comparison src/Input/console/Dual_Resampler.cxx @ 0:13389e613d67 trunk

[svn] - initial import of audacious-plugins tree (lots to do)
author nenolod
date Mon, 18 Sep 2006 01:11:49 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13389e613d67
1
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
3
4 #include "Dual_Resampler.h"
5
6 #include <stdlib.h>
7 #include <string.h>
8
9 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
10 can redistribute it and/or modify it under the terms of the GNU Lesser
11 General Public License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version. This
13 module is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16 more details. You should have received a copy of the GNU Lesser General
17 Public License along with this module; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
19
20 #include BLARGG_SOURCE_BEGIN
21
22 const unsigned resampler_extra = 256;
23
24 Dual_Resampler::Dual_Resampler()
25 {
26 }
27
28 Dual_Resampler::~Dual_Resampler()
29 {
30 }
31
32 blargg_err_t Dual_Resampler::resize( int pairs )
33 {
34 BLARGG_RETURN_ERR( sample_buf.resize( pairs * 2 ) );
35 buf_pos = sample_buf.size();
36 oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
37 return resampler.buffer_size( oversamples_per_frame + resampler_extra );
38 }
39
40 void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, sample_t* out )
41 {
42 long pair_count = sample_buf.size() >> 1;
43 blip_time_t blip_time = blip_buf.count_clocks( pair_count );
44 int sample_count = oversamples_per_frame - resampler.written();
45
46 int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
47 assert( unsigned (new_count - sample_count) < resampler_extra );
48
49 blip_buf.end_frame( blip_time );
50 assert( blip_buf.samples_avail() == pair_count );
51
52 resampler.write( new_count );
53
54 long count = resampler.read( sample_buf.begin(), sample_buf.size() );
55 assert( count == (long) sample_buf.size() );
56
57 mix_samples( blip_buf, out );
58 blip_buf.remove_samples( pair_count );
59 }
60
61 void Dual_Resampler::play( long count, sample_t* out, Blip_Buffer& blip_buf )
62 {
63 // empty extra buffer
64 long remain = sample_buf.size() - buf_pos;
65 if ( remain )
66 {
67 if ( remain > count )
68 remain = count;
69 count -= remain;
70 memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
71 out += remain;
72 buf_pos += remain;
73 }
74
75 // entire frames
76 while ( count >= (long) sample_buf.size() )
77 {
78 play_frame_( blip_buf, out );
79 out += sample_buf.size();
80 count -= sample_buf.size();
81 }
82
83 // extra
84 if ( count )
85 {
86 play_frame_( blip_buf, sample_buf.begin() );
87 buf_pos = count;
88 memcpy( out, sample_buf.begin(), count * sizeof *out );
89 out += count;
90 }
91 }
92
93 #include BLARGG_ENABLE_OPTIMIZER
94
95 void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, sample_t* out )
96 {
97 Blip_Reader sn;
98 int bass = sn.begin( blip_buf );
99 const sample_t* in = sample_buf.begin();
100
101 for ( int n = sample_buf.size() >> 1; n--; )
102 {
103 int s = sn.read();
104 long l = (long) in [0] * 2 + s;
105 sn.next( bass );
106 long r = in [1];
107 if ( (BOOST::int16_t) l != l )
108 l = 0x7FFF - (l >> 24);
109 r = r * 2 + s;
110 in += 2;
111 out [0] = l;
112 out [1] = r;
113 out += 2;
114 if ( (BOOST::int16_t) r != r )
115 out [-1] = 0x7FFF - (r >> 24);
116 }
117
118 sn.end( blip_buf );
119 }
120