1

(3 replies, posted in Sinclair)

Hope you aren't going to hate me for saying this, but... I'm not really a fan of this one. Sounds like you wanted to make something energetic and uplifting while also introducing a bit of that classic horror vibe. That combination doesn't really work for me, it's like it's trying too many things at the same time. Sorry mate sad

2

(113 replies, posted in Sinclair)

A little reminder about the approaching deadline of the beeper compo at Multimatograf. Let's show all the lAYmers who's the boss big_smile

Does your onboard audio even have connectors for a PC Speaker? Oftentimes PC beep is just emulated in software nowadays.

Great find, as always. I recall reading about this shutdown event before, but didn't know a recording existed in the wild.

I'm afraid you can't really buy such a thing. It's really simple to make though. I'm very bad at soldering and have done it, so you can do it, too wink Check here for how to do it:

https://www.deinmeister.de/e_sbpcqlnk.htm
http://www.oldskool.org/guides/speakerrecording

If you really don't dare to do it yourself, try to find a fablab/makerspace and get help there. There are a few in your city, if I'm not mistaken.

I think the best option is to just wire the PC Speaker socket to a line out, and connect that to your hi-fi. Alternatively, most older sound cards have a socket for routing the PC Speaker through it (labelled SPKIN, usually), so you just need to connect that to the PC Speaker socket with a jumper cable.

The noise channel probably won't be useful since it starts on a low cycle.

However https://www.smspower.org/Development/SN76489 claims that

If the register value is zero or one then the output is a constant value of +1. This is often used for sample playback on the SN76489.

so we won't get any more volume range than we already have anyway. Might still be worth a try to see if 0 gives a better range than 1.

Even though I'm originally from Germany, I've never heard of that console before, let alone seen one in the wild.
Since it's supported in MAME it could, in theory, be support it in Bintracker.

upd7810 seems very funky. Not sure what they were thinking when they designed that. Could be fun to program it, though.

Do you happen to know if setting the frequency of an SN channel will reset its phase?

Ah, good. I'm really too tired to dig into this today.

I wonder what causes that high-pitched whine. This and the slow speed makes me think that the engine isn't running at the 2MHz I was assuming. Are there any interrupts still active? Are there any additional delays when writing to the SN, or is it possible that video is causing some blockage?

Optimizing the data read will only get you so far. Since the overall volume is low, row transitions will always be noticable. You might gain more by writing to all 3 tone channels instead of just one, provided you can make the inner sound loop run fast enough.

You might also consider mapping each Tritone channel to it's own SN channel. That would make things less timing critical.

Ah yes, sorry, Tritone has indeed only global tempo. Also, yes, speed value = row length, and that should be bne play_note.
I'll have to dig deeper, then. Hope I'll have some time tomorrow.

I was actually thinking you might want to bypass 1tracker and just dump directly to asm data, so you can save one conversion step and design the data format and loader however you see fit.

Spotted another one - you're missing the row length counting, ie.

    dex                         ;2  row length low byte
    beq .play_note              ;3 -- 95 ~ 21053Hz (original is 22876Hz)

    dey                         ; row length hi byte
    beq .play_note

where X should be 0 on init, and Y should be whatever Tritone spits out as row length. I don't have Tritone's data format at hand right now but iirc it should be the first byte of a pattern row.

One thing I spotted skimming through quickly is that you're loading a drum marker per tone channel, but there's only one global drum channel in Tritone.

Wow, didn't know Stephane Picq was still active yikes

My French hasn't gotten any better over the years so I'm afraid listening to that much of it in one go will make my head explode, but somebody should pester these guys to play some modern 1-bit stuff.

http://garvalf.free.fr/var/upload/musiq … ectrum.1tm

Alright, so the gist of (equal volume) Tritone is basically this:

    ldx #$0                     ;   reset row length counter lo byte

.play_note
    clc                         ;2  update osc
.ch1_div_lo
    lda #$0                     ;2
