351

(20 replies, posted in Sinclair)

We're explored a lot in the area of stand alone beeper music, one that takes nearly all CPU time, but only scratched the surface of the music that plays along some action on the screen. Could be interesting to try this out too. Here is my thoughts.

Early ZX games often were attempting to play some music alongside the gameplay - for example, Antics or Manic Miner.

There is three methods to play beeper music during gameplay.

First is to just put a very short duration beep after each frame. Causes major slowdown to the game and staccato sounding music, but with relatively clean sound.

Second, very often employed to play sound effects, is to play short duration beeps and noises during leftover time of a TV frame, instead of HALT, sound loop stopped with a new interrupt. It introduces major 50 Hz buzz, but no slowdown. Requires to have enough leftover time, though.

Third, I think is the most obscure one, is applicable to games where frame time is evenly distributed around some nearly constant-time process (rendering usually), so they can call sound routine a number of times per frame with mostly constant pace. That likely would suit well for multicolor engines such as Nirvana. They can have a short sample buffer, prepared outside the raster, then read and output value from the buffer to #FE each N scanlines (very low sample rate, but may work for some cases).


The result in existing old games, I think, almost unversally could be described as 'annoying'. But I don't think that's just because of some general issue with the idea itself, rather with poor execution. Most games with in-game music use monophonic single beeps, single simplest timbre (square), combined with poor music (mostly crude renditions of classics), mostly without any pauses (constant beeps/buzz), no dynamics at all. If either or both of the issues (tech and composition) will be improved, the result should become much more pleasant.

i don't think polyphony is a must, as my practice (yet to be released) with PC Speaker shown that it is very well possible to pull quite impressive illusion of multiple voices with proper authoring tools (easy multiple-to-single channel voice management) and composing. Nice to have anyways, if possible.

Timbre/tone control would help greatly, especially pseudo volume control - it would bring the dynamics, and timbre control would help with sound variety. Noise generator would improve the percussion too, even though PC Speaker experience shows that even square tone alone is enough to make a good rythm parts.

Proper composition of new original music, with good variety and dynamics, is of course would bring the greatest improvement to the matter.

To avoid mixing up the stuff in the next gen engine thread or scattering it around, collecting all info here:


There is a few games with seemingly unique engines that weren't used anywhere else. What they has in common is the strong vibrato on the tone channel, which I think is underexplored area in modern engines.

Saboteur and Sigma 7 engines has one tone channel and noise drums, Sigma 7 also has phasing effects going on the tone channel.

Galaxy Force has two channels of tone and noise drums. The second channel sounds somewhat like ZX-10.

Another game that seemingly has the same weird and rare engine as Galaxy Force - Count Duckula. The same year, but seems that it has totally different authors.


Another unique sounding engine that does not seem to be used anywhere else is in the game Transmutter.

353

(135 replies, posted in Sinclair)

I thought we had one, but I wasn't able to locate, and this one has my post with mention of Galaxy Force and few other interesting old engines. Better to split it to a separate thread anyways.

354

(135 replies, posted in Sinclair)

Another game that seemingly has the same weird and rare engine as Galaxy Force - Count Duckula. The same year, but seems that it has totally different authors.

I was totally sure 3 was Wham. It sounds exactly like Wham, pure square, the carrier hiss, the echo trick at the beginning. Then the drums kick in, typical LS ones. Maybe it is the third version of his engine? Going to investigate.

Edit: more likely that's the first LS engine, or maybe an engine that inspired Lyndon to make his own (music credited for Barry Leitch). Main sound loop looks very similar to Wham, but with some changes in registers usage.

356

(51 replies, posted in Sinclair)

I'm on Windows 7 x64.

Tried it few more times, there was no crash, but the app remains in the processes. Maybe this help to locate the issue.

357

(51 replies, posted in Sinclair)

Great stuff, more the merrier, especially with new ideas on tracker internal architectures and UI design.

