Class: Rubyboy::ApuChannels::Channel3
- Inherits:
-
Object
- Object
- Rubyboy::ApuChannels::Channel3
- Defined in:
- lib/rubyboy/apu_channels/channel3.rb
Constant Summary collapse
- WAVE_DUTY =
[ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], # 12.5% [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0], # 25% [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0], # 50% [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # 75% ].freeze
Instance Attribute Summary collapse
-
#enabled ⇒ Object
Returns the value of attribute enabled.
-
#wave_duty_position ⇒ Object
Returns the value of attribute wave_duty_position.
-
#wave_ram ⇒ Object
Returns the value of attribute wave_ram.
Instance Method Summary collapse
- #calculate_frequency ⇒ Object
- #dac_output ⇒ Object
-
#initialize ⇒ Channel3
constructor
A new instance of Channel3.
- #length ⇒ Object
- #read_nr3x(x) ⇒ Object
- #step(cycles) ⇒ Object
- #step_fs(fs) ⇒ Object
- #write_nr3x(x, val) ⇒ Object
Constructor Details
#initialize ⇒ Channel3
Returns a new instance of Channel3.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 15 def initialize @cycles = 0 @frequency = 0 @frequency_timer = 0 @wave_duty_position = 0 @enabled = false @dac_enabled = false @length_enabled = false @is_upwards = false @is_decrementing = false @sweep_enabled = false @sweep_period = 0 @sweep_shift = 0 @period = 0 @period_timer = 0 @current_volume = 0 @initial_volume = 0 @shadow_frequency = 0 @sweep_timer = 0 @length_timer = 0 @wave_duty_pattern = 0 @output_level = 0 @volume_shift = 0 @wave_ram = Array.new(16, 0) end |
Instance Attribute Details
#enabled ⇒ Object
Returns the value of attribute enabled.
6 7 8 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 6 def enabled @enabled end |
#wave_duty_position ⇒ Object
Returns the value of attribute wave_duty_position.
6 7 8 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 6 def wave_duty_position @wave_duty_position end |
#wave_ram ⇒ Object
Returns the value of attribute wave_ram.
6 7 8 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 6 def wave_ram @wave_ram end |
Instance Method Details
#calculate_frequency ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 64 def calculate_frequency if @is_decrementing if @shadow_frequency >= (@shadow_frequency >> @sweep_shift) @shadow_frequency - (@shadow_frequency >> @sweep_shift) else 0 end else [0x3ff, @shadow_frequency + (@shadow_frequency >> @sweep_shift)].min end end |
#dac_output ⇒ Object
76 77 78 79 80 81 82 83 84 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 76 def dac_output return 0.0 unless @dac_enabled && @enabled ret = ((0xf & ( @wave_ram[@wave_duty_position >> 1] >> ((@wave_duty_position & 0x01) << 2) ))) >> @volume_shift (ret / 7.5) - 1.0 end |
#length ⇒ Object
57 58 59 60 61 62 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 57 def length return unless @length_enabled && @length_timer > 0 @length_timer -= 1 @enabled &= @length_timer > 0 end |
#read_nr3x(x) ⇒ Object
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 86 def read_nr3x(x) case x when 0 then ((@dac_enabled ? 0x80 : 0x00) | 0x7f) when 1 then 0xff when 2 then (@output_level << 5) | 0x9f when 3 then 0xff when 4 then (@length_enabled ? 0x40 : 0x00) | 0xbf else 0xff end end |
#step(cycles) ⇒ Object
43 44 45 46 47 48 49 50 51 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 43 def step(cycles) @cycles += cycles return if @cycles < @frequency_timer @cycles -= @frequency_timer @frequency_timer = (2048 - @frequency) * 2 @wave_duty_position = (@wave_duty_position + 1) % 32 end |
#step_fs(fs) ⇒ Object
53 54 55 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 53 def step_fs(fs) length if fs & 0x01 == 0 end |
#write_nr3x(x, val) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rubyboy/apu_channels/channel3.rb', line 97 def write_nr3x(x, val) case x when 0 @dac_enabled = val & 0x80 > 0 @enabled &= @dac_enabled when 1 @length_timer = 256 - val when 2 @output_level = (val >> 5) & 0x03 when 3 @frequency = (@frequency & 0x700) | val when 4 @frequency = (@frequency & 0xff) | ((val & 0x07) << 8) @length_enabled = val & 0x40 > 0 @length_timer = 256 if @length_timer == 0 @enabled = true if (val & 0x80) > 0 && @dac_enabled end end |