diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libgme/nes_fds_apu.h | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libgme/nes_fds_apu.h')
-rw-r--r-- | lib/rbcodec/codecs/libgme/nes_fds_apu.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/nes_fds_apu.h b/lib/rbcodec/codecs/libgme/nes_fds_apu.h new file mode 100644 index 0000000000..8dac3b721a --- /dev/null +++ b/lib/rbcodec/codecs/libgme/nes_fds_apu.h | |||
@@ -0,0 +1,116 @@ | |||
1 | // NES FDS sound chip emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef NES_FDS_APU_H | ||
5 | #define NES_FDS_APU_H | ||
6 | |||
7 | #include "blargg_common.h" | ||
8 | #include "blip_buffer.h" | ||
9 | |||
10 | enum { lfo_base_tempo = 8 }; | ||
11 | enum { fds_osc_count = 1 }; | ||
12 | |||
13 | enum { fds_io_addr = 0x4040 }; | ||
14 | enum { fds_io_size = 0x53 }; | ||
15 | |||
16 | enum { fds_wave_size = 0x40 }; | ||
17 | enum { fds_master_vol_max = 10 }; | ||
18 | enum { fds_vol_max = 0x20 }; | ||
19 | enum { fds_wave_sample_max = 0x3F }; | ||
20 | |||
21 | struct Nes_Fds_Apu { | ||
22 | unsigned char regs_ [fds_io_size];// last written value to registers | ||
23 | int lfo_tempo; // normally 8; adjusted by set_tempo() | ||
24 | |||
25 | int env_delay; | ||
26 | int env_speed; | ||
27 | int env_gain; | ||
28 | |||
29 | int sweep_delay; | ||
30 | int sweep_speed; | ||
31 | int sweep_gain; | ||
32 | |||
33 | int wave_pos; | ||
34 | int last_amp; | ||
35 | blip_time_t wave_fract; | ||
36 | |||
37 | int mod_fract; | ||
38 | int mod_pos; | ||
39 | int mod_write_pos; | ||
40 | unsigned char mod_wave [fds_wave_size]; | ||
41 | |||
42 | // synthesis | ||
43 | blip_time_t last_time; | ||
44 | struct Blip_Buffer* output_; | ||
45 | struct Blip_Synth synth; | ||
46 | }; | ||
47 | |||
48 | // init | ||
49 | void Fds_init( struct Nes_Fds_Apu* this ); | ||
50 | // setup | ||
51 | void Fds_set_tempo( struct Nes_Fds_Apu* this, int t ); | ||
52 | |||
53 | // emulation | ||
54 | void Fds_reset( struct Nes_Fds_Apu* this ); | ||
55 | |||
56 | static inline void Fds_volume( struct Nes_Fds_Apu* this, int v ) | ||
57 | { | ||
58 | Synth_volume( &this->synth, (v*14) / 100 / fds_master_vol_max / fds_vol_max / fds_wave_sample_max ); | ||
59 | } | ||
60 | |||
61 | static inline void Fds_set_output( struct Nes_Fds_Apu* this, int i, struct Blip_Buffer* b ) | ||
62 | { | ||
63 | #if defined(ROCKBOX) | ||
64 | (void) i; | ||
65 | #endif | ||
66 | |||
67 | assert( (unsigned) i < fds_osc_count ); | ||
68 | this->output_ = b; | ||
69 | } | ||
70 | |||
71 | void Fds_run_until( struct Nes_Fds_Apu* this, blip_time_t ); | ||
72 | static inline void Fds_end_frame( struct Nes_Fds_Apu* this, blip_time_t end_time ) | ||
73 | { | ||
74 | if ( end_time > this->last_time ) | ||
75 | Fds_run_until( this, end_time ); | ||
76 | this->last_time -= end_time; | ||
77 | assert( this->last_time >= 0 ); | ||
78 | } | ||
79 | |||
80 | void Fds_write_( struct Nes_Fds_Apu* this, unsigned addr, int data ); | ||
81 | static inline void Fds_write( struct Nes_Fds_Apu* this, blip_time_t time, unsigned addr, int data ) | ||
82 | { | ||
83 | Fds_run_until( this, time ); | ||
84 | Fds_write_( this, addr, data ); | ||
85 | } | ||
86 | |||
87 | static inline int Fds_read( struct Nes_Fds_Apu* this, blip_time_t time, unsigned addr ) | ||
88 | { | ||
89 | Fds_run_until( this, time ); | ||
90 | |||
91 | int result = 0xFF; | ||
92 | switch ( addr ) | ||
93 | { | ||
94 | case 0x4090: | ||
95 | result = this->env_gain; | ||
96 | break; | ||
97 | |||
98 | case 0x4092: | ||
99 | result = this->sweep_gain; | ||
100 | break; | ||
101 | |||
102 | default: | ||
103 | { | ||
104 | unsigned i = addr - fds_io_addr; | ||
105 | if ( i < fds_wave_size ) | ||
106 | result = this->regs_ [i]; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return result | 0x40; | ||
111 | } | ||
112 | |||
113 | // allow access to registers by absolute address (i.e. 0x4080) | ||
114 | static inline unsigned char* regs_nes( struct Nes_Fds_Apu* this, unsigned addr ) { return &this->regs_ [addr - fds_io_addr]; } | ||
115 | |||
116 | #endif | ||