Haha, achievement unlocked I'd say wink

For PCSPE, I'd be interested in porting it to LV2 some day. Not happening anytime soon though, I guess.

Oh, didn't know littlescale made a 1-bit thingy. Nifty!


(0 replies, posted in General Discussion)

I guess this isn't very interesting for most people, but since I'm currently putting a lot of time into the MDAL project, I thought  I'd post some updates about that here once in a while.


Last year saw the specification of the MDAL standard (standards, actually) and the development of libmdal, which eventually became the back end for bintracker. While the concept itself was reasonably successful, the actual implementation - surprise surprise - turned out to be too limited to support pretty much anything other than the engines that are currently available in bintracker. In fact, the current MDAL can't even support a simple engine like Huby. So, a redesign is needed.

New Standards

In the past months, I've been drafting new standards for MDAL configurations (MDCONF) and the actual MDAL module language (MDMOD). These drafts have now progressed to a state where I can share some details. First up, here are some links:

MDMOD v2 Specification Draft
MDCONF v2 Specification Draft

Obviously nothing is set in stone yet. However, I believe that the MDMOD specification is already quite mature. On the surface it still looks pretty similar to MDMOD v0, but there are a few major breaking changes. These were necessary to facilitate some of the more complex features provided by MDCONF v2. MDMOD v2 does add some boilerplate, but it also adds some syntactic sugar. Overall, it should still be quite human readable/editable even though the focus in v2 will be on machine processing.

The most notable change is that typing and scoping are no longer implicit. In MDMOD v0 you could write something like

  NOTE=a4, FX=fxtable1

and MDAL would automatically infer that "pattern1" is a block of type pattern and fxtable is a block of type "fx". In MDMOD v2, you will need to write this as