One bug report so far - when I closed program, Windows error occured, 'the program was stopped, close it?' (not sure how it is in english, I'm on localized Windows).

358

(7 replies, posted in Sinclair)

Yes, import function is part of each engine script, frontend only provides file selection dialog. I just reused the same import function over and over again, as it was designed for Phaser3.

359

(22 replies, posted in Sinclair)

Default settings for drum is 20 (slide) and 2 (pitch).

On a side note, yeah, there is a little mess with lack of zero value in 1tracker. I didn't thought it could be important when I started the project, now it would be quite difficult to add it, all engine scripts would need a fix to support that. But I'll get to it eventually, as it makes things more obvious (0 to disable something).

360

(166 replies, posted in Sinclair)

No callbacks there, that's just a basic player library, after all. The only way to get actual play position is to hook up to the emulated RAM in GME, which likely will require to customize its code. Engine scripts then could have a special callback that would watch for specific RAM addresses and translate them into position to display, in a way specific for each engine and engine script.

361

(166 replies, posted in Sinclair)

Vortex Tracker II actually needs an alternative (there is few already, but not very popular). The reason is that VT2 basically a Pro Tracker 3 (Zx Spectrum's) clone, limited by its original, slightly expanded format. While it is really good for music in general, there were even better formats on ZX (ASC Sound Master, for one), and there is also specific requirements for music in games that needs it to be as compact as possible, but PT3 format isn't much effective in this regard (a song takes 5K easily). There is no need to replace VTII, but providing alternative to handle specific cases would be nice.

Cursor following song while it is playing would be pretty convinient, but unfortunately it is pretty tricky (not impossible) to implement it due to the multi-engine concept itself. Tracker would need to somehow get actual playing position, but that needs to be reported by each engine, and not all engines actually use rows and speed concept internally (some just store delays between events). Another idea is to just move cursor approximately, depending on play time, but this needs very precise speed-to-time translation, which is again very tricky, because beeper engines tend to have major tempo fluctuations. So yes, at the time being we have to live without it.

362

(37 replies, posted in Other Platforms)

Yeah, good luck with all that.

363

(37 replies, posted in Other Platforms)

Proteus that costs like $1000 is certainly an overkill for this.

For this particular application I didn't need to know exact cycle count or do assembly optimization. If I was to write AVR assembly code by hand, I sure would know how many cycles it takes - it is common practice to memorize opcode cycles (super easy on AVR), and count them in time critical parts when writing for 8/16 bit systems in assembler.

What I needed was just to see compiler generated code, to check if particular changes in C code makes resulting code longer or shorter, which is totally enough to estimate efficiency of edits - another common practice when writing for 8/16 bit systems in C. It is super simple task, I don't see why it should be overcomplicated like that with all that porting to other environments, using simulators, debuggers, and stuff like that. All it really takes is just a quick glance at the compiler output, which is normally fully exposed to the user. It is just an Arduino IDE's quirk that it hides the intermediate assembly.

364

(37 replies, posted in Other Platforms)

Thanks for explaination of the issue.

As for looking up to the generated code, I have my doubts about these ideas. First, I just need to see what compiler spits out, in order to see how efficiently certain C code compiles with certain C compiler. That's purely software issue, normally you don't even have to do anything to just get the intermediate assembly output. Using simulators, switching platforms, using JTAG or any extra HW is all total overkill for this. Also, I doubt that latest Arduino and AVR Studio 4.18 use the same exact C compiler with same exact options, and if this is not the case, it just won't help at all.

I have no doubts that a lot more can be pulled off with Arduino or plain AVR. Something along the lines of Casio CZ series or Korg Poly 800 (with external filter) should be totally doable. We here not trying to squeeze out all that is possible, we're just playing with concepts of porting over ZX beeper engines, with all their quirks and specifics, and maybe applying some of this experience to do like 'super' versions of those engines. And using Arduino over plain AVR is an important feature, because that's certainly more accessible platform for strangers and newcomers.

365

(166 replies, posted in Sinclair)

In general we can have Atari 8-bit and C64 stuff in 1tracker, as Game Music Emu supports both SAP and SID. For better convinience we'd need to make a 6502 assembler in AngelScript, to be able to use source assembly code instead of precompiled binaries, but at first it can be done with just binary (used to be like that before adding Z80Ass).

In particular for this synth, yes, first step would be to reverse it into a compilable 6502 source and data format description. I'm also not sure, maybe it would be easier to just make a new one from scratch, unless it has some unique hard-to-replicate features.

We can have fun and do an AY-3-8910 alternative, too. People were asking if it possible to do something like that for years.

366

(166 replies, posted in Sinclair)

A new version is up. I reworked engine selection, now it caches all engines info into files, because number of the engines got large enough to make scanning time kind of tiresome. A few minor fixes as well. Added Octode 2k15, PWM, and 2k16 flavours, so all Octodes supported now. Also added a very simple SN76489 engine (virtual, VGM export only, no player code at all).

The list slowly getting longer. Meanwhile, I had thoughts on the matter (not looking to the code, though), and here is what I think so far.

For oldest PCs that runs pure DOS, like XT/AT/386 maybe, the usual timed code approach may be viable, with a delay in the main loop that automatically gets adjusted at startup by measuring actual CPU speed. What is possible to do is limited by the speed of the slowest targeted system with shortest possible delay. So basically a little bit less than a 4.7 MHz 8088 can do, which is the same ballpark as ZX Spectrum. Engine types would be not limited in this case, all approaches should work. Music playing would stop everything else.

However, considering how vastly different PCs and their speeds are, plus the possiblity to run something in background, and that every PC has 8253 PIT to generate interrupts, more universal apporach would be to utilize the interrupts. Now we can have quite good sound loop sample rate (when it runs on a PC that is fast enough), but sound generation methods gets limited. We can either use one-change per loop engines, such as Squeaker or Octode, or PWM like with one pulse at a time (basically the PCM playing trick, just without PCM).

One issue with developing this field is that DosBox isn't terribly accurate in regards of timings and PC Speaker emulation. Considering that Pinball Fantasy sounds reasonable while many of the games listed above is not, I think that the second approach is more accessible at the moment - unless you want to work strictly with old hardware and old tools.

368

(7 replies, posted in Other Platforms)

The only 'proper' way to make 16-bit pointer on 6502 is just LDA/STA (ZP),y. Self-modifying code is another option, but that's only for systems with enough RAM for code.

Thought it may be actually useful to sketch out a simple 6502 sound routine. This is Music Box like, two 8-bit channels, interleaving, written in the dumbest way. Tested on NES:

;all referenced vars are 8-bit, located in zero page

    lda #0
    sta <CH1_CNT
    sta <CH2_CNT
    sta <CH1_OUT
    sta <CH2_OUT
    lda #55
    sta <CH1_DIV
    lda #150
    sta <CH2_DIV
    
sound_loop:

    dec <CH1_CNT    ;5 decrement channel 1 counter
    bne no_inc_1    ;2/3 if no overflow, skip through steady timing code
    lda <CH1_DIV    ;2 load new counter value
    sta <CH1_CNT    ;2 store to the counter
    inc <CH1_OUT    ;5 invert channel output polarity
    jmp skip_1        ;3 continue
    
no_inc_1:

    nop                ;2    timing
    nop                ;2
    nop                ;2
    nop                ;2
    jmp skip_1        ;3
    
skip_1:

    lda <CH1_OUT    ;2    kind of sbc a,a on carry
    ror a            ;2
    lda <CH1_OUT    ;2
    sbc <CH1_OUT    ;2 here we get 0 or 255 depending from the original least significant bit, slow, but universal
    
    sta DMC_RAW        ;4 dump it directly to DAC, other systems may need an AND here
    
    dec <CH2_CNT    ;5 the same for second channel
    bne no_inc_2    ;2/3
    lda <CH2_DIV    ;2
    sta <CH2_CNT    ;2
    inc <CH2_OUT    ;5
    jmp skip_2        ;3
    
no_inc_2:

    nop                ;2    timing
    nop                ;2
    nop                ;2
    nop                ;2
    jmp skip_2        ;3
    
skip_2:

    lda <CH2_OUT    ;2    kind of sbc a,a on carry
    ror a            ;2
    lda <CH2_OUT    ;2
    sbc <CH2_OUT    ;2
    
    sta DMC_RAW        ;4
    
    jmp sound_loop ;3=67t

Don't forget about the nasty 6502 quirk, if any branch (except BVS) is crossing 256-byte page, it adds an extra cycle. So it is better to align starting address and keep eye on it. Not that 1 extra cycle will matter a lot, but if there is complex branch logic, it will make difference.

Good. Updated the download with halved output gain version, just in case.

I confirm the issue. Seems that the output level is just too high, so adding another one brings major clipping. Quick solution is to reduce output volume of each instance of the plugin in your DAW.

371

(7 replies, posted in Other Platforms)

Radio-86RK should be even worse. It controls the speaker with DI and EI commands, and has DMA bursts constantly running in background to refresh screen and memory (so tape routines only works while display is disabled).

I guess Apple II's inability to set speaker state directly renders Phaser-like engines undoable, but on the other hand Apple II coders often use PWM techniques to get like ~8 'volume' levels, in Fuzz Click fashion.

6502 assembly is actually super easy, the trick is to switch the thinking patterns after x86/8080/Z80, i.e. from register-oriented to memory-oriented programming.

372

(7 replies, posted in Other Platforms)

https://www.xtof.info/blog/?p=807

Also, Peter Sovietov just said that he did a similar thing in the past, that plays sound through the actual PC Speaker, using WinAPI's Beep function. Too bad that newer Windows (7 and above) does not use actual speaker for this anymore. Anyways, download here.

Yet another new VSTi in my collection - plugin that allows to use a modern DAW to create the lovely horrible oldschool single channel PC speaker music, like old DOS games had when no sound card has been installed. I mean, like Monkey Island or Lotus III had.

The best part is that the end result can be used not just in the DAW like usual, but also exported as data to be used in actual programs. A QBasic player example is included, for shit and giggles.

Here is small MP3 demo

Download the plugin


A side note, this is my first plugin with GUI, programmed all in plain WinAPI. What an unpleasant experience it was.


http://shiru.untergrund.net/temp1/pcspe_screen.png

In case anyone interested, yet another unrelated but hardcore retro addition to my VSTi's library - Flopster, sample-based plugin that plays floppy disk drive noises to make 'floppy music' without having actual hardware.