mml2vgm icon indicating copy to clipboard operation
mml2vgm copied to clipboard

Gigatron sound engine support

Open denjhang opened this issue 2 years ago • 29 comments

Gigatron is an 8bit computer composed of only 7400 series chips, and it has a 4-channel PSG. At present, I have developed a music engine using C language for Gigatron. If you are interested, I hope you can add Gigatron to the mml2vgm project. I can provide all the required materials, which are legal and open source. Actually I want to be able to use mml2vgm to convert mml to an array of the gigatron music engine, the so called output function.

denjhang avatar Apr 18 '22 06:04 denjhang

おぉそれは凄いですね! PSGチップは何なのでしょうか? デバッグ環境やエミュレーション環境が揃うなら、少し興味がありますw

kuma4649 avatar Apr 18 '22 12:04 kuma4649

I have a debug and emulation environment running under Windows 10, and of course Windows 7 works as well. gtemuAT67 v1.0.9R.zip gtemuAT67 is the latest gigatron emulator with complete functions. The compressed package contains the binary compiled by myself, which can be used directly after decompression. The main program is gtemuAT67.exe, use Ctrl+H to open the help file. Use Ctrl+B to browse the local gt1 file and load it. Press the Z key to change the display mode, in short, it can make functions such as printf that need to refresh the screen run faster.

denjhang avatar Apr 18 '22 12:04 denjhang

glcc-1.4.zip GLCC is the ported version of LCC in gigatron, which has many giagron unique header files, all located in glcc\lib\gigatron-lcc\include\gigatron The files in the compressed package are also precompiled versions. You can use them directly after decompressing. Note that it is a command line program. The main program is glcc\bin\glcc

I usually use the following statement to compile test.c glcc -rom=v5a -map=conx test.c -o test_v5a_32k.gt1 Note that the test.gt1 file is the gigatron executable.

denjhang avatar Apr 18 '22 12:04 denjhang

gigatron sound engine.zip The engine.c in the compressed package is the music engine I wrote using glcc, and it can work normally. mml2gt_note.xlsx is the pitch table of the gigatron music engine, and the other txt files are my functional description (in Chinese) of the music engine.

denjhang avatar Apr 18 '22 12:04 denjhang

test_envlope.zip Here is an example of the steps I envisioned to convert mml to gigatron music, explained in great detail (in Chinese).

denjhang avatar Apr 18 '22 12:04 denjhang

step22.zip This is an example of the gigaron music engine with music, the source code and the gigatron executable in the zip.You can run it directly in the emulator.

denjhang avatar Apr 18 '22 13:04 denjhang

My music engine may not be fully functional, since gigaron audio is even WSG-like, i.e. waveforms can be replaced and samples may be played. Here is the official documentation for gigatron audio. Audio.txt

denjhang avatar Apr 18 '22 13:04 denjhang

Of course, gigatron can not only use glcc, but also some development languages dedicated to gigatron, such as gtbasic, gcl, vcpu assembly and native assembly. But I don't know much about them. I think gtbasic and gcl can also implement such a music engine, and gtbasic is much more powerful and efficient than glcc. gcl is a low-level language.

denjhang avatar Apr 18 '22 13:04 denjhang

Briefly introduce the audio of gigatron: 4-channel PSG/WSG. Support pitch and can support pitch bend. Volume adjustment can realize software volume envelope and waveform dynamic switching. Four built-in waveforms: triangle wave, sawtooth wave, square wave, periodic metal noise. The built-in waveform is in a specific area in RAM, so it can be replaced.

denjhang avatar Apr 18 '22 13:04 denjhang

gtemuAT67.exeを実行するとフルスクリーンになってしまうのですが、ウィンドウモードはありますか?

kuma4649 avatar Apr 19 '22 13:04 kuma4649

