Explore the Gigatron music engine, using GLCC
Forum rules
Be nice. No drama.
Be nice. No drama.
Explore the Gigatron music engine, using GLCC
I know C, but I know Chiptune better. I love Chiptune, and I've always wanted Gigatron to have a powerful music creation software, like some trackers or MML, that can use all of Gigatron's musical features to make unique chip music. Just like PSG, SID or FM synthesis.
Now I'm going to realize my dream myself, the original music engine looks pretty good so far.
Let me briefly introduce my Gigatron music engine.
First of all thanks to lb3361, his efforts made my dream possible.
When it comes to music, getting the pitch right first, I initially had a little trouble with looking up the pitch table, but it was quickly resolved.
On about lines 15 to 39 is the actual music control array.
Each array can define channel, pitch, volume, waveform, start step.
Of course, the start step and volume here may be a little confusing. Let me explain.
When the Gigatron audio channel uses only one channel (any of the four channels), and only the square wave is used, the wavA will be able to control the volume of the square wave, in the range of 64-128, with decreasing volume. When two channels or more are used at the same time, the function of volume adjustment will not work.
As for the start step, since I'm using frameCount as a "timer", my music engine actually has a "timeline" that increases in sync with frameCount. When the length of the "timeline" is equal to the start step, the other values in the group are written to wavA, wavX, keyL, keyH, resulting in the correct note.
Based on these characteristics, using my music engine can dynamically change the pitch, volume, and waveform. If you can use these flexibly, I believe that Gigatron will not be much worse than PSG or SID in terms of music.
Of course I will not be satisfied with the present, I will always improve my music engine, I need everyone's ideas.
Currently I'm writing a Python based converter that can convert mml from mml2vgm standard syntax to arrays used by my music engine.
Now I'm going to realize my dream myself, the original music engine looks pretty good so far.
Let me briefly introduce my Gigatron music engine.
First of all thanks to lb3361, his efforts made my dream possible.
When it comes to music, getting the pitch right first, I initially had a little trouble with looking up the pitch table, but it was quickly resolved.
On about lines 15 to 39 is the actual music control array.
Each array can define channel, pitch, volume, waveform, start step.
Of course, the start step and volume here may be a little confusing. Let me explain.
When the Gigatron audio channel uses only one channel (any of the four channels), and only the square wave is used, the wavA will be able to control the volume of the square wave, in the range of 64-128, with decreasing volume. When two channels or more are used at the same time, the function of volume adjustment will not work.
As for the start step, since I'm using frameCount as a "timer", my music engine actually has a "timeline" that increases in sync with frameCount. When the length of the "timeline" is equal to the start step, the other values in the group are written to wavA, wavX, keyL, keyH, resulting in the correct note.
Based on these characteristics, using my music engine can dynamically change the pitch, volume, and waveform. If you can use these flexibly, I believe that Gigatron will not be much worse than PSG or SID in terms of music.
Of course I will not be satisfied with the present, I will always improve my music engine, I need everyone's ideas.
Currently I'm writing a Python based converter that can convert mml from mml2vgm standard syntax to arrays used by my music engine.
- Attachments
-
- step11_v5a_32k.gt1
- (7.67 KiB) Downloaded 99 times
-
- step11.c
- (2.37 KiB) Downloaded 94 times
Re: Explore the Gigatron music engine, using GLCC
You can also use wavX to introduce random noise or effects at 60Hz, (very useful for making the noise waveform sound more like real noise).
Incorrect, see my sound effects and speech/samples demo here:
https://www.youtube.com/watch?v=dZTAFZLg7Xs
Marcel and Walter came up with an amazingly complex sound engine in a tiny amount of bit-banging instructions, it's quite remarkable really.
Re: Explore the Gigatron music engine, using GLCC
I would be glad to have an explanation of how one uses wavA to adjust the volume of a channel.
I can see it has to do with this piece of code:
I understand how this can work with a square wave thanks to the high pass filter.
How does it work with triangles or sawtooths? Just by chopping the top?
Can it be done with a sine wave as in at67's music demo?
I can see it has to do with this piece of code:
Code: Select all
0177 09fa ld [y,$fa] 1186 ld([Y,wavA]) #18
0178 1407 ld $07,y 1187 ld(soundTable>>8,Y) #19
0179 8d00 adda [y,x] 1188 adda([Y,X]) #20
017a e87d blt $017d 1189 bmi(pc()+3) #21
017b fc7e bra $017e 1190 bra(pc()+3) #22
017c 203f anda $3f 1191 anda(63) #23
017d 003f ld $3f 1192 ld(63) #23(!)
How does it work with triangles or sawtooths? Just by chopping the top?
Can it be done with a sine wave as in at67's music demo?
Re: Explore the Gigatron music engine, using GLCC
It seems that ROMvX0 has many more functions, such as the ability to play voice samples. But the music composed of sine waves in that video does not seem to have volume modulation (although there is a volume meter in the video, but I feel that it is fake, the volume does not fade to 0 at all, but directly changes to 0), it still sounds the same as Pretty much the same as before. I know gtmidi. At present, a lot of Gigatron game music is generated using that. I found that gtmidi cannot define the volume envelope. When four channels are used at the same time(For example, to play some music with four parts), the volume value of these four channels cannot be changed dynamically, and the sound remains unchanged, and there is no function to dynamically change the waveform, so I Dissatisfied with gtmidi.at67 wrote: ↑14 Mar 2022, 19:03You can also use wavX to introduce random noise or effects at 60Hz, (very useful for making the noise waveform sound more like real noise).
Incorrect, see my sound effects and speech/samples demo here:
https://www.youtube.com/watch?v=dZTAFZLg7Xs
Marcel and Walter came up with an amazingly complex sound engine in a tiny amount of bit-banging instructions, it's quite remarkable really.
Maybe in the future, I will port my music engine to gtbasic and make it more efficient and flexible.
I know "Plays a 4 channel MIDI tune with proper volume per channel.", but that just sets the volume value at the beginning of each channel, and it stays the same after that, and doesn't mention anything like volume envelopes or adsr.Maybe the current ROMvX0 already has envelope-related functions, so I need to wait for the ROMvX0 to be released.I certainly hope ROMvX0 will bring new features.
Re: Explore the Gigatron music engine, using GLCC
It works with any waveform, it just adds a DC offset which compresses and clips the waveform eventually to DC. Sure this introduces distortion as the waveform collapses, but it gets harder to hear as the volume decreases, (obviously), and you have 6bit waveforms mixed into 8bit and then truncated to the highest 4 bits anyway, so whatever distortion you introduce by the volume compression is mostly lost in the quantisation noise and low quality analog filter.
64 = highest volume, 127 = lowest volume.
Re: Explore the Gigatron music engine, using GLCC
You can play voice samples without ROMvX0, ROMvX0 just lets you do it with about 10% of the vCPU cycles, the first voice sample I played on the Gigatron was done purely in vCPU code, you just have to think outside the box a bit.
Well your feelings are irrelevant and misguided when it comes to facts, the volume control in that demo is not fake.denjhang wrote: ↑15 Mar 2022, 01:41 But the music composed of sine waves in that video does not seem to have volume modulation (although there is a volume meter in the video, but I feel that it is fake, the volume does not fade to 0 at all, but directly changes to 0), it still sounds the same as Pretty much the same as before.
Of course it is, given I designed the gtMIDI format, wrote all the tools/players and pretty much the only one who has produced any music examples on the Gigatron.
gtMIDI has a -v option, maybe try using that?denjhang wrote: ↑15 Mar 2022, 01:41 I found that gtmidi cannot define the volume envelope. When four channels are used at the same time(For example, to play some music with four parts), the volume value of these four channels cannot be changed dynamically, and the sound remains unchanged, and there is no function to dynamically change the waveform, so I Dissatisfied with gtmidi.
Ok, here's a little hint...how did I generate the sound effects for Space Invaders and PucMon? Have a listen to them carefully, you'll notice that every one of the effects has individual ADSR control over all four channels. How did I do that?denjhang wrote: ↑15 Mar 2022, 01:41 I know "Plays a 4 channel MIDI tune with proper volume per channel.", but that just sets the volume value at the beginning of each channel, and it stays the same after that, and doesn't mention anything like volume envelopes or adsr.Maybe the current ROMvX0 already has envelope-related functions, so I need to wait for the ROMvX0 to be released.I certainly hope ROMvX0 will bring new features.
Anyway I'm not going to argue anymore, if you truly think the Gigatron does not have individual and full control over each channel's envelope, then good for you and good luck with your audio experiments.
Re: Explore the Gigatron music engine, using GLCC
In an old post, Marcel wrote something about "low frequency modulation" and I wondered whether I missed diverging. I am also wondering whether this distortion becomes audible with 8 bits audio, as in Hans' youtube (https://forum.gigatron.io/viewtopic.php ... t=10#p3014). The new board is still in the mail. I haven't heard it directly yet.at67 wrote: ↑15 Mar 2022, 08:41 It works with any waveform, it just adds a DC offset which compresses and clips the waveform eventually to DC. Sure this introduces distortion as the waveform collapses, but it gets harder to hear as the volume decreases, (obviously), and you have 6bit waveforms mixed into 8bit and then truncated to the highest 4 bits anyway, so whatever distortion you introduce by the volume compression is mostly lost in the quantisation noise and low quality analog filter.
64 = highest volume, 127 = lowest volume.
Re: Explore the Gigatron music engine, using GLCC
Marcel was referring to this:lb3361 wrote: ↑15 Mar 2022, 11:13 In an old post, Marcel wrote something about "low frequency modulation" and I wondered whether I missed diverging. I am also wondering whether this distortion becomes audible with 8 bits audio, as in Hans' youtube (https://forum.gigatron.io/viewtopic.php ... t=10#p3014). The new board is still in the mail. I haven't heard it directly yet.
"01fb wavX[1] ...............: Waveform modulation with `xora'"
Each channel can be XOR modulated with values from their corresponding wavX locations. It doesn't have to be at 60Hz, i.e. once per frame, but the results you get are highly dependent on when and how often you modify wavX and where the audio bit banger is in the current video frame. i.e. lots of random aliasing could be expected to occur if you modified wavX too frequently and without precise timing.
With respect to volume adjustment using DC offset, my emulator does a reasonable job of emulating the resultant sound, (ignoring noise caused by real electronics). What I hear in my emulator is very similar to what I hear to my hardware, for 4bit, 6bit and 8bit sound.
There is still a lot of quantisation noise generated even in 8bit mode, as it's not true 8 bit samples unless all 4 channels are active and being exercised peak to peak.
In the end the Gigatron audio HW has it's own distinct sound with 4 channel adjustable freq, volume, waveforms and low frequency ADSR; it's pretty amazing what it is capable of and in some ways is very similar to mid-late 1970's arcade machines where most of the sound effects were created manually and programmatically by adjusting ADSR 60 times per second, (which is exactly what I do for PucMon and Invader).
Re: Explore the Gigatron music engine, using GLCC
at67 wrote: ↑15 Mar 2022, 08:52You can play voice samples without ROMvX0, ROMvX0 just lets you do it with about 10% of the vCPU cycles, the first voice sample I played on the Gigatron was done purely in vCPU code, you just have to think outside the box a bit.
Well your feelings are irrelevant and misguided when it comes to facts, the volume control in that demo is not fake.denjhang wrote: ↑15 Mar 2022, 01:41 But the music composed of sine waves in that video does not seem to have volume modulation (although there is a volume meter in the video, but I feel that it is fake, the volume does not fade to 0 at all, but directly changes to 0), it still sounds the same as Pretty much the same as before.
Of course it is, given I designed the gtMIDI format, wrote all the tools/players and pretty much the only one who has produced any music examples on the Gigatron.
gtMIDI has a -v option, maybe try using that?denjhang wrote: ↑15 Mar 2022, 01:41 I found that gtmidi cannot define the volume envelope. When four channels are used at the same time(For example, to play some music with four parts), the volume value of these four channels cannot be changed dynamically, and the sound remains unchanged, and there is no function to dynamically change the waveform, so I Dissatisfied with gtmidi.
Ok, here's a little hint...how did I generate the sound effects for Space Invaders and PucMon? Have a listen to them carefully, you'll notice that every one of the effects has individual ADSR control over all four channels. How did I do that?denjhang wrote: ↑15 Mar 2022, 01:41 I know "Plays a 4 channel MIDI tune with proper volume per channel.", but that just sets the volume value at the beginning of each channel, and it stays the same after that, and doesn't mention anything like volume envelopes or adsr.Maybe the current ROMvX0 already has envelope-related functions, so I need to wait for the ROMvX0 to be released.I certainly hope ROMvX0 will bring new features.
Anyway I'm not going to argue anymore, if you truly think the Gigatron does not have individual and full control over each channel's envelope, then good for you and good luck with your audio experiments.
I know some of my opinions or feelings are inaccurate, so I won't be stubborn that the Gigatron can't change the volume when multiple channels are enabled. I would have preferred the Gigatron to be more powerful in terms of audio.
Maybe I'm getting the wrong feeling just because my sound engine has so many flaws that it needs continuous improvement. Including the feeling that I get bugs from a flawed sound engine is also quite normal.
Your video does have multiple channels adjusting the volume, but I can't hear the volume change for music using a sine wave (which makes me think there's no way to adjust the volume, so I feel like that's fake. It often doesn't feel right ), I can hear other volume changes using noise and square waves.
By the way gtmidi, I don't actually know gtmidi, my impression of all Gigatron's music is only from Piano.gt1 and Tetronis.gt1, PucMon.gt1 and the like. Tetronis.gt1 in particular, if I heard correctly, all the music in this game has no volume envelope.
Re: Explore the Gigatron music engine, using GLCC
The issue here is that it is way more powerful than you think, experiment more, lament less...
I should be asleep, but I am annoyed, why am I annoyed? Who the F knows, anyway here is a video of code that I wrote in the last 45minutes that conclusively proves what the Gigatron is capable of, if you refuse to accept this proof, then I give up.
https://www.youtube.com/watch?v=-RmvJREUqcU
Here is the entirety of the source code written in gtBASIC, there is no faking of the waveform, the oscilloscope samples address 0x13, (XOUT), as fast as it can to give a representation of the audio being generated.
Good luck :/
P.S. Yes it uses ROMvX0 instructions, but that is completely irrelevant, the same thing works with any ROM, just much less efficiently in terms of vCPU cycles.
I should be asleep, but I am annoyed, why am I annoyed? Who the F knows, anyway here is a video of code that I wrote in the last 45minutes that conclusively proves what the Gigatron is capable of, if you refuse to accept this proof, then I give up.
https://www.youtube.com/watch?v=-RmvJREUqcU
Here is the entirety of the source code written in gtBASIC, there is no faking of the waveform, the oscilloscope samples address 0x13, (XOUT), as fast as it can to give a representation of the audio being generated.
Good luck :/
P.S. Yes it uses ROMvX0 instructions, but that is completely irrelevant, the same thing works with any ROM, just much less efficiently in terms of vCPU cycles.
Code: Select all
_runtimePath_ "../runtime"
_runtimeStart_ &hFFFF
_arraysStart_ &hFFFF
_codeRomType_ ROMvX0
_enable6BitAudioEmu_ ON 'experimental
const SMP_A = &h8000
const SMP_N = 64
const SMP_H = 64
const OSC_X = 49
const OSC_Y = (120 - 64)/2 + 4
const OSC_A = &h0800 + OSC_Y*256 + OSC_X
const OFFSCREEN=&h78A0
samplesAddr = SMP_A
def byte(SMP_A, 0, 1, SMP_N) = 0 'buffer A
def byte(SMP_A + &h40, 0, 1, SMP_N) = 0 'buffer B
'alloc offscreen scrolling areas, (<address>, <optional width>, <optional height>, <optional offset>)
alloc OFFSCREEN, 96, 8, &h0100
def byte(&h0702, x, 0.0, 360.0, 64, 4) = sin(x)*31.0 + 32.0
v1=0 : v2=v1 : v3=v2 : v4=v3
s1=1 : s2=s1 : s3=s2 : s4=s3
scrollPos=0 : scrollTmp=scrollPos
gosub initialise
init textScroll
sound off
f = 0
repeat
wait
set SOUND_TIMER, 5
gosub sinewave
gosub oscilloscope
inc f.lo
if (f.lo LSR 1) AND 1 then v1 = v1 + s1
if (f.lo LSR 2) AND 1 then v2 = v2 + s2
if (f.lo LSR 4) AND 1 then v3 = v3 + s3
if (f.lo LSR 8) AND 1 then v4 = v4 + s4
if (v1 > 63) OR (v1 < 0) then s1 = -s1
if (v2 > 63) OR (v2 < 0) then s2 = -s2
if (v3 > 63) OR (v3 < 0) then s3 = -s3
if (v4 > 63) OR (v4 < 0) then s4 = -s4
forever
sinewave:
sound on, 1, 2000, v1, 2
sound on, 2, 2500, v2, 2
sound on, 3, 3000, v3, 2
sound on, 4, 3500, v4, 2
return
oscilloscope:
addrA = samplesAddr
'erase waveform buffer B
set FG_COLOUR, &h10
sAddr = samplesAddr XOR &h40
for i=SMP_N-1 downto 0
asm
LD 0x13 'sample waveform
POKE+ _addrA 'save to buffer
LDWI _OSC_A
OSCPX _sAddr, _i
endasm
'pixelAddr = (((peek(sAddr + i)) AND &hFC) LSR 2) LSL 8
'poke OSC_A + pixelAddr + i, &h10
next i
'draw waveform buffer A
set FG_COLOUR, &h1D
for i=SMP_N-1 &downto 0
asm
LDWI _OSC_A
OSCPX _samplesAddr, _i
endasm
'pixelAddr = (((peek(samplesAddr + i)) AND &hFC) LSR 2) LSL 8
'poke OSC_A + pixelAddr + i, &h1D
next i
'toggle waveform buffers
samplesAddr = samplesAddr XOR &h40
return
textScroll:
asm
PUSH
LDWI &h01E1 'bottom banner
STW _scrollTmp
LDW _scrollPos
POKE _scrollTmp
INC _scrollPos
POP
endasm
ret
initialise:
mode 2
set BG_COLOUR, &h30
cls
cls OFFSCREEN, 96, 8
set FG_COLOUR, &h20
rectf OSC_X - 3, OSC_Y - 3, OSC_X + SMP_N + 2, OSC_Y + SMP_H + 2
set FG_COLOUR, &h10
rectf OSC_X, OSC_Y, OSC_X + SMP_N - 1, OSC_Y + SMP_H - 1
set FG_COLOUR, &h3F
tscroll off
tclip off
set FG_COLOUR, &h0F
at 2, 112 : print "Sinewave Envelopes!.."
return