.ch1_acc_lo
    adc #$0                     ;2
    sta .ch1_acc_lo+1           ;4
.ch1_div_hi
    lda #$0                     ;2
.ch1_acc_hi
    adc #$0                     ;2
    sta .ch1_acc_hi+1           ;4
.ch1_duty
    cmp #$0                     ;2  compare against duty threshold
    sbc .ch1_acc_hi             ;4  A = 0 on low half-cycle, FF on hi half-cycle
    and #%00001111              ;2
    sta SYSVIA_ORAS             ;4

    clc                         ;2
.ch2_div_lo
    lda #$0                     ;2
.ch2_acc_lo
    adc #$0                     ;2
    sta .ch2_acc_lo+1           ;4
.ch2_div_hi
    lda #$0                     ;2
.ch2_acc_hi
    adc #$0                     ;2
    sta .ch2_acc_hi+1           ;4
.ch2_duty
    cmp #$0                     ;2
    sbc .ch2_acc_hi             ;4
    and #%00001111              ;2
    sta SYSVIA_ORAS             ;4

    clc                         ;2
.ch3_div_lo
    lda #$0                     ;2
.ch3_acc_lo
    adc #$0                     ;2
    sta .ch3_acc_lo+1           ;4
.ch3_div_hi
    lda #$0                     ;2
.ch3_acc_hi
    adc #$0                     ;2
    sta .ch3_acc_hi+1           ;4
.ch3_duty
    cmp #$0                     ;2
    sbc .ch3_acc_hi             ;4
    and #%00001111              ;2
    sta SYSVIA_ORAS             ;2

    dex                         ;2  row length low byte
    beq .play_note              ;3 -- 95 ~ 21053Hz (original is 22876Hz)

    dey                         ; row length hi byte
    beq .play_note

If you want to use unequal volumes (which could definitely come in handy), you need to shift the outputs around a bit somehow. In the original unqual volume, the outputs are distributed at a ratio of 34:49:70 cycles.

As far as data reading goes, I didn't bother since you're probably better off just design your own data scheme.

Noise mode can be tacked onto this design easily by adding

    rol
    adc #0

after adding chx_acc_hi, and using #$2174 as frequency divider value. The duty setting will act more or less as a volume control on that. Or tack on the PWM sample code from SquatM, but beware that this engine is overall much quieter, so PWM samples at full blast may be too loud. Speaking of quiet, I think this will be the main problem with this code - it'll probably be too quiet on the SN, so you might want to write to all 3 tone channels instead of just one. Or even better, output each channel on its own SN tone channel.

As to why the sound is so noisy/muffled, I don't know enough about the beeb to help you there. Are there any waitstates/badlines/whatever it's called to be aware of?

Btw, that comment on youtube suggesting to use the shift register is a good lead, I think. Not necessarily as a hardware mod like the guy is suggesting, but as a means to offload some processing.

negative charge wrote:

The BBC Micro uses an SN76489.  The Acorn Electron has no dedicated hardware for sound - it uses a ULA.  I can adapt the code for the Electron fairly easily once there's a working SN76489 version.

Ok, now I understand your plan. I was kind of betting on being able to just use SN volume to render PWM frames, but so this has to be done the proper 1-bit way.

negative charge wrote:
utz wrote:

Also, am I correct in assuming that I could just keep pumping out DATA bytes (LATCH = 0) to set the volume of a given channel?

That's correct - it's pretty much what the SquatM engine is doing:

    ora     #%10010000         ; bit-7 (latch/data), bits-6/5 (channel - 0), bit 4 (type - latch volume)
    sound_write_slow             ; output sound bit

Sorry, I meant taking this even further: only ora #%10010000 at the beginning, and then just use the active latch to set the lower 4 bits, without needing to set channel and type again. Though considering how quiet the SN is at the 50% base volume we get by setting period to 1, it might be necessary to actually set multiple channels at once.

Ah, so we're targetting SN76489. I assumed there might be some sort of native device.