:PATTERNS(1)[pattern1] {
  NOTE=a4, FX=1
:FX(1)[fxtable1] {

The stuff in angular brackets is just a name and can be omitted. The good news is that, assuming the block type PATTERNS only provides NOTE and FX fields, you would also be able to write pattern1 like this:

  a4, 1

meaning the field names can be omitted. You still need to specify the field name if you only update some of the fields on the given step, though. Also, there's a new short hand for empty steps. This


becomes this:


Another big news is that sequences (now called ORDER) are now matrix sequences like for example in Famitracker. Garvalf really wanted this I think... and he was absolutely right that this is a good idea. Sequences are now entirely virtual, so in bintracker you will still be able to use the classic "glob" style (and in addition, the new matrix style or automatic sequences like in 1tracker). Also, syntax for sequences and blocks will be exactly the same in MDMOD v2. So, assuming we have a config that specifies something with 3 channels, you can write the sequence as

:ORDER {    // no need to specify the instance if there is only one
  $00, $01, $02
  $00, $01, $02
  $00, $03, $04

or you could write

  $00, $01, $02
  CH2 = $03, CH3 = $04

MDCONF v2, on the other hand, is very much a departure from v1. There is a much higher level of abstraction, with the aim to seperate the input from the output configuration as much as possible. I'm still very much in the process of working out the details, but it's starting to take shape, at least.

One of the most exiting news is that with MDCONF v2, you can define a recursive data structure. This will make it possible to support things like SID subtunes, or the SEQUENCE-CHAIN-PATTERN approach used by LSDJ and Slocum's Music Kit for the Atari 2600. Generally, the approach for v2 is to define input and output Groups (which are an entirely abstract construct), which contain any number of Fields (still derived from Commands like in v1), Blocks (patterns, tables, etc), and, most importantly, other Groups. Anyway, don't want to go too much into detail, as this is of course all super dry and theoretical. If you are really interested, read the specifiaction draft.

Where to go from here

I'm now a couple of months into designing a new libmdal to work with the v2 standards. The new lib is meant to be a fully-fledged tracker backend, so in theory it could be used to build trackers other than bintracker (though I doubt anyone will do it). I'm afraid there's still a few more months worth of work ahead of me, so don't expect to see the results any time soon. Once it's in a working state, I'm intending to write a dedicated GUI library to work with libmdal. Together with a few salvaged bits from the current bintracker, these will eventually become the new, all-powerful bintracker. Yay!

In any case, as mentioned earlier, nothing is set in stone yet. If you have any ideas, suggestions, questions, I'm more than happy to hear them.


(1 replies, posted in Sinclair)

DiHalt 2018 takes place 7-8 July, and as usual they'll have a dedicated beeper compo.


(5 replies, posted in Sinclair)

Ah, bummer. Well, y'always learn something new.
A google search for "spectrum +3 audio fix" turns up quite a few results though, so if you're handy with soldering you might be able to improve things.

Wow, excellent song! Not much of a Musical guy myself, but that's certainly some very solid work.

Very curious about that demo. Let us know if you need help with anything.


(5 replies, posted in Sinclair)

If I'm not mistaken the tape out is indeed not affected.

DivIDE is definately a blessing for live shows. Loading through MIC can be very unreliable in noisy environments, especially when there is vibration from bass. Before I had one I used to bring a CD player to my gigs for loading. One of those bulky hifi ones, not a walkman, oh no, those won't cut it! big_smile Nowadays there's divMMC which is a fraction of the size of a divIDE and uses SD instead of CF. Haven't had a real reason to buy one but I am considering it as a backup in case my divIDE dies, which wouldn't be surprising after ~6 years of rather heavy use.


(5 replies, posted in Sinclair)

As far as beeper/tape-out is concerned, I've heard a lot of good things about the +3, though I don't own one so I have to take other people's words for it. Only ever used the rubber 48K myself, works just fine wink Wouldn't go for a 128K unless I wanted to use AY. 128K has different contention timings which may have some newer beeper engines end up sounding less clean than they should. +3 doesn't have this problem because there's no I/O contention on that machine.

Hi uglifruit, welcome aboard.

1-bit music in a musical, now that's something I haven't heard of before! Do you happen to have a recording of that performance by any chance?

Yes, definately need some better live tools for the Spectrum. Got some rough ideas floating around, but no time to work on it.
As for hacking advanced keyboard control into existing 1bit engines, it's definately doable for most of them. Generally I think the best approach would be to jump from the engine's basic keyhandler into your own and then poll the keyboard again, to avoid introducing extra noise.

Also, since you seem to enjoy tinkering with asm, maybe the BeepModular engine is something for you:
https://github.com/utz82/ZX-Spectrum-1- … aster/bm-1


Plogue has support for P824x sound, but it only supports the default stuff. And of course Plogue is closed source so it's not that useful. David was kind enough to publish some info, though: https://ploguechipsounds.blogspot.nl/20 … p824x.html
Think I have to pass on this one for the time being, even though I'd be very interested to code on the 8048. But I've got too many hobbies already at the moment yikes


(4 replies, posted in Other Platforms)

Yes, there was no sound, because as you know, GME doesn't support Apple II. Hence my proposal about "generic" emulation/simulation by recreating engine algorithms in C/C++. I think even AngelscriptJIT would be fast enough.

krüe's plugin does export stand-alone executables (wrapped to a disk format), at least the later versions do. However, in case of Apple II, it's a matter of discussion what even constitutes a "playable" format. There's neither any standardized snapshot format, nor do most emulators support loading binary to mem. Instead you get a colourful variety of "disk" formats, usually with hardly any proper documentation and usually containing proprietary DOS blobs. There's a public domain alternative called NakedOS, but it's documentation isn't exactly great either.


(4 replies, posted in Other Platforms)

Well, we did have ED in 1tracker at some point, made by krüe: http://krue.net/1tracker/
However he said the plugin doesn't work in recent 1tracker versions anymore.

Regarding sound emulation, one thing I've been considering is generic emulation by recreating the engine algorithms in C/C++. Abandoned the idea because it obviously inefficient and involves copious amounts of work, but taking into account also the recent discussion about handhelds/watches etc, it might actually be the most sensible route.

Regarding the "missing roots", there may or may not be a direct link. Only Mark Alexander would know, obviously. The history of 1-bit music as we know it now is full of interesting links (for example I'm pretty sure there's some continuity from Whirlwind I -> IBM AN/FSQ-7 -> TX-0), however there has been an equal amount of "re-inventing the wheel".

So if you've ever looked into Apple II matters, you've probably heard of Electric Duet. If not, check this vid for a little introduction. As you can see, just two tone channels with variable duty. Nothing special at all. Except that the program is from 1981, predating multichannel Spectrum beeper music by several years. It might actually be the first use of the "pulse interleaving" technique.

As I recently did a track using Electric Duet, I got curious and wanted to learn more. A friendly soul then pointed me to this place:
which contains a great write-up by the program's author, Paul Lutus, as well as the engine source code. A read I can certainly recommend!

On a side note, Electric Duet's GUI is surprisingly tracker-like. Especially so considering the "sheet music" type editors where all the hype back then, and real trackers didn't appear until many years later. Very fascinating.

Regarding low clock speed, I think part of the secret may be overtones. A piezo will cut the low range anyway, so you can generate tones at the very low end of the audible spectrum, and the piezo will "magically" transpose up. Afaik some of the LCD games also had hardware PWM to handle sound.

In any case, I agree, it's a very interesting field.


(2 replies, posted in Sinclair)

That's a neat idea, and very well executed.
I assume W setting has no effect for the ES engine, right? I'm wondering if it would be possible to use the value for something.
Generally speaking, I think such meta-engines are a very interesting concept. One question that comes to mind though is how to handle a variable number of parameters in a tracker. For example beepertoy can take on 2-8 channels depending on which engine is used. As far as I can tell that doesn't translate well to either 1te or mdalconf.

Uh wrong thread I guess but yeah, consider me interested. Got any links?
Btw if you wanted to post your stuff on here I could make a sub-board for it. As you can tell this place isn't all that active but maybe that'd attract some others as well...

Ah ok. Yeah in that case you'd have to deal with HTML5 Audio API which might be slightly, err, unnerving yikes

Just fyi, Beepola is by Chris Cowley, but yeah, it's great smile Good luck and please post the game here when it's finished!

Don't know of anything ready-made as such, but a Squeeker type generator would be trivial to implement. What language is your game written in? Simple (if slightly unsafe) C++ example:

uint16_t suma = 0;
uint16_t fdiva = 0;
uint16_t sumb = 0;
uint16_t fdivb = 0;

int16_t generate_pcm_sample() {
    suma += fdiva;
    sumb += fdivb;
    return ((suma | sumb) < 0x2000) ? 0x7000 : 0;

You'd just call this repeatedly to fill your sound buffer.

On the other hand, why not simply use some ZX Spectrum music? With an engine like Huby, you'd get some pretty authentic sound.
Example: https://irrlichtproject.bandcamp.com/tr … ny-fingers
I'd even make a track for you, though we'd need to talk about the budget in case you're planning for a commercial or ad-supported release.

Or you could use Shiru's PCSPE VSTi and whip up something in FL or Ableton.

Ah, I remember drooling over this a while back. I agree, the simplicity of this makes it all the more interesting. On the other hand, having worked with piezo sound a while back I can assure you that it's even more awful than one would imagine. Then again I suppose it wouldn't be a problem to connect something more useful.

Hi there!

Well, in order to be totally authentic, you'd need to implement an SM-510 emulator, and write your own player. In that case you're looking at quite a bit of work, obviously. It's not impossible, though wink MAME has some SM-510 emulation code, and it's even BSD licensed, yay!
https://github.com/mamedev/mame/blob/ma … 10/sm510.h
And there is an SM-5 series assembler, written in Java:
https://web.archive.org/web/20160112051 … arpasm.zip
as well as an emulator, from the same guy, though I'm not sure how useful it is or if it even does sound:
https://web.archive.org/web/20160112051 … tchman.zip

The problem is that the SM-510 is slow af, so you're not going to get really advanced stuff out of it. However if I understand correctly it actually has 4 bit output so maybe that's enough to mix two voices.

I have yet to find a full instruction set of that thing, though. However, appearantly it's similar to the TMS-1100... hmmm... also no idea what this "melody module" thing is all about.

The other, slightly less authentic route would be to implement a generic piezo emulator, and write a player for that. As neither PFM nor pulse interleaving will work on an actual piezo, I'd go for a Squeeker-type player. See here  for a technical discussion. Basically you generate pulse waves with reasonably low duties (say, 10-25 %) and OR them together for the final output.

In any case, please keep me up to date about this project, and let me know if I can help in any way.


(23 replies, posted in Other Platforms)

Ah yes, I was almost going to make a comment about the thing being GPL. However, the Borik brothers seem to be nice folks from what little contact I had with them some years ago. So they might be possible to talk to them about relicensing the relevant portion to MIT/BSD or something. Let me know if you want their contacts.


(23 replies, posted in Other Platforms)

Maybe 8253 emulation code from GPMD85 emulator could be of help?


(23 replies, posted in Other Platforms)

Most fascinating, and happy to see the progress.
At the end of the video from the unit test, what's the meaning of the "40468 7"?


(82 replies, posted in Sinclair)

Awesome, thanks Shiru!

Forgot to mention, I did apply a few changes to the source last  time. All of them cosmetic, but Clang will have a fit about these.

int put_str(int x,int y,char* str,unsigned char col) =>
int put_str(int x,int y,const char* str,unsigned char col)

void put_str_file(int x,int y,char* str,unsigned char col) =>
void put_str_file(int x,int y,const char* str,unsigned char col)

int put_str(int x,int y,char* str,unsigned char col); =>
int put_str(int x,int y,const char* str,unsigned char col);

select_engine.h:34, 104
if (dp = opendir(engineDirectory)) =>
if ((dp = opendir(engineDirectory)))

Also added -fPIC flag in makefile. Position-independant executables are now the default on most Linux distros, but the Angelscript JIT compiler doesn't like that idea, it seems.

More critically, since a few versions there is still a bug that will cause random "engine provided no data" errors. I cannot get a reliable way of reproducing it though. It mostly happens after applying a marker and then entering something on the first row of the new block. Though sometimes it will happen in the middle of a block as well. Usually the problem starts occuring only after editing for a while (though it will then persist through restarts), but I've occasionally had it happen on an almost blank tune as well.

Mwahaha. The BEEP command can be used to escalate privileges in Debian big_smile https://www.debian.org/security/2018/dsa-4163
The way for 1-bit world domination is clear!