Electronics, coding and hacking. And ADD.

« GERP 2016 Solskogen 2016 - Kaimana! »

A 5th audio channel on the Amiga


The Amiga is one of my favorite machines, especially when it comes to the audio. Most of you who had an Amiga back in the day (and maybe still do) remember that it had four eight-bit, stereo-separated sample based audio channels. But what if I told you there's a way to get a fifth audio channel?

Ok, so it's not a real, real audio channel, but I'm talking about something capable of outputting audio: the Amiga composite video port. It's the same socket as the other two audio ports, it outputs terrible video quality and is not in use on most Amigas. So why not put it to work?

The concept is simple: a bright color outputs a high voltage, while a dark color outputs a low. By changing the screen colors at just the right speed, I'm able to generate audio frequencies and use them to play music.

Let's look at it in detail by examining the video signals for a perfectly black screen:

Now, compare this to a white screen:

The first obvious thing you'll notice are the "dips" in the curve every 64µS. These are the horizontal sync signals, one "dip" per line, and they cannot be disabled. Consequentally, they will also produce an audible humming sound, which you will hear in the video further down.

It is clear that we can easily manipulate the video signals by changing the screen graphics, and by carefully changing the graphics at just the right time, we should be able to make video that's.. well, audible.

I wrote a simple assembly program that fills the screen with 285 raster lines from top to bottom. This means that one line represents the voltage level between two horizontal syncs (or "dips" if you like) as seen in the pictures above. All lines are updated 50 frames per second with the next values from the audio sample.

The code automatically adds a DC offset to the AC audio waveform so the sample data varies from 0..255 instead of -127..127. And since the Amiga only has 16 gradients from black to white, we only use the upper 4 bits of the sample. (Using gradients of various colors will not increase the sound quality, look up how colors are encoded in composite video.)

Now, what I needed next was some way of composing music with this fifth audio track. There are existing programs that emulate multiple tracks through software mixing, but I decided to take the short route and use spare 800 commands in Protracker for playing the last track. To keep things simple, I'm dedicating the 5th track just to the drums, so I don't have to worry about adding support for various notes. The command 8xx simply plays the instrument xx at a preset pitch. As you can see above, instrument 1 (801) is the bassdrum, 2 (802) is the snare, and 6 (806) is the hi-hat. The Protracker replay routine was modified to support these "video samples."

Just like the other audio ports, this one needs to be amplified to be heard. I connected a set of active PC speakers via this adapter cable. Although I built this one myself, similar cables are dirt cheap on eBay, if you want to try this out for yourself.

Take a chill pill, Picard, and listen.

Here's the proof-of-concept demo. The audio is a bit low, but if you listen closely, you can hear that I'm gradually spending all 4 audio channels before introducing the drums.


to A 5th audio channel on the Amiga

