Explore the Gigatron music engine, using GLCC

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
denjhang
Posts: 54
Joined: 02 May 2021, 01:25
Location: yuenan
Contact:

Explore the Gigatron music engine, using GLCC

Post by denjhang »

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.
Attachments
step11_v5a_32k.gt1
(7.67 KiB) Downloaded 96 times
step11.c
(2.37 KiB) Downloaded 90 times
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Explore the Gigatron music engine, using GLCC

Post by at67 »

denjhang wrote: 14 Mar 2022, 16:43 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.
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).
denjhang wrote: 14 Mar 2022, 16:43 When two channels or more are used at the same time, the function of volume adjustment will not work.
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.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: Explore the Gigatron music engine, using GLCC

Post by lb3361 »

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:

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(!)
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?
denjhang
Posts: 54
Joined: 02 May 2021, 01:25
Location: yuenan
Contact:

Re: Explore the Gigatron music engine, using GLCC

Post by denjhang »

at67 wrote: 14 Mar 2022, 19:03
denjhang wrote: 14 Mar 2022, 16:43 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.
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).
denjhang wrote: 14 Mar 2022, 16:43 When two channels or more are used at the same time, the function of volume adjustment will not work.
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.
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.
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.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Explore the Gigatron music engine, using GLCC

Post by at67 »

lb3361 wrote: 15 Mar 2022, 00:32 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?
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.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Explore the Gigatron music engine, using GLCC

Post by at67 »

denjhang wrote: 15 Mar 2022, 01:41 It seems that ROMvX0 has many more functions, such as the ability to play voice samples.
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.
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.
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 I know gtmidi. At present, a lot of Gigatron game music is generated using that.
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.
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.
gtMIDI has a -v option, maybe try using 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.
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?

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.
lb3361
Posts: 360
Joined: 17 Feb 2021, 23:07

Re: Explore the Gigatron music engine, using GLCC

Post by lb3361 »

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.
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
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Explore the Gigatron music engine, using GLCC

Post by at67 »

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.
Marcel was referring to this:
"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).
denjhang
Posts: 54
Joined: 02 May 2021, 01:25
Location: yuenan
Contact:

Re: Explore the Gigatron music engine, using GLCC

Post by denjhang »

at67 wrote: 15 Mar 2022, 08:52
denjhang wrote: 15 Mar 2022, 01:41 It seems that ROMvX0 has many more functions, such as the ability to play voice samples.
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.
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.
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 I know gtmidi. At present, a lot of Gigatron game music is generated using that.
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.
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.
gtMIDI has a -v option, maybe try using 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.
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?

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.
at67
Site Admin
Posts: 647
Joined: 14 May 2018, 08:29

Re: Explore the Gigatron music engine, using GLCC

Post by at67 »

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.

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
Post Reply