Skip to content

Commit

Permalink
Correct frequency shifts on wave channel
Browse files Browse the repository at this point in the history
This mirrors the tone channels as far as implementation, and corrects
an issue where the sample buffer was getting misaligned on frequency
updates that didn't start new notes.
  • Loading branch information
zeta0134 committed Jan 15, 2017
1 parent 58d6699 commit bf90cf1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
32 changes: 24 additions & 8 deletions gameboy/audio.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ audio.reset = function()
audio.tone2.frequency_last_update = 0 -- in cycles
audio.tone2.period_counter = 0
audio.tone2.wave_duty_counter = 0
audio.tone1.frequency_shadow = 0
audio.tone2.frequency_shadow = 0

audio.wave3.debug_disabled = false
audio.wave3.enabled = false
Expand All @@ -62,6 +62,10 @@ audio.reset = function()
audio.wave3.period = 0 -- in cycles
audio.wave3.continuous = false
audio.wave3.base_cycle = 0
audio.wave3.frequency_last_update = 0 -- in cycles
audio.wave3.period_counter = 0
audio.wave3.sample_index = 0
audio.wave3.frequency_shadow = 0

audio.noise4.debug_disabled = false
audio.noise4.volume_initial = 0
Expand Down Expand Up @@ -289,9 +293,12 @@ io.write_logic[ports.NR34] = function(byte)
local freq_value = freq_high + freq_low

audio.wave3.period = 64 * (2048 - freq_value)
audio.wave3.period_conter = (2048 - freq_value)
audio.wave3.frequency_shadow = freq_value
audio.wave3.continuous = continuous
if restart then
audio.wave3.base_cycle = timers.system_clock
audio.wave3.sample_index = 0
end
end

Expand Down Expand Up @@ -475,17 +482,26 @@ audio.wave3.generate_sample = function(clock_cycle)
local duration = clock_cycle - wave3.base_cycle
if wave3.enabled then
if wave3.continuous or (duration <= wave3.max_length) then
local period = wave3.period
local period_progress = (duration % period) / (period)
local sample_index = math.floor(period_progress * 32)
if sample_index > 31 then
sample_index = 31
--local period = wave3.period
--local period_progress = (duration % period) / (period)
--local sample_index = math.floor(period_progress * 32)
while clock_cycle > wave3.frequency_last_update + 2 do
wave3.period_counter = wave3.period_counter - 1
if wave3.period_counter <= 0 then
wave3.period_counter = (2048 - wave3.frequency_shadow)
wave3.sample_index = wave3.sample_index + 1
if wave3.sample_index >= 32 then
wave3.sample_index = 0
end
end
wave3.frequency_last_update = wave3.frequency_last_update + 2
end
local byte_index = bit32.rshift(sample_index, 1)

local byte_index = bit32.rshift(wave3.sample_index, 1)
local sample = io.ram[0x30 + byte_index]
-- If this is an even numbered sample, shift the high nybble
-- to the lower nybble
if sample_index % 2 == 0 then
if wave3.sample_index % 2 == 0 then
sample = bit32.rshift(sample, 4)
end
-- Regardless, mask out the lower nybble; this becomes our sample to play
Expand Down
35 changes: 32 additions & 3 deletions love/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ function play_gameboy_audio(buffer)
love.audio.play(source)
end

function dump_audio(buffer)
-- play the sound still
play_gameboy_audio(buffer)
-- convert this to a bytestring for output
local output = ""
local chars = {}
for i = 0, 32768 - 1 do
local sample = buffer[i]
sample = math.floor(sample * (32768 - 1)) -- re-root in 16-bit range
chars[i * 2] = string.char(bit32.band(sample, 0xFF))
chars[i * 2 + 1] = string.char(bit32.rshift(bit32.band(sample, 0xFF00), 8))
end
output = table.concat(chars)

love.filesystem.append("audiodump.raw", output, 32768 * 2)
end

function love.load(args)
sound_buffer = love.sound.newSoundData(32768, 32768, 16, 2)
love.graphics.setDefaultFilter("nearest", "nearest")
Expand Down Expand Up @@ -169,9 +186,7 @@ function love.load(args)
window_title = "LuaGB - " .. gameboy.cartridge.header.title
love.window.setTitle(window_title)

gameboy.audio.on_buffer_full(function(buffer)
play_gameboy_audio(buffer)
end)
gameboy.audio.on_buffer_full(play_gameboy_audio)

love.audio.setVolume(0.1)
end
Expand Down Expand Up @@ -270,6 +285,20 @@ action_keys.kp3 = function() toggle_panel("oam") end
action_keys.kp4 = function() toggle_panel("disassembler") end
action_keys.kp5 = function() toggle_panel("audio") end

local audio_dump_running = false
action_keys.a = function()
if audio_dump_running then
gameboy.audio.on_buffer_full(play_gameboy_audio)
print("Stopped dumping audio.")
audio_dump_running = false
else
love.filesystem.remove("audiodump.raw")
gameboy.audio.on_buffer_full(dump_audio)
print("Started dumping audio to audiodump.raw ...")
audio_dump_running = true
end
end

action_keys.lshift = function() profile_enabled = not profile_enabled end

local input_mappings = {}
Expand Down

0 comments on commit bf90cf1

Please sign in to comment.