Feed for this Entry


  • That's pretty awesome, considering how bare-bones it is. I bet with a bit of "sync recovery" circuitry, you can fill in the holes created by the horizontal and vertical sync pulses with a sample-and-hold circuit.

    Speaking of which, with a sample and hold circuit and a PLL set up, you can probably arrange four samples per scanline, and play them back at 63kHz sample rate.

    Nifty work though! That's pretty awesome!

  • Samuel: Thanks! And you are absolutely right, the SYNC signals can be filtered out. But I left them there for a reason: the simplicity of it. As it is right now, anyone can do it.

    But, I see your point and it's definitely valid. Maybe I'll do a v2.0 one day.

    Another idea is to push the I/O's from the parallel port through a DAC, that should give a pretty good quality sound... hm...

    #993 | Comment by admin on Aug 5, 2016 06:06am
  • Ports of Call came with a DAC for the parallel port. Called the "Life-Size Sound Enhancer". It was for the PC, but it could be used to play music on the Amiga as well.

    #997 | Comment by swede on Aug 12, 2016 10:49am
  • So if you did this with an AGA copper list you could get full 8-bit resolution as there is 256 positions?

    #998 | Comment by h0ffman on Aug 12, 2016 12:07pm
  • You magnificent bastard. Have my children!

    #999 | Comment by Randy on Aug 12, 2016 12:12pm
  • h0ffman: The sound quality would be a better on AGA, yes. If I go the parallel port route, as I pondered about in a comment further up, I would get full quality (8-bit resolution and no SYNCs disturbing the waveforms). Which I might do.

  • Hehe. You can really hear the VBlank period, especially during the kick since it has lower frequency content than the refresh rate. But nice!

  • Cool proof of concept, but uselss with all the hum and the occupation of the video...
    The parallel port + DAC trick would be much better indeed.

  • There's also the well known Covox "sound thing" which you could buy (or make yourself from schematics!) to do the same thing for IBM PCs, and served its purpose fairly well from sometime in the 80s through to the early 90s, when plug in sound cards finally started to make monophonic 8-bit sample quality with maximum frequencies in the teens start to look a bit old hat...

    Now, the question is, how fast the Amiga can run that port, and how many other pins you can manually toggle on it besides the simple 8 data lines? Although the cycle time is about the same for both, we do have a 16-bit bus to play with vs the 8-bit that early PCs struggled with, after all. It might be useful to pull even more channels out of it (at probably lower bit depths and with fixed volume, but that's a call that would have to be made), or to provide better sampling precision or at least some control signals for an additional volume control unit to parallel the one inside Paula herself (which, after all, allows adjustment of the relative levels of each sample being output without compromising their resolution in the process, and so can be used to create a pair of ~14-bit virtual channels in place of four 8-bit ones)...

    And then combining it with your visual output idea, and the regular internal channels, maybe through a minimixer to allow panning (manual or under Amiga control) of the new channels with better finesse than just "left" or "right" (including the all-new, amazing, "centre" ... or, it could be a fixed-pan one where we now have six channels... two left, two right, two centre (at lower overall amplitude to avoid drowning out the originals). Might start challenging how much data the memory can shunt out, at this rate...

    But wait, there's more.. (this will likely need a second post to maintain clarity ... one sec)

    #1003 | Comment by MarkP on Aug 12, 2016 06:53pm
  • OK, so I just had another brainfart and ended up thought-experimenting my way through it, hence the delay...

    Anyway there's various points I want to try and throw out here as short as I'm able to condense them. All of which would still be pretty simplistic - not quite "plug an RCA from the composite port to a stereo", but, still... perfboard and discrete components, or simple standard ICs that do the job of well-worn classic arrangements of such, plus a bunch of coding, would cover it all.

    1. I'm not convinced that changing colour wouldn't have an effect. Even if that port only outputs monochrome, it still has to generate the monochrome signal from what's coming out of the rest of the chipset... which is RGB. Unless literally all it does is connect, say, the Green line to the Luma of a standard encoder jumpered for B/W mode, there will be some kind of colour conversion going on, probably using an absolutely bog standard converter chip...

    If it cheaps out and merely bridges all three channels to Luma as equal partners, that still increases the precision of your signal threefold, and would allow very easy exploitation of such by separating the signal range in three; at the lowest end, you have (say) R=0, G=0, B= variable. In the middle you hold red at zero, blue at max, and vary green. And at the top, red varies whilst green and blue are maxed. Just need to pre-scale the sample value and you're golden. And, heck, if you're going to use a dedicated set of percussion data with the hack, you could do that "offline" too.

    (BTW, you said you had 32 levels, using 5 bits of the sample? How are you managing that on a machine with only 16 levels for each channel (4 bits), meaning only 16 greyscales? If it's halfbrite mode (...which I thought still used the same palette and DAC and was just a way to save on index registers?), all that sixth bitplane does is divide the palette index corresponding to plane 6 = 0 in half to obtain the one virtually corresponding to p6 = 1. Either it doesn't do anything useful, or it gives you improved resolution on only one side of the wave... adding an extra 7 positions from 0.5 to 7.5... Which is still an improvement, aye, but it's 23 levels, not 32, and bloody weird to have to try and work out unless ONLY using pre-calculated samples that would sound like whitenoise under any other system :D )

    More likely, though, is that it multiplies the three channels by different individual scalefactors which should make 100% blue fairly dark, 100% red moderately dark, and 100% green medium grey on a B/W screen, all of them adding up to bright white when put together. Not *entirely* 16.7%, 33.3%, and 50%, but fairly close to it, and it's a formula I've seen in many different places so it's not hard to track down. The 4096 different results for the luminosity figure would be best worked out in a spreadsheet, arranged by output intensity normalised to 0-255, and the most useful bunch of them highlighted and picked out to be used as the output values for a converter program. There may be a few duplicates, and some holes in the list, but it should provide a reasonably good selection. More than just 32 or even 64, certainly. Even if it really IS 1/6th, 1/3rd, 1/2, then the smallest step there is 1/96th of full range, and you can engineer 96 unique levels quite trivially... and 6.5 bits will sound a lot better than what is probably 4, or maybe 4.5 right now.

    (I think the actual Blue is more like 18%, but the non-uniformity of the whole thing means that the only two places where that might cause some unnevenness instead of actually increasing the resolution quite a bit are the two where it matters least anyway - at the very max and very min deflections. And even there the step size is equivalent to having about 90 in total...)

    ((...crap, I also just thought about gamma levels and whether the main audio output is linear or logarithmic thanks to that. This whole thing is a minefield of potential pitfalls and basically a survey of the various output levels produced by both the normal soundchip and the composite port when each possible digital value is applied to them is probably needed. This started out feeling simple. Now I'm not so sure. Still, it's all stuff that would have been doable in 1985, including the analysis, just using an analogue scope instead of, say, recording it into a PC at 16-bit sample depth or better and using it to analyse the amplitude for you ;) ))

    By the way, this relationship between internal RGB and output Luma should remain regardless of whether the composite video signal is mono or colour. You should be able to see this for yourself by just pulling up DPaint or something and looking at the full-palette colour picker screen, with both an RGB and a composite screen plugged in. With colour output on composite, they should both at least superficially resemble each other.

    If you now use the picture controls to reduce the saturation to zero (IE forcing it to B/W), you should see that the purer blue colours are fairly murky, the purer reds are kinda dim, and the purer greens around the midrange; secondaries and pastels are lighter, and you still get pure white, pure black, and the greys where you would expect.

    Ideally, if it's only a mono encoder, this should be the case regardless of where the saturation slider sits (if there's no colour component to the signal, the decoder should kill that part of the circuit and just use luma direct), and it should still look exactly the same as described.

    However, if Commodore cheaped out, it could be that the pure colours all look about the same medium-dark shade, and all the secondaries the same medium-bright one... (with the mono converter only; if this was the case with colour the overall result would look terrible).

    And if they went even further and just picked one of the colour lines to convert directly ("doing an Amstrad", I think that is), you'll see an odd pattern where it, the two secondaries that include it, and white are all at maximum brightness, the opposite two primaries and one secondary are the same as black, and there's a weird pattern of variation between those maxima and minima.

    But I strongly suspect the first option out of those three.

    Also, don't worry if it does produce a colour signal; the way the encoding works *should* (and I say that "should" in strong italics, 50ft all and flashing red and white) mean that on a sufficiently fuzzy B/W TV, and to the ear, the colour components are completely transparent. They're present as lower resolution baseband signals encoded (even when not on the RF line) as lower amplitude sinusoids imposed onto the luma signal proper, each at a characteristic frequency and phase offset. The frequencies are up into the hundreds of khz or low mhz, well above what any speaker can reproduce or ear detect, and the phases chosen to cancel out as much as possible. And, as they're sines, at a much higher carrier frequency than the actual data, their net contribution to the baseband DC of the Luma signal is nil. A sharply focussed set will show them up as the dithered "crawling ants" that are familiar from poor quality colour composite decoding (which doesn't include any cancellation of the recovered colour signal from the luma, or smooth out the extracted colour components properly), but running them into a speaker will have the same effect as a fairly powerful horizontal motion blur and they'll simply vanish.

    But, getting back to my original point, this doesn't mean that there won't be *any* benefit to the finesse of the black and white part by changing the colour tones. I think it would still be worthwhile.

    And, bugger it, I've run on massively anyway. I'll see if I can express the other thoughts asap in a third post. They're not as complicated, at least.

    #1004 | Comment by MarkP on Aug 12, 2016 08:35pm
  • OK...

    2. The sync problem may be fixable just with notch filters at 50hz and 15625hz, but I don't think that'll fix it as much as anticipated, because there's still that big ugly hole in each line and each frame, taking up about 10% of each, and it's not a clean sine or even a squarewave - it's a narrow pulse, which is a pain in the arse to passively filter out.

    However the main problem is primary overtones from the frequency of the pulse shape itself, ie in this case roughly 10x how often it appears; for horizontal this can be ignored as it's up into the ultrasonic (15.6khz is piercing and annoying, 156khz is inaudible), but the vertical implies a secondary spiky, buzzy tone around 500hz (I'm guesstimating from how you've been able to get 285 active lines and the whole frame is likely either 312 or 313...). Possibly another narrow notch around there will help? There's still the missing data and the regular flip between "silence" and actual sound every 1/50th sec, but that might not be as annoying or obvious.

    (Still, I dunno what it was like for the Amiga crowd, but growing up with an ST meant we just accepted 50hz buzz on the monitor speaker or indeed it's headphone output as a fact of life, as both of those things were right next to the CRT anyway, and it induced one hell of a buzz into everything around it ... in fact, you could probably have made this trick work just by running the program and not changing any wires ... so it might be acceptable as just One Of Those Retro Things. Alternatively, if you turn up the monitor sound and mess around with speaker wiring polarity and such, you might find a relative position between speaker and screen where the two things suddenly cancel out...)

    I have another idea for this which involves a 32-byte FIFO, a connection to the input side of the composite encoder between the RGB-to-luma part and the DAC, and the input side clocked at system video speed but the output at that much minus (number of skipped lines X 50), with some additional bits and bobs to make sure it starts and stays in sync... which basically gets rid of both sets of holes without any filtering by (a) saving the digital luma signal into a buffer slot partway along the line (goodbye Hsync) and (b) playing the generated sample data about 10% slower than before (so ~14000hz - which sounds kinda suspicious, doesn't it! I wonder whether Paula knows a similar trick...) even though the Amiga is reading it from memory and sending it to the video output at the same speed (goodbye Vsync), seamlessly looping back as the input side starts taking in the new frame data just as it's finally finished outputting the old data.

    Your routine also then doesn't need to (if it even does anyway) skip forwards through the sample without actually replaying any data during the Vsync, it can just pause and pick up where it left off instead.

    3. I wonder if it can be obviated anyway? If the composite isn't going to do any useful job of displaying things during output, can things be fiddled so that it never actually produces either sync, and - even if the RGB quits showing anything during the flyback periods - the copper/agnus convinced to keep spewing colour data out to it, so you get neither the whistle nor the buzz, nor any missing parts?

    4. On that front... The RGB itself. Mate, look... you've got three 4-bit channels there ripe for the taking. If you can get 9 bits (8 data + 1 manually fungible clock/status pin) out of the parallel in reasonable sync with them, and wire that up as 3 sets of 3 with suitable attenuation, you can effectively make three 7-bit channels, using the same process.

    The RGB will suffer the same problem of not being able to produce any useful image during the syncs, but it also doesn't force you to deal with the pulses themselves, and you could, for example, have the parallel providing the 3 most significant bits of each channel, and the RGB the 4 least significant. Then all you have to suffer is the samples essentially being only 3-bit for 1/500th of a second every 1/50th of a second, and 7-bit the rest of the time. When you've got a mix of 7 channels going on, possibly with these additional ones being centre-mixed (and thus, if hooked up right, providing 50% of what would otherwise be their maximum level to each side) and, of course, not as full time as the internal ones unless you're making a VERY full-on module, it shouldn't even be noticeable.

    (Hopefully I don't have to say anything about using the copper to change the palette on the fly to get more than 32 colours in each frame so that you can have an entirely free combination of levels on each channel, right?)

    5. There's another way, besides that, which is both better quality and more realistic, and lets you use the screen in some way too, but it does "only" give two extra channels instead of three. You do score a total of six 8-bit hardware channels all the same.

    Red and Blue in the RGB port provide the 4 LSBs of each new channel (you could just bridge them together with a resistor on one, but you'd still have the deadzone issue). The parallel port provides the MSBs using just its normal data pins. Thus far, so simple; you have nominally 8-bit channels that lose a tiny bit of quality by actually only being 4-bit for a fraction of their active time.

    Green (plus sync lines) gives you a monochrome display, with your choice of between 2 and 16 freely definable intensities, and controlled using between 1 and 4 bitplanes.

    Audio output is still controlled by redefining the palette once per line, though it's between slightly and much more intense depending on how many levels you want on the display because you have to re-write the whole lot every time one, other, or both of the sample levels is updated. The green level data stays the same each time, after being initially set up, and the same red and blue is used for each of the entries during each update spool.

    (for usefulness crossed with economy i'd suggest 2bpp, so only 4 entries; on a mono screen, being used for interface control rather than showing photos, it's about as useful as any higher amount, and very efficient too. Nintendo knew this...)

    For maximum funzies you can also connect either the full RGB complement to a monitor (I suggest a CM8833 with the "green" switch on the front, for obvious reasons), or indeed the composite if it's got colour output, and get some pretty sweet graphical effects on the go, either overlaying the UI, or with deliberately programmed FX running behind the audio parts.

    6. An alternative tack is PWM... there's a whole pile of pixels that can be individually addressed across the screen, meaning there's a MUCH higher frequency signal waiting to be produced, and one that you can manipulate using a single additional bitplane per channel and a bunch of pre-defined patterns (one per line, unless you want to increase the sample rate and do 2 per line - 31.5khz - or 3 per line - 47khz...). And also the amplitude gap between the two of them can be manipulated using the palette entries...

    The parallel can still produce 2x4 or 3x3 sets of MSBs, and you can still use just 2 or all 3 RGB lines, but the bit depth during the active parts of the screen will be greatly improved. Even if all you do is have a static colour, or a 50% dither, that's more or less an extra bit for free - so seven entirely hardware generated (IE no CPU calculation and shit-ton of memory reading and writing, no slowdown, no loss of replay frequency or special effects) 8-bit-or-better (most of the time!) channels could be yours for the taking, including some simulation of post-DAC volume control to bring the result more in line with what Paula produces.

    And it might even work to have the LPT output at a higher speed with a bit of dithering on its own LSBs during the deadzone in order to hide the gap a bit better...

    Also the effects obtainable if you keep the display on (with or without a usable interface) will be even cooler, including through composite, as a purely mono one might end up creating hard-to-predict artefact colours on a connected TV, and an already colour one will do that as well but in an even wilder way.

    I mean, the actual result will probably be terrible mess given that you're using the LSBs of an audio signal (which is essentially noise, much of the time...), unless you try to use the R+B as direct 4-bit outputs improved by PWM that still have the dropout issue...

    7. Side idea: mixer board for the additional outputs that provides some basic modicum of Paula-like control over volume ∋ if we expand that to 256 volume levels, 64 panning levels (or, just 128 volume levels for each of L and R), plus 2 bits to pick which channel it applies to, it's only 60 bits. One bit per line (15625 baud... half of MIDI, even) still allows about 4 and a half updates per frame, or enough to update all three tracks three times every 25th of a second. Given that this would by itself be sufficient for an extra deep-bass channel if abused in the right way, I think it's probably sufficent.

    (Heck, the serial port, with a shift register attached, doing MIDI rate, could be a low-frequency channel with 8 bits of resolution at upto 3125hz... so essentially you've got yourself a 7.1 Amiga. If the mixerbox was still a useful thing, it'd have to be controlled some other way, but figuring it out would be definitely worthwhile)

    8. And after that... go on to do the same for a load of other machines. Particularly, this would be interesting for adding two or three hardware PCM channels to a stock Atari ST (or 2-3 more to an STe) without having to do anything extra with the PSG, although it should be noted that it is also the chip which controls the parallel port in the first place...

    It would be short a bit for each of the RGBs, and without the copper (or blitter, in the plain ST) the palette updating and any attempts at PWM would be trickier and more CPU intense, but otherwise the same tricks could be achieved (and if it were relevant, any model that has an RF modulator built in also has composite video - just rather inconveniently coming out of the same port as all the other video data)... on top of which there's all the existing fun to be had with the YM2149 and, in the STe, the 2-channel DMA.

    And although the active screen area is otherwise very limited, tricks are available to open up the overscan areas to essentially the same size as the Amiga, and the code doesn't slow things down ever so much; the faster CPU and bus should help a little with that.

    Meaning with the later machine you could have a pair of 7-bit or three 6-bit PCMs (which, just like the Amiga, drop to 4 or 3-bit for a portion of the frame time, and could be PWM'd to improve both the maximum and minimum quality), another pair of 8-bit PCMs with their own volume control and EQ/panning, possibly a retained mono video display with trippy overlay, and a low-system-load soundchip that can produce 3 squarewaves, whitenoise, and by use of additional cleverness, a low frequency triangle or sawtooth wave on top of them and extra low frequency buzzer effects... I make that 11 different channels with various characteristics.

    Or of course you could just abuse the PSG channels for 3x 5-bit logarithmically scaled PCMs, or a single sort-of-8-bit that uses the various levels available by combining those unevenly scaled channels together. In practice, the machine was more than capable of producing acceptable (not good, but acceptable) quality replay of 4-channel modules using that technique - rather like getting 7 channels using software in Oktalyser - so there could be upto 9 PCMs of different grades available for use. And when you're combining that many together, telling which are the low quality and which the high gets a bit tricky, especially if you prioritise use of the high quality ones and reserve the low quality ones for when they're actually needed (preferably attenuated to hide their roughness).

    But besides the ST, I figure your base technique plus the other tweaks could be used by, well, pretty much any retro machine with a video or monitor output (IE everything), even down to the VCS and VIC-20, MDA and CGA cards on the IBM PC, MSX, CPC, ZX81, Spectrum (regular and 128k), C64 (oh man, why didn't I think of that earlier), all kinds of consoles through to the Genesis (and SNES?), and even VGA cards (by which point you've practically reached stereo CD quality).

    The best bit of this being that it would even work well on those which don't actually have a sound card in the first place. How about getting SB16 quality audio alongside hi-rez greyscale graphics out of a VGA PC... with no soundblaster at all? (Heck, maybe not even an Adlib... or internal beeper)

    It's a stunning idea that I can't believe has taken this long for anyone to have a go with... it's worthy of investigation and development.

    Anyway, it's late, and I gotta quit. I may have forgotten something I need to add later, but, honestly, I doubt it, as my attempt to be brief has again resulted in a book.

    #1005 | Comment by MarkP on Aug 12, 2016 09:51pm
  • Dumb question but why not just spew audio data to the parallel port and let an external DAC to the decoding? Seems like this guy has figured out how to overclock the parallel port to get plenty of output bandwidth.

    #1006 | Comment by Byrd on Aug 12, 2016 10:48pm
  • Byrd: That's definitely an option (see my comments on the subject further up). The downside is that it will require custom hardware, not just a cable. But I may definitely look into that.

  • The CoVox used on IBM compatibles when soundcards was expensive, can be built with resistors only.

    But AFAIK, the communication to the paralell port isn't exactly DMA, but requires active code to read/write to/from. The standard Amiga sampler uses a simple AD converter with powersupply from the paralell port, and it's not much different to output things the same way.

    Also, remember!, the CIAs are notoriously sensitive and prone to break for just about anything wrong unless buffered circuitry are used... (Read; ParNET for example).

    I can't remember what a standard A500/2000 can read/write on the parallel port, but is it about 15KHz (30KHz sample rate)?

    I must say this was a fun proof of concept. Unfortunately I don't have any A1200, only A4000.

    The ECS/OCS Amigas only has 16 gradients of gray. The AGA Amigas has 256 gradients of gray. The picture above is the back of a A1200 (hence the yellow video out), where the A500/2000 has a black one (and 16 grayscales).

    #1008 | Comment by Xtal on Aug 13, 2016 12:54pm
  • Oh, and the extra halfbrite doesn't add any more grayscales than the original 16. It's essentially 8 of the 16 grayscales. With two levels of black.

    #1009 | Comment by Xtal on Aug 13, 2016 01:09pm
  • Now, what if you could do audio processing using paint applications.. oh wait you can...

    Image Processing Techniques for Audio - Part 1
    Image Processing Techniques for Audio - Part 2


    Another interesting hardware project..

    #1012 | Comment by nick on Aug 16, 2016 09:15am
  • Why use the composite video port? why not use the RGB port instead? You can get 3 channels here without the SYNC.

    #1013 | Comment by Samuel on Aug 16, 2016 01:32pm
  • Samuel: A chose the composite port because it was available and unused. I'm already using the RGB port on my TV.

    Yes I could have used another port, but this was super easy and nobody uses the composite port anyways.

  • I have been trying to work out if there's a way to output audio from my Amiga 500 to my analog mixing desk, anyway ideas?

    #1116 | Comment by Jim on Jun 24, 2018 05:22pm

About You

Email address is not published

Add to the Discussion

Add to Google