Mercurial > audlegacy-plugins
comparison src/console/Classic_Emu.cxx @ 316:fb513e10174e trunk
[svn] - merge libconsole-blargg into mainline libconsole:
+ obsoletes plugins-ugly:sapplug
author | nenolod |
---|---|
date | Thu, 30 Nov 2006 19:54:33 -0800 |
parents | 3da1b8942b8b |
children | 986f098da058 |
comparison
equal
deleted
inserted
replaced
315:2294f3a6f136 | 316:fb513e10174e |
---|---|
1 | 1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/ |
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ | |
3 | 2 |
4 #include "Classic_Emu.h" | 3 #include "Classic_Emu.h" |
5 | 4 |
6 #include "Multi_Buffer.h" | 5 #include "Multi_Buffer.h" |
6 #include <string.h> | |
7 | 7 |
8 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you | 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 | 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 | 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 | 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 | 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 | 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for | 14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 more details. You should have received a copy of the GNU Lesser General | 15 details. You should have received a copy of the GNU Lesser General Public |
16 Public License along with this module; if not, write to the Free Software | 16 License along with this module; if not, write to the Free Software Foundation, |
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | 18 |
19 #include BLARGG_SOURCE_BEGIN | 19 #include "blargg_source.h" |
20 | 20 |
21 Classic_Emu::Classic_Emu() | 21 Classic_Emu::Classic_Emu() |
22 { | 22 { |
23 buf = NULL; | 23 buf = 0; |
24 stereo_buffer = NULL; | 24 stereo_buffer = 0; |
25 voice_types = 0; | |
26 | |
27 // avoid inconsistency in our duplicated constants | |
28 assert( (int) wave_type == (int) Multi_Buffer::wave_type ); | |
29 assert( (int) noise_type == (int) Multi_Buffer::noise_type ); | |
30 assert( (int) mixed_type == (int) Multi_Buffer::mixed_type ); | |
25 } | 31 } |
26 | 32 |
27 Classic_Emu::~Classic_Emu() | 33 Classic_Emu::~Classic_Emu() |
28 { | 34 { |
29 delete stereo_buffer; | 35 delete stereo_buffer; |
30 } | 36 } |
31 | 37 |
32 void Classic_Emu::set_equalizer( equalizer_t const& eq ) | 38 void Classic_Emu::set_equalizer_( equalizer_t const& eq ) |
33 { | 39 { |
34 Music_Emu::set_equalizer( eq ); | 40 Music_Emu::set_equalizer_( eq ); |
35 update_eq( eq.treble ); | 41 update_eq( eq.treble ); |
36 if ( buf ) | 42 if ( buf ) |
37 buf->bass_freq( equalizer().bass ); | 43 buf->bass_freq( equalizer().bass ); |
38 } | 44 } |
39 | 45 |
40 blargg_err_t Classic_Emu::set_sample_rate( long sample_rate ) | 46 blargg_err_t Classic_Emu::set_sample_rate_( long sample_rate ) |
41 { | 47 { |
42 if ( !buf ) | 48 if ( !buf ) |
43 { | 49 { |
44 if ( !stereo_buffer ) | 50 if ( !stereo_buffer ) |
45 BLARGG_CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer ); | 51 CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer ); |
46 buf = stereo_buffer; | 52 buf = stereo_buffer; |
47 } | 53 } |
48 | 54 return buf->set_sample_rate( sample_rate, 1000 / 20 ); |
49 BLARGG_RETURN_ERR( buf->set_sample_rate( sample_rate, 1000 / 20 ) ); | |
50 return Music_Emu::set_sample_rate( sample_rate ); | |
51 } | 55 } |
52 | 56 |
53 void Classic_Emu::mute_voices( int mask ) | 57 void Classic_Emu::mute_voices_( int mask ) |
54 { | 58 { |
55 require( buf ); // set_sample_rate() must have been called | 59 Music_Emu::mute_voices_( mask ); |
56 | |
57 Music_Emu::mute_voices( mask ); | |
58 for ( int i = voice_count(); i--; ) | 60 for ( int i = voice_count(); i--; ) |
59 { | 61 { |
60 if ( mask & (1 << i) ) | 62 if ( mask & (1 << i) ) |
61 { | 63 { |
62 set_voice( i, NULL, NULL, NULL ); | 64 set_voice( i, 0, 0, 0 ); |
63 } | 65 } |
64 else | 66 else |
65 { | 67 { |
66 Multi_Buffer::channel_t ch = buf->channel( i ); | 68 Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) ); |
69 assert( (ch.center && ch.left && ch.right) || | |
70 (!ch.center && !ch.left && !ch.right) ); // all or nothing | |
67 set_voice( i, ch.center, ch.left, ch.right ); | 71 set_voice( i, ch.center, ch.left, ch.right ); |
68 } | 72 } |
69 } | 73 } |
70 } | 74 } |
71 | 75 |
72 blargg_err_t Classic_Emu::setup_buffer( long new_clock_rate ) | 76 blargg_err_t Classic_Emu::setup_buffer( long rate ) |
73 { | 77 { |
74 require( sample_rate() ); // fails if set_sample_rate() hasn't been called yet | 78 clock_rate_ = rate; |
75 | 79 buf->clock_rate( rate ); |
76 clock_rate = new_clock_rate; | 80 RETURN_ERR( buf->set_channel_count( voice_count() ) ); |
77 buf->clock_rate( clock_rate ); | |
78 BLARGG_RETURN_ERR( buf->set_channel_count( voice_count() ) ); | |
79 set_equalizer( equalizer() ); | 81 set_equalizer( equalizer() ); |
80 remute_voices(); | 82 buf_changed_count = buf->channels_changed_count(); |
81 return blargg_success; | 83 return 0; |
82 } | 84 } |
83 | 85 |
84 void Classic_Emu::start_track( int track ) | 86 blargg_err_t Classic_Emu::start_track_( int track ) |
85 { | 87 { |
86 Music_Emu::start_track( track ); | 88 RETURN_ERR( Music_Emu::start_track_( track ) ); |
87 buf->clear(); | 89 buf->clear(); |
90 return 0; | |
88 } | 91 } |
89 | 92 |
90 blip_time_t Classic_Emu::run_clocks( blip_time_t t, bool* ) | 93 blargg_err_t Classic_Emu::play_( long count, sample_t* out ) |
91 { | 94 { |
92 assert( false ); | |
93 return t; | |
94 } | |
95 | |
96 blip_time_t Classic_Emu::run( int msec, bool* added_stereo ) | |
97 { | |
98 return run_clocks( (long) msec * clock_rate / 1000, added_stereo ); | |
99 } | |
100 | |
101 void Classic_Emu::play( long count, sample_t* out ) | |
102 { | |
103 require( sample_rate() ); // fails if set_sample_rate() hasn't been called yet | |
104 | |
105 long remain = count; | 95 long remain = count; |
106 while ( remain ) | 96 while ( remain ) |
107 { | 97 { |
108 remain -= buf->read_samples( &out [count - remain], remain ); | 98 remain -= buf->read_samples( &out [count - remain], remain ); |
109 if ( remain ) | 99 if ( remain ) |
110 { | 100 { |
111 bool added_stereo = false; | 101 if ( buf_changed_count != buf->channels_changed_count() ) |
112 blip_time_t clocks_emulated = run( buf->length(), &added_stereo ); | 102 { |
113 buf->end_frame( clocks_emulated, added_stereo ); | 103 buf_changed_count = buf->channels_changed_count(); |
104 remute_voices(); | |
105 } | |
106 int msec = buf->length(); | |
107 blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000; | |
108 RETURN_ERR( run_clocks( clocks_emulated, msec ) ); | |
109 assert( clocks_emulated ); | |
110 buf->end_frame( clocks_emulated ); | |
114 } | 111 } |
115 } | 112 } |
113 return 0; | |
116 } | 114 } |
117 | 115 |
116 // Rom_Data | |
117 | |
118 blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in, | |
119 int header_size, void* header_out, int fill, long pad_size ) | |
120 { | |
121 long file_offset = pad_size - header_size; | |
122 | |
123 rom_addr = 0; | |
124 mask = 0; | |
125 size_ = 0; | |
126 rom.clear(); | |
127 | |
128 file_size_ = in.remain(); | |
129 if ( file_size_ <= header_size ) // <= because there must be data after header | |
130 return gme_wrong_file_type; | |
131 blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size ); | |
132 if ( !err ) | |
133 err = in.read( rom.begin() + file_offset, file_size_ ); | |
134 if ( err ) | |
135 { | |
136 rom.clear(); | |
137 return err; | |
138 } | |
139 | |
140 file_size_ -= header_size; | |
141 memcpy( header_out, &rom [file_offset], header_size ); | |
142 | |
143 memset( rom.begin() , fill, pad_size ); | |
144 memset( rom.end() - pad_size, fill, pad_size ); | |
145 | |
146 return 0; | |
147 } | |
148 | |
149 void Rom_Data_::set_addr_( long addr, int unit ) | |
150 { | |
151 rom_addr = addr - unit - pad_extra; | |
152 | |
153 long rounded = (addr + file_size_ + unit - 1) / unit * unit; | |
154 if ( rounded <= 0 ) | |
155 { | |
156 rounded = 0; | |
157 } | |
158 else | |
159 { | |
160 int shift = 0; | |
161 unsigned long max_addr = (unsigned long) (rounded - 1); | |
162 while ( max_addr >> shift ) | |
163 shift++; | |
164 mask = (1L << shift) - 1; | |
165 } | |
166 | |
167 if ( addr < 0 ) | |
168 addr = 0; | |
169 size_ = rounded; | |
170 if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails | |
171 | |
172 if ( 0 ) | |
173 { | |
174 dprintf( "addr: %X\n", addr ); | |
175 dprintf( "file_size: %d\n", file_size_ ); | |
176 dprintf( "rounded: %d\n", rounded ); | |
177 dprintf( "mask: $%X\n", mask ); | |
178 } | |
179 } |