/src/vlc/contrib/contrib-build/game-music-emu/gme/Dual_Resampler.cpp
Line | Count | Source |
1 | | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/ |
2 | | |
3 | | #include "Dual_Resampler.h" |
4 | | |
5 | | #include <stdlib.h> |
6 | | #include <string.h> |
7 | | |
8 | | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you |
9 | | can redistribute it and/or modify it under the terms of the GNU Lesser |
10 | | General Public License as published by the Free Software Foundation; either |
11 | | version 2.1 of the License, or (at your option) any later version. This |
12 | | module is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
14 | | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 | | details. You should have received a copy of the GNU Lesser General Public |
16 | | License along with this module; if not, write to the Free Software Foundation, |
17 | | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | | |
19 | | #include "blargg_source.h" |
20 | | |
21 | | Dual_Resampler::Dual_Resampler() : |
22 | 185 | sample_buf_size(0), |
23 | 185 | oversamples_per_frame(-1), |
24 | 185 | buf_pos(-1), |
25 | 185 | resampler_size(0) |
26 | 185 | { |
27 | 185 | } |
28 | | |
29 | 185 | Dual_Resampler::~Dual_Resampler() { } |
30 | | |
31 | | blargg_err_t Dual_Resampler::reset( int pairs ) |
32 | 180 | { |
33 | | // expand allocations a bit |
34 | 180 | RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) ); |
35 | 180 | resize( pairs ); |
36 | 180 | resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2); |
37 | 180 | return resampler.buffer_size( resampler_size ); |
38 | 180 | } |
39 | | |
40 | | void Dual_Resampler::resize( int pairs ) |
41 | 264 | { |
42 | 264 | int new_sample_buf_size = pairs * 2; |
43 | 264 | if ( sample_buf_size != new_sample_buf_size ) |
44 | 219 | { |
45 | 219 | if ( (unsigned) new_sample_buf_size > sample_buf.size() ) |
46 | 0 | { |
47 | 0 | check( false ); |
48 | 0 | return; |
49 | 0 | } |
50 | 219 | sample_buf_size = new_sample_buf_size; |
51 | 219 | oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2; |
52 | 219 | clear(); |
53 | 219 | } |
54 | 264 | } |
55 | | |
56 | | void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out ) |
57 | 9.10k | { |
58 | 9.10k | long pair_count = sample_buf_size >> 1; |
59 | 9.10k | blip_time_t blip_time = blip_buf.count_clocks( pair_count ); |
60 | 9.10k | int sample_count = oversamples_per_frame - resampler.written(); |
61 | | |
62 | 9.10k | int new_count = play_frame( blip_time, sample_count, resampler.buffer() ); |
63 | 9.10k | assert( new_count < resampler_size ); |
64 | | |
65 | 9.10k | blip_buf.end_frame( blip_time ); |
66 | 9.10k | assert( blip_buf.samples_avail() == pair_count ); |
67 | | |
68 | 9.10k | resampler.write( new_count ); |
69 | | |
70 | 9.10k | #ifdef NDEBUG // Avoid warning when asserts are disabled |
71 | 9.10k | resampler.read( sample_buf.begin(), sample_buf_size ); |
72 | | #else |
73 | | long count = resampler.read( sample_buf.begin(), sample_buf_size ); |
74 | | assert( count == (long) sample_buf_size ); |
75 | | #endif |
76 | | |
77 | 9.10k | mix_samples( blip_buf, out ); |
78 | 9.10k | blip_buf.remove_samples( pair_count ); |
79 | 9.10k | } |
80 | | |
81 | | void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf ) |
82 | 6.96k | { |
83 | | // empty extra buffer |
84 | 6.96k | long remain = sample_buf_size - buf_pos; |
85 | 6.96k | if ( remain ) |
86 | 6.59k | { |
87 | 6.59k | if ( remain > count ) |
88 | 9 | remain = count; |
89 | 6.59k | count -= remain; |
90 | 6.59k | memcpy( out, &sample_buf [buf_pos], remain * sizeof *out ); |
91 | 6.59k | out += remain; |
92 | 6.59k | buf_pos += remain; |
93 | 6.59k | } |
94 | | |
95 | | // entire frames |
96 | 9.34k | while ( count >= (long) sample_buf_size ) |
97 | 2.38k | { |
98 | 2.38k | play_frame_( blip_buf, out ); |
99 | 2.38k | out += sample_buf_size; |
100 | 2.38k | count -= sample_buf_size; |
101 | 2.38k | } |
102 | | |
103 | | // extra |
104 | 6.96k | if ( count ) |
105 | 6.71k | { |
106 | 6.71k | play_frame_( blip_buf, sample_buf.begin() ); |
107 | 6.71k | buf_pos = count; |
108 | 6.71k | memcpy( out, sample_buf.begin(), count * sizeof *out ); |
109 | 6.71k | out += count; |
110 | 6.71k | } |
111 | 6.96k | } |
112 | | |
113 | | void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out ) |
114 | 9.10k | { |
115 | 9.10k | Blip_Reader sn; |
116 | 9.10k | int bass = sn.begin( blip_buf ); |
117 | 9.10k | const dsample_t* in = sample_buf.begin(); |
118 | | |
119 | 7.36M | for ( int n = sample_buf_size >> 1; n--; ) |
120 | 7.35M | { |
121 | 7.35M | int s = sn.read(); |
122 | 7.35M | int32_t l = (int32_t) in [0] * 2 + s; |
123 | 7.35M | if ( (int16_t) l != l ) |
124 | 0 | l = 0x7FFF - (l >> 24); |
125 | | |
126 | 7.35M | sn.next( bass ); |
127 | 7.35M | int32_t r = (int32_t) in [1] * 2 + s; |
128 | 7.35M | if ( (int16_t) r != r ) |
129 | 0 | r = 0x7FFF - (r >> 24); |
130 | | |
131 | 7.35M | in += 2; |
132 | 7.35M | out [0] = l; |
133 | 7.35M | out [1] = r; |
134 | 7.35M | out += 2; |
135 | 7.35M | } |
136 | | |
137 | 9.10k | sn.end( blip_buf ); |
138 | 9.10k | } |
139 | | |