Mercurial > audlegacy-plugins
comparison src/console/Spc_Emu.cxx @ 12:3da1b8942b8b trunk
[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 03:14:20 -0700 |
parents | src/Input/console/Spc_Emu.cxx@13389e613d67 |
children | fb513e10174e |
comparison
equal
deleted
inserted
replaced
11:cff1d04026ae | 12:3da1b8942b8b |
---|---|
1 | |
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ | |
3 | |
4 #include "Spc_Emu.h" | |
5 | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8 #include "blargg_endian.h" | |
9 | |
10 /* Copyright (C) 2004-2006 Shay Green. This module is free software; you | |
11 can redistribute it and/or modify it under the terms of the GNU Lesser | |
12 General Public License as published by the Free Software Foundation; either | |
13 version 2.1 of the License, or (at your option) any later version. This | |
14 module is distributed in the hope that it will be useful, but WITHOUT ANY | |
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for | |
17 more details. You should have received a copy of the GNU Lesser General | |
18 Public License along with this module; if not, write to the Free Software | |
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | |
20 | |
21 #include BLARGG_SOURCE_BEGIN | |
22 | |
23 Spc_Emu::Spc_Emu( double gain ) | |
24 { | |
25 apu.set_gain( gain ); | |
26 } | |
27 | |
28 Spc_Emu::~Spc_Emu() | |
29 { | |
30 } | |
31 | |
32 const char** Spc_Emu::voice_names() const | |
33 { | |
34 static const char* names [] = { | |
35 "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8" | |
36 }; | |
37 return names; | |
38 } | |
39 | |
40 void Spc_Emu::mute_voices( int m ) | |
41 { | |
42 Music_Emu::mute_voices( m ); | |
43 apu.mute_voices( m ); | |
44 } | |
45 | |
46 blargg_err_t Spc_Emu::set_sample_rate( long sample_rate ) | |
47 { | |
48 if ( sample_rate != native_sample_rate ) | |
49 { | |
50 BLARGG_RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) ); | |
51 resampler.time_ratio( (double) native_sample_rate / sample_rate, 0.9965 ); | |
52 } | |
53 return Music_Emu::set_sample_rate( sample_rate ); | |
54 } | |
55 | |
56 blargg_err_t Spc_Emu::load( Data_Reader& in ) | |
57 { | |
58 header_t h; | |
59 BLARGG_RETURN_ERR( in.read( &h, sizeof h ) ); | |
60 return load( h, in ); | |
61 } | |
62 | |
63 blargg_err_t Spc_Emu::load( const header_t& h, Data_Reader& in ) | |
64 { | |
65 if ( in.remain() < Snes_Spc::spc_file_size - (int) sizeof h ) | |
66 return "Not an SPC file"; | |
67 | |
68 if ( strncmp( h.tag, "SNES-SPC700 Sound File Data", 27 ) != 0 ) | |
69 return "Not an SPC file"; | |
70 | |
71 long remain = in.remain(); | |
72 long size = remain + sizeof h; | |
73 if ( size < trailer_offset ) | |
74 size = trailer_offset; | |
75 BLARGG_RETURN_ERR( spc_data.resize( size ) ); | |
76 | |
77 set_track_count( 1 ); | |
78 set_voice_count( Snes_Spc::voice_count ); | |
79 | |
80 memcpy( spc_data.begin(), &h, sizeof h ); | |
81 return in.read( &spc_data [sizeof h], remain ); | |
82 } | |
83 | |
84 void Spc_Emu::start_track( int track ) | |
85 { | |
86 Music_Emu::start_track( track ); | |
87 | |
88 resampler.clear(); | |
89 if ( apu.load_spc( spc_data.begin(), spc_data.size() ) ) | |
90 check( false ); | |
91 } | |
92 | |
93 void Spc_Emu::skip( long count ) | |
94 { | |
95 count = long (count * resampler.ratio()) & ~1; | |
96 | |
97 count -= resampler.skip_input( count ); | |
98 if ( count > 0 ) | |
99 apu.skip( count ); | |
100 | |
101 // eliminate pop due to resampler | |
102 const int resampler_latency = 64; | |
103 sample_t buf [resampler_latency]; | |
104 play( resampler_latency, buf ); | |
105 } | |
106 | |
107 void Spc_Emu::play( long count, sample_t* out ) | |
108 { | |
109 require( track_count() ); // file must be loaded | |
110 | |
111 if ( sample_rate() == native_sample_rate ) | |
112 { | |
113 if ( apu.play( count, out ) ) | |
114 log_error(); | |
115 return; | |
116 } | |
117 | |
118 long remain = count; | |
119 while ( remain > 0 ) | |
120 { | |
121 remain -= resampler.read( &out [count - remain], remain ); | |
122 if ( remain > 0 ) | |
123 { | |
124 long n = resampler.max_write(); | |
125 if ( apu.play( n, resampler.buffer() ) ) | |
126 log_error(); | |
127 resampler.write( n ); | |
128 } | |
129 } | |
130 | |
131 assert( remain == 0 ); | |
132 } | |
133 |