You can modify the contents of graphics_config.ini to switch between fullscreen and windowed, as well as modify the display resolution. ` [Monitor] ; case sensitive Fullscreen = 1 ; windowed = 0, fullscreen = 1 Resizable = 1 ; disable/enable resizable, only works in windowed mode Borderless = 0 ; disable/enable borderless, only works in windowed mode and overrides Resizable VSync = 0 ; disable/enable VSync, (not normally of value to enable) FixedSize = 0 ; disable/enable monitor independant size, ignores everything except Width and Height Filter = 0 ; 0=Nearest, 1=Linear, 2=Best
Width = 320 ; Desktop or , only works in windowed mode Height = 240 ; Desktop or , only works in windowed mode ScaleX = 1.5 ; , only works in windowed mode ScaleY = 1.5 ; , only works in windowed mode PosX = 40 ; , only works in windowed mode PosY = 40 ; , only works in windowed mode

`

denjhang avatar Apr 19 '22 13:04 denjhang

エミュレータのソースコードはありますでしょうか

kuma4649 avatar Apr 19 '22 20:04 kuma4649

エミュレータのソースコードはありますでしょうか

https://github.com/kervinck/gigatron-rom/tree/master/Contrib/at67 The gtemuAT67 emulator source code is located here. I was able to compile it successfully using SDL2 and the latest version of GCC. Of course, you can also use VS2019 and the like to compile. Of course, other contents in this folder are also important, including the source code of the gtbasic compiler, as well as many gtbasic-based program examples. Since at67 has not organized a more systematic gtbasic description, I have not learned to use it for the time being.

denjhang avatar Apr 19 '22 20:04 denjhang

少しソースをよみましたけども、音声処理だけをC#で再現させるのはかなり手間がかかると思います。 ここができないと、MDSoundに追加できなく、mml2vgmでも使用できないです。 何とかなりませんか?

kuma4649 avatar Apr 19 '22 21:04 kuma4649

If it is difficult to achieve the original gigatron audio simulation, it can be simplified. I simply understand gigatron as a 4-channel WSG, but the output audio has only 4-bit samples (6-bit or even 8-bit samples can also be achieved by hardware modification). I have a register table of the audio part of gigatron here, you can refer to it to write a C# audio core.

Of course, even though I can't play gigatron audio with MDSound, I'd be more than content to just convert the mml to a gigatron executable.

denjhang avatar Apr 19 '22 22:04 denjhang

Sound basics

There is a secondary output port (XOUT) with 8 bits. It is split in 4 bits for the LEDs, and 4 bits that go into a 4-bit DAC resistor array to form 16 output levels. By default, we have 4 sound channels in software that are 6 bits each internally. At the beginning of each scan line, one of these software channels gets updated to compute a new 6-bits sample. So one software channel update happens during every horizontal VGA sync pulse. After every 4 scan lines, the top 4 bits of their sum gets output to the sound part of the XOUT register.

The 4 software channels can independently generate a tone and a waveform. Some of the preprogrammed waveforms are triangle, sawtooth, pulse and something that looks like noise, but sounds a bit metallic. It can all be changed of course, as it is all software-defined.

Controls

There are 6 bytes for each sound channel. They're at the top of page 1..4.

截图未命名0420061219

The 6 bytes are:

wavA Modulation after table lookup with ADD operation and optional clipping (can approximate PWM with this) wavX Modulation of index with XOR operation keyL:keyH 15-bit frequency (bit7 of keyL should be 0). There is a lookup table on page 7 in ROM oscL:oscH 15-bit phase, automatically incremented with keyL:keyH every 4 scan lines (1 channel per scan line).

