annotate src/console/Vgm_Emu.cxx @ 284:72f0de06bb56 trunk

[svn] - wavpack/wputils.h is deprecated, wavpack/wavpack.h should be used instead.
author nenolod
date Mon, 20 Nov 2006 18:24:07 -0800
parents 3da1b8942b8b
children fb513e10174e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
1
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
3
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
4 #include "Vgm_Emu.h"
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
5
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
6 #include <math.h>
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
7 #include <string.h>
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
8 #include "blargg_endian.h"
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
9
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
10 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
11 can redistribute it and/or modify it under the terms of the GNU Lesser
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
12 General Public License as published by the Free Software Foundation; either
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
13 version 2.1 of the License, or (at your option) any later version. This
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
14 module is distributed in the hope that it will be useful, but WITHOUT ANY
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
17 more details. You should have received a copy of the GNU Lesser General
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
18 Public License along with this module; if not, write to the Free Software
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
20
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
21 #include BLARGG_SOURCE_BEGIN
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
22
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
23 double const gain = 3.0; // FM emulators are internally quieter to avoid 16-bit overflow
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
24 double const rolloff = 0.990;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
25 double const oversample_factor = 1.5;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
26
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
27 Vgm_Emu::Vgm_Emu( bool os, double tempo )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
28 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
29 oversample = os;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
30 pos = NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
31 data = NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
32 uses_fm = false;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
33 vgm_rate = (long) (header_t::time_rate * tempo + 0.5);
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
34
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
35 static equalizer_t const eq = { -14.0, 80 };
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
36 set_equalizer( eq );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
37 psg.volume( 1.0 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
38 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
39
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
40 Vgm_Emu::~Vgm_Emu()
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
41 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
42 unload();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
43 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
44
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
45 void Vgm_Emu::unload()
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
46 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
47 data = NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
48 pos = NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
49 set_track_ended( false );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
50 mem.clear();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
51 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
52
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
53 blargg_err_t Vgm_Emu::set_sample_rate( long sample_rate )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
54 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
55 BLARGG_RETURN_ERR( blip_buf.set_sample_rate( sample_rate, 1000 / 30 ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
56 return Classic_Emu::set_sample_rate( sample_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
57 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
58
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
59 BOOST::uint8_t const* Vgm_Emu::gd3_data( int* size ) const
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
60 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
61 if ( size )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
62 *size = 0;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
63
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
64 long gd3_offset = get_le32( header_.gd3_offset );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
65 if ( !gd3_offset )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
66 return NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
67
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
68 gd3_offset -= 0x40 - offsetof (header_t,gd3_offset);
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
69 if ( gd3_offset < 0 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
70 return NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
71
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
72 byte const* gd3 = data + gd3_offset;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
73 if ( data_end - gd3 < 16 || 0 != memcmp( gd3, "Gd3 ", 4 ) || get_le32( gd3 + 4 ) >= 0x200 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
74 return NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
75
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
76 long gd3_size = get_le32( gd3 + 8 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
77 if ( data_end - gd3 < gd3_size - 12 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
78 return NULL;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
79
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
80 if ( size )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
81 *size = data_end - gd3;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
82 return gd3;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
83 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
84
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
85 void Vgm_Emu::update_eq( blip_eq_t const& eq )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
86 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
87 psg.treble_eq( eq );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
88 dac_synth.treble_eq( eq );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
89 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
90
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
91 void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
92 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
93 if ( i < psg.osc_count )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
94 psg.osc_output( i, c, l, r );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
95 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
96
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
97 const char** Vgm_Emu::voice_names() const
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
98 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
99 static const char* fm_names [] = {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
100 "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
101 };
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
102 if ( uses_fm )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
103 return fm_names;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
104
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
105 static const char* psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
106 return psg_names;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
107 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
108
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
109 void Vgm_Emu::mute_voices( int mask )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
110 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
111 Classic_Emu::mute_voices( mask );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
112 dac_synth.output( &blip_buf );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
113 if ( uses_fm )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
114 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
115 psg.output( (mask & 0x80) ? 0 : &blip_buf );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
116 if ( ym2612.enabled() )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
117 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
118 dac_synth.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * gain );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
119 ym2612.mute_voices( mask );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
120 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
121
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
122 if ( ym2413.enabled() )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
123 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
124 int m = mask & 0x3f;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
125 if ( mask & 0x20 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
126 m |= 0x01e0; // channels 5-8
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
127 if ( mask & 0x40 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
128 m |= 0x3e00;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
129 ym2413.mute_voices( m );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
130 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
131 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
132 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
133
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
134 blargg_err_t Vgm_Emu::load_( const header_t& h, void const* new_data, long new_size )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
135 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
136 header_ = h;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
137
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
138 // compatibility
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
139 if ( 0 != memcmp( header_.tag, "Vgm ", 4 ) )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
140 return "Not a VGM file";
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
141 check( get_le32( header_.version ) <= 0x150 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
142
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
143 // psg rate
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
144 long psg_rate = get_le32( header_.psg_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
145 if ( !psg_rate )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
146 psg_rate = 3579545;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
147 blip_time_factor = (long) floor( (double) (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
148 blip_buf.clock_rate( psg_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
149
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
150 data = (byte*) new_data;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
151 data_end = data + new_size;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
152
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
153 // get loop
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
154 loop_begin = data_end;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
155 if ( get_le32( header_.loop_offset ) )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
156 loop_begin = &data [get_le32( header_.loop_offset ) + offsetof (header_t,loop_offset) - 0x40];
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
157
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
158 set_voice_count( psg.osc_count );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
159 set_track_count( 1 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
160
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
161 BLARGG_RETURN_ERR( setup_fm() );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
162
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
163 // do after FM in case output buffer is changed
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
164 BLARGG_RETURN_ERR( Classic_Emu::setup_buffer( psg_rate ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
165
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
166 return blargg_success;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
167 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
168
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
169 blargg_err_t Vgm_Emu::setup_fm()
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
170 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
171 long ym2612_rate = get_le32( header_.ym2612_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
172 long ym2413_rate = get_le32( header_.ym2413_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
173 if ( ym2413_rate && get_le32( header_.version ) < 0x110 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
174 update_fm_rates( &ym2413_rate, &ym2612_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
175
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
176 uses_fm = false;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
177
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
178 double fm_rate = blip_buf.sample_rate() * oversample_factor;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
179
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
180 if ( ym2612_rate )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
181 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
182 uses_fm = true;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
183 if ( !oversample )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
184 fm_rate = ym2612_rate / 144.0;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
185 Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, gain );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
186 BLARGG_RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
187 ym2612.enable( true );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
188 set_voice_count( 8 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
189 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
190
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
191 if ( !uses_fm && ym2413_rate )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
192 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
193 uses_fm = true;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
194 if ( !oversample )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
195 fm_rate = ym2413_rate / 72.0;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
196 Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, gain );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
197 int result = ym2413.set_rate( fm_rate, ym2413_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
198 if ( result == 2 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
199 return "YM2413 FM sound isn't supported";
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
200 BLARGG_CHECK_ALLOC( !result );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
201 ym2413.enable( true );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
202 set_voice_count( 8 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
203 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
204
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
205 if ( uses_fm )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
206 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
207 //dprintf( "fm_rate: %f\n", fm_rate );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
208 fm_time_factor = 2 + (long) floor( fm_rate * (1L << fm_time_bits) / vgm_rate + 0.5 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
209 BLARGG_RETURN_ERR( Dual_Resampler::resize( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
210 psg.volume( 0.135 * gain );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
211 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
212 else
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
213 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
214 ym2612.enable( false );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
215 ym2413.enable( false );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
216 psg.volume( 1.0 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
217 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
218
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
219 return blargg_success;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
220 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
221
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
222 blargg_err_t Vgm_Emu::load( Data_Reader& reader )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
223 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
224 header_t h;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
225 BLARGG_RETURN_ERR( reader.read( &h, sizeof h ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
226 return load( h, reader );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
227 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
228
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
229 blargg_err_t Vgm_Emu::load( const header_t& h, Data_Reader& reader )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
230 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
231 unload();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
232
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
233 // allocate and read data
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
234 long data_size = reader.remain();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
235 int const padding = 8;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
236 BLARGG_RETURN_ERR( mem.resize( data_size + padding ) );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
237 blargg_err_t err = reader.read( mem.begin(), data_size );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
238 if ( err ) {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
239 unload();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
240 return err;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
241 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
242 memset( &mem [data_size], 0x66, padding ); // pad with end command
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
243
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
244 return load_( h, mem.begin(), data_size );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
245 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
246
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
247 void Vgm_Emu::start_track( int track )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
248 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
249 require( data ); // file must have been loaded
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
250
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
251 Classic_Emu::start_track( track );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
252 psg.reset();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
253
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
254 dac_disabled = -1;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
255 pcm_data = data;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
256 pcm_pos = data;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
257 dac_amp = -1;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
258 vgm_time = 0;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
259 pos = data;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
260 if ( get_le32( header_.version ) >= 0x150 )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
261 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
262 long data_offset = get_le32( header_.data_offset );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
263 check( data_offset );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
264 if ( data_offset )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
265 pos += data_offset + offsetof (header_t,data_offset) - 0x40;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
266 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
267
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
268 if ( uses_fm )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
269 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
270 if ( ym2413.enabled() )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
271 ym2413.reset();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
272
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
273 if ( ym2612.enabled() )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
274 ym2612.reset();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
275
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
276 fm_time_offset = 0;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
277 blip_buf.clear();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
278 Dual_Resampler::clear();
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
279 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
280 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
281
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
282 long Vgm_Emu::run( int msec, bool* added_stereo )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
283 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
284 blip_time_t psg_end = run_commands( msec * vgm_rate / 1000 );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
285 *added_stereo = psg.end_frame( psg_end );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
286 return psg_end;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
287 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
288
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
289 void Vgm_Emu::play( long count, sample_t* out )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
290 {
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
291 require( pos ); // track must have been started
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
292
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
293 if ( uses_fm )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
294 Dual_Resampler::play( count, out, blip_buf );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
295 else
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
296 Classic_Emu::play( count, out );
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
297 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
298