diff options
Diffstat (limited to 'apps/codecs/libgme/opl_apu.c')
-rw-r--r-- | apps/codecs/libgme/opl_apu.c | 396 |
1 files changed, 198 insertions, 198 deletions
diff --git a/apps/codecs/libgme/opl_apu.c b/apps/codecs/libgme/opl_apu.c index 64b2714b81..b573baef11 100644 --- a/apps/codecs/libgme/opl_apu.c +++ b/apps/codecs/libgme/opl_apu.c | |||
@@ -1,198 +1,198 @@ | |||
1 | #include "opl_apu.h" | 1 | #include "opl_apu.h" |
2 | 2 | ||
3 | #include "blargg_source.h" | 3 | #include "blargg_source.h" |
4 | 4 | ||
5 | /* NOTE: Removed unused chips ~ gama */ | 5 | /* NOTE: Removed unused chips ~ gama */ |
6 | 6 | ||
7 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ) | 7 | blargg_err_t Opl_init( struct Opl_Apu* this, long clock, long rate, blip_time_t period, enum opl_type_t type ) |
8 | { | 8 | { |
9 | Synth_init( &this->synth ); | 9 | Synth_init( &this->synth ); |
10 | 10 | ||
11 | this->type_ = type; | 11 | this->type_ = type; |
12 | this->clock_ = clock; | 12 | this->clock_ = clock; |
13 | this->rate_ = rate; | 13 | this->rate_ = rate; |
14 | this->period_ = period; | 14 | this->period_ = period; |
15 | Opl_set_output( this, 0 ); | 15 | Opl_set_output( this, 0 ); |
16 | Opl_volume( this, (int)FP_ONE_VOLUME ); | 16 | Opl_volume( this, (int)FP_ONE_VOLUME ); |
17 | 17 | ||
18 | switch (type) | 18 | switch (type) |
19 | { | 19 | { |
20 | case type_opll: | 20 | case type_opll: |
21 | case type_msxmusic: | 21 | case type_msxmusic: |
22 | case type_smsfmunit: | 22 | case type_smsfmunit: |
23 | OPLL_new ( &this->opll, clock, rate ); | 23 | OPLL_new ( &this->opll, clock, rate ); |
24 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); | 24 | OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); |
25 | break; | 25 | break; |
26 | case type_vrc7: | 26 | case type_vrc7: |
27 | OPLL_new ( &this->opll, clock, rate ); | 27 | OPLL_new ( &this->opll, clock, rate ); |
28 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); | 28 | OPLL_reset_patch( &this->opll, OPLL_VRC7_TONE ); |
29 | break; | 29 | break; |
30 | case type_msxaudio: | 30 | case type_msxaudio: |
31 | OPL_init( &this->opl, this->opl_memory, sizeof this->opl_memory ); | 31 | OPL_init( &this->opl, this->opl_memory, sizeof this->opl_memory ); |
32 | OPL_setSampleRate( &this->opl, rate, clock ); | 32 | OPL_setSampleRate( &this->opl, rate, clock ); |
33 | OPL_setInternalVolume(&this->opl, 1 << 13); | 33 | OPL_setInternalVolume(&this->opl, 1 << 13); |
34 | break; | 34 | break; |
35 | } | 35 | } |
36 | 36 | ||
37 | Opl_reset( this ); | 37 | Opl_reset( this ); |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
41 | void Opl_shutdown( struct Opl_Apu* this ) | 41 | void Opl_shutdown( struct Opl_Apu* this ) |
42 | { | 42 | { |
43 | switch (this->type_) | 43 | switch (this->type_) |
44 | { | 44 | { |
45 | case type_opll: | 45 | case type_opll: |
46 | case type_msxmusic: | 46 | case type_msxmusic: |
47 | case type_smsfmunit: | 47 | case type_smsfmunit: |
48 | case type_vrc7: | 48 | case type_vrc7: |
49 | OPLL_delete( &this->opll ); | 49 | OPLL_delete( &this->opll ); |
50 | break; | 50 | break; |
51 | case type_msxaudio: break; | 51 | case type_msxaudio: break; |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | void Opl_reset( struct Opl_Apu* this ) | 55 | void Opl_reset( struct Opl_Apu* this ) |
56 | { | 56 | { |
57 | this->addr = 0; | 57 | this->addr = 0; |
58 | this->next_time = 0; | 58 | this->next_time = 0; |
59 | this->last_amp = 0; | 59 | this->last_amp = 0; |
60 | 60 | ||
61 | switch (this->type_) | 61 | switch (this->type_) |
62 | { | 62 | { |
63 | case type_opll: | 63 | case type_opll: |
64 | case type_msxmusic: | 64 | case type_msxmusic: |
65 | case type_smsfmunit: | 65 | case type_smsfmunit: |
66 | case type_vrc7: | 66 | case type_vrc7: |
67 | OPLL_reset( &this->opll ); | 67 | OPLL_reset( &this->opll ); |
68 | OPLL_setMask( &this->opll, 0 ); | 68 | OPLL_setMask( &this->opll, 0 ); |
69 | break; | 69 | break; |
70 | case type_msxaudio: | 70 | case type_msxaudio: |
71 | OPL_reset( &this->opl ); | 71 | OPL_reset( &this->opl ); |
72 | break; | 72 | break; |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ); | 76 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ); |
77 | void Opl_write_data( struct Opl_Apu* this, blip_time_t time, int data ) | 77 | void Opl_write_data( struct Opl_Apu* this, blip_time_t time, int data ) |
78 | { | 78 | { |
79 | run_until( this, time ); | 79 | run_until( this, time ); |
80 | switch (this->type_) | 80 | switch (this->type_) |
81 | { | 81 | { |
82 | case type_opll: | 82 | case type_opll: |
83 | case type_msxmusic: | 83 | case type_msxmusic: |
84 | case type_smsfmunit: | 84 | case type_smsfmunit: |
85 | case type_vrc7: | 85 | case type_vrc7: |
86 | OPLL_writeIO( &this->opll, 0, this->addr ); | 86 | OPLL_writeIO( &this->opll, 0, this->addr ); |
87 | OPLL_writeIO( &this->opll, 1, data ); | 87 | OPLL_writeIO( &this->opll, 1, data ); |
88 | break; | 88 | break; |
89 | case type_msxaudio: | 89 | case type_msxaudio: |
90 | OPL_writeReg( &this->opl, this->addr, data ); | 90 | OPL_writeReg( &this->opl, this->addr, data ); |
91 | break; | 91 | break; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | int Opl_read( struct Opl_Apu* this, blip_time_t time, int port ) | 95 | int Opl_read( struct Opl_Apu* this, blip_time_t time, int port ) |
96 | { | 96 | { |
97 | run_until( this, time ); | 97 | run_until( this, time ); |
98 | switch (this->type_) | 98 | switch (this->type_) |
99 | { | 99 | { |
100 | case type_opll: | 100 | case type_opll: |
101 | case type_msxmusic: | 101 | case type_msxmusic: |
102 | case type_smsfmunit: | 102 | case type_smsfmunit: |
103 | case type_vrc7: | 103 | case type_vrc7: |
104 | return OPLL_read( &this->opll, port ); | 104 | return OPLL_read( &this->opll, port ); |
105 | case type_msxaudio: | 105 | case type_msxaudio: |
106 | return OPL_readStatus( &this->opl ); | 106 | return OPL_readStatus( &this->opl ); |
107 | } | 107 | } |
108 | 108 | ||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t time ) | 112 | void Opl_end_frame( struct Opl_Apu* this, blip_time_t time ) |
113 | { | 113 | { |
114 | run_until( this, time ); | 114 | run_until( this, time ); |
115 | this->next_time -= time; | 115 | this->next_time -= time; |
116 | 116 | ||
117 | if ( this->output_ ) | 117 | if ( this->output_ ) |
118 | Blip_set_modified( this->output_ ); | 118 | Blip_set_modified( this->output_ ); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ) | 121 | static void run_until( struct Opl_Apu* this, blip_time_t end_time ) |
122 | { | 122 | { |
123 | if ( end_time > this->next_time ) | 123 | if ( end_time > this->next_time ) |
124 | { | 124 | { |
125 | blip_time_t time_delta = end_time - this->next_time; | 125 | blip_time_t time_delta = end_time - this->next_time; |
126 | blip_time_t time = this->next_time; | 126 | blip_time_t time = this->next_time; |
127 | unsigned count = time_delta / this->period_ + 1; | 127 | unsigned count = time_delta / this->period_ + 1; |
128 | switch (this->type_) | 128 | switch (this->type_) |
129 | { | 129 | { |
130 | case type_opll: | 130 | case type_opll: |
131 | case type_msxmusic: | 131 | case type_msxmusic: |
132 | case type_smsfmunit: | 132 | case type_smsfmunit: |
133 | case type_vrc7: | 133 | case type_vrc7: |
134 | { | 134 | { |
135 | OPLL* opll = &this->opll; // cache | 135 | OPLL* opll = &this->opll; // cache |
136 | struct Blip_Buffer* const output = this->output_; | 136 | struct Blip_Buffer* const output = this->output_; |
137 | while ( count > 0 ) | 137 | while ( count > 0 ) |
138 | { | 138 | { |
139 | unsigned todo = count; | 139 | unsigned todo = count; |
140 | if ( todo > 1024 ) todo = 1024; | 140 | if ( todo > 1024 ) todo = 1024; |
141 | short *buffer = OPLL_update_buffer(opll, todo); | 141 | short *buffer = OPLL_update_buffer(opll, todo); |
142 | 142 | ||
143 | if ( output && buffer ) | 143 | if ( output && buffer ) |
144 | { | 144 | { |
145 | int last_amp = this->last_amp; | 145 | int last_amp = this->last_amp; |
146 | unsigned i; | 146 | unsigned i; |
147 | for ( i = 0; i < todo; i++ ) | 147 | for ( i = 0; i < todo; i++ ) |
148 | { | 148 | { |
149 | int amp = buffer [i]; | 149 | int amp = buffer [i]; |
150 | int delta = amp - last_amp; | 150 | int delta = amp - last_amp; |
151 | if ( delta ) | 151 | if ( delta ) |
152 | { | 152 | { |
153 | last_amp = amp; | 153 | last_amp = amp; |
154 | Synth_offset_inline( &this->synth, time, delta, output ); | 154 | Synth_offset_inline( &this->synth, time, delta, output ); |
155 | } | 155 | } |
156 | time += this->period_; | 156 | time += this->period_; |
157 | } | 157 | } |
158 | this->last_amp = last_amp; | 158 | this->last_amp = last_amp; |
159 | } | 159 | } |
160 | count -= todo; | 160 | count -= todo; |
161 | } | 161 | } |
162 | } | 162 | } |
163 | break; | 163 | break; |
164 | case type_msxaudio: | 164 | case type_msxaudio: |
165 | { | 165 | { |
166 | struct Y8950* opl = &this->opl; | 166 | struct Y8950* opl = &this->opl; |
167 | struct Blip_Buffer* const output = this->output_; | 167 | struct Blip_Buffer* const output = this->output_; |
168 | while ( count > 0 ) | 168 | while ( count > 0 ) |
169 | { | 169 | { |
170 | unsigned todo = count; | 170 | unsigned todo = count; |
171 | if ( todo > 1024 ) todo = 1024; | 171 | if ( todo > 1024 ) todo = 1024; |
172 | int *buffer = OPL_updateBuffer(opl, todo); | 172 | int *buffer = OPL_updateBuffer(opl, todo); |
173 | 173 | ||
174 | if ( output && buffer ) | 174 | if ( output && buffer ) |
175 | { | 175 | { |
176 | int last_amp = this->last_amp; | 176 | int last_amp = this->last_amp; |
177 | unsigned i; | 177 | unsigned i; |
178 | for ( i = 0; i < todo; i++ ) | 178 | for ( i = 0; i < todo; i++ ) |
179 | { | 179 | { |
180 | int amp = buffer [i]; | 180 | int amp = buffer [i]; |
181 | int delta = amp - last_amp; | 181 | int delta = amp - last_amp; |
182 | if ( delta ) | 182 | if ( delta ) |
183 | { | 183 | { |
184 | last_amp = amp; | 184 | last_amp = amp; |
185 | Synth_offset_inline( &this->synth, time, delta, output ); | 185 | Synth_offset_inline( &this->synth, time, delta, output ); |
186 | } | 186 | } |
187 | time += this->period_; | 187 | time += this->period_; |
188 | } | 188 | } |
189 | this->last_amp = last_amp; | 189 | this->last_amp = last_amp; |
190 | } | 190 | } |
191 | count -= todo; | 191 | count -= todo; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | break; | 194 | break; |
195 | } | 195 | } |
196 | this->next_time = time; | 196 | this->next_time = time; |
197 | } | 197 | } |
198 | } | 198 | } |