(You typically don't write into oscL,oscH)

The sound synthesises runs during every horizontal pulse of the VGA signal. It is implemented twice, once for visible lines and once for vertical blank. The sample update runs in the videoC lines, or their equivalents in vBlank. A video frame has 521 lines, so there is no fixed mapping from video line to channel.

In pseudo code:
----------------------------------------------------------------
For every channel:
  "osc" += "key"                // Advance phase
  byte i = oscH & 0xfc          // Keep only the highest 6 bits
       i ^= wavX                // Low 2 bits select waveform.
                                // High 6 bits give effects.
       i = soundTable[i] + wavA // More sound effect options
       i = i&128 ? 63 : i&63
  sample += i

Every 4 scan lines:
  1. Emit sample & 0xf0         // The DAC has 4-bits
  2. Reset sample
       sample = 3               // Why 3? Any value <=3 (=255-4*63) will
                                // work, and we have only 1 cycle available
       st $03,[$03]             // for this, so operand is address and value
----------------------------------------------------------------

Notes

The ROM has a handy lookup table for the frequencies that is calculated for a 6.25 MHz system doing 200 cycles per horizontal sync.

Note: index 0 = 0 Hz = OFF

ROM table at $0900
----------------------------------------------------------------
notesTable:   0900 0000  ld   $00
              0901 0000  ld   $00
              0902 0045  ld   $45         ;C-0 (16.4 Hz)
              0903 0000  ld   $00
              0904 0049  ld   $49         ;C#0 (17.3 Hz)
              0905 0000  ld   $00
[...]
              09be 001a  ld   $1a         ;A#7 (3729.3 Hz)
              09bf 007a  ld   $7a
----------------------------------------------------------------

The waveforms are stored in RAM page 7. They are initialised once at boot time and then never again (so not with soft reset). [Edit: from ROM v4 onwards, these are reinitialised with each soft reset!] You select one with the low two bits of wavX. They look like below. The page is initialised as noise (0), triangle (1), pulse (2) and sawtooth (3). You can change them, but then the next application will see your changes. You shouldn't change the sawtooth waveform (3) because it doubles as a right-shift-2 lookup table for the SYS_Unpack_56 function used by Pictures.

Image: https://forum.gigatron.io/download/file.php?id=8

denjhang avatar Apr 19 '22 22:04 denjhang

pseudo Codeだと詳細がわからないのですが、それに該当する実際のコードはどこにありますでしょうか

kuma4649 avatar Apr 20 '22 09:04 kuma4649

https://twitter.com/kumakumakumaT_T/status/1516903532431286272?s=20&t=b8IqlU_ApMxgPlml_BdICA

kuma4649 avatar Apr 20 '22 22:04 kuma4649

こんな感じでよいのかしら?

kuma4649 avatar Apr 20 '22 22:04 kuma4649

こんな感じでよいのかしら?

Probably so, actually I don't know the underlying principles very well.(笑)

denjhang avatar Apr 21 '22 02:04 denjhang

Here's a gtemu implemented using only a single c source that you can take a look at. It's in the compressed package.I think this code explains how Gigatron works. gtemu.zip .

denjhang avatar Apr 21 '22 02:04 denjhang

gtemu.zip

私が欲しいものとは違うかな...

kuma4649 avatar Apr 21 '22 09:04 kuma4649

https://twitter.com/kumakumakumaT_T/status/1517112906747641857?s=20&t=UXiZexo8FmzdKQQ7c6b7Iw

kuma4649 avatar Apr 21 '22 12:04 kuma4649

I simply think that wavA can adjust the volume, when wavA is between 64 and 127 can adjust the volume. wavX is the selection waveform, the range is 0 to 3. keyH and keyL together control the pitch. I don't change oscH and oscL. So I don't know these two either.

When soundTimer = 1, a sound will be produced, and every sixtieth of a second or so, the value is automatically set to 0. If sound is required, you must manually set this system variable to 1. As for changing the wavetable, it is necessary to modify the data located on the seventh page in the memory.

denjhang avatar Apr 21 '22 13:04 denjhang

大体はその理解であっていると思います

kuma4649 avatar Apr 21 '22 13:04 kuma4649

Ok, so how is it going now, with the video you uploaded, I don't think there's anything wrong with it.

denjhang avatar Apr 24 '22 10:04 denjhang

進捗無しです(^^;

kuma4649 avatar Apr 25 '22 21:04 kuma4649

https://twitter.com/kumakumakumaT_T/status/1520747897821986817?s=20&t=uGiuGBLYbi66yYG-QJXfQA

kuma4649 avatar May 01 '22 12:05 kuma4649

I think it should be released.

denjhang avatar May 07 '22 12:05 denjhang