Would it be acceptable to leave Port B I/O in WRITE mode and only switch to READing between pattern rows? That would speed up things quite a bit.

Also, am I correct in assuming that I could just keep pumping out DATA bytes (LATCH = 0) to set the volume of a given channel?

So, regarding optimization options, 1tracker has a row optimization thingy that you can access with Ctrl-F4. That'll only save you a couple of kb though.
Otherwise you'd need to write your own optimizer that breaks up 1tracker's long single pattern into a sequence of smaller chunks, emitting duplicates. If you can afford to unpack into a large buffer at runtime, you could also just compress the player+music data. Something like ZX0 usually does a pretty good job for that.

Btw, Empty 512 Bytes sounds surprisingly convincing, despite such crude limitations. You would probably get much further with a Tritone-like engine, though. @xxl to the rescue, perhaps you could share your GTIA port? Otherwise, it shouldn't be too difficult to port the z80 code. If you give me a summary on how things work on the BBC Micro side (ie. how to output sound, disable interrupts, available zp locations, standard compile address, etc), I could try to whip up a rough 6502 draft. Will take a few days before I get around to that, though.

Hello there bataais, welcome aboard! I'm liking a lot what I'm seeing on your blog. Our forum is mostly about music as you can see, but I'm very interested to hear more about your video projects as well.

Hi, I'm pretty pressed on time atm so will try to answer in more detail in the coming days. For now just a couple of quick replies:

negative charge wrote:

I'm wondering if there are options to optimize this file automatically, as compiled with player is over 27kb (out of 32kb available)?

No automatic options, I'm afraid. Generally it is possible to optimize the song data though.

negative charge wrote:

I'm also interested in whether any of the other engines have been ported to the 6502 (or variants) with source code available?  My Z80 knowledge to do this myself isn't up to the task.

Ports exist, but none with source available.

negative charge wrote:

Finally, a long shot but does anyone have ideas on how to convert SN76489 LFSR noise to SquatM noise/percussion? (fixed rather than tuned).

Eh, finally some good news. Yes, this can be done. If you can generate the bitstream from the LFSR, you can convert it to SquatM's PWM sample format, which is basically just a bitstream with run length encoding. So eg. %1111000000011000000111000011 becomes 2,4,3,6,2,7,4,0 - the final 0 is the end marker.

22

(2 replies, posted in Sinclair)

Pah, kids and their hipster gadgets nowadays big_smile

There are plenty of z80 instructions which are neither 4 cycles nor a multiple thereof, so that statement is kind of bollocks. Sampling every 4 cycles should still be good enough though, since most beeper engines align output to 8 cycles. To do things properly however one should sample at every clock cylce, and then apply a low-pass at half the sample rate of the emulated output.

23

(5 replies, posted in Sinclair)

I could also pre-generate the tables, if that helps.

24

(6 replies, posted in Other Platforms)

Shiru wrote:

Another weird method of controlling a speaker is found in the 8080-based Soviet DIY computer RK86. It lacks any interrupts whatsoever, so EI/DI control the speaker.

The PTC Sol-20 Music System is another (very early) example of this. Coincidentally it's also an 8080-based machine, though the Music System itself is an S100 card.

bushy555 wrote:

I have since experimented with 1k2b but unfortunately didn't get very far

On ZX81 it's actually a little more complicated since you write to port #ff, but read from port #fe. So if you comment out lines 64-66 and 85-87, and change line 206 to 'ld bc,#01fe', you should be nearly there, save for the drums. Really, don't torture yourself with 1k2b though. that's a horrible piece of code. Funnily enough, these new engines I made (ulasyn and PhaserF) should be fairly straightforward to port.

25

(6 replies, posted in Other Platforms)

Ah, that's similar to how it works on ZX81, which isn't surprising considering the machine's history. A rather inconvenient setup for 1-bit music, but not impossible. You'll probably want to write your own engine for this though, rather than porting an existing one.

Just how many different machines do you have in that barn of yours, though? yikes