59

One of my favorite videos ever is a tribute to Radiohead "Nude" by James Houston. I have never seen the program in the video available to download, so I've just made an attempt to extract it myself. Here are the steps I tried:

  • Grabbed the audio using youtube-dl by specifying the "best audio" mode, not downloading the video.
  • Trimmed the audio file to the ZX-Spectrum blocks using Audacity.
  • Mixed the stereo channel into a mono (Audacity).
  • Resampled the audio file to 44100 using sox (I probably did something wrong but I couldn't save the resampled audio with Audacity).
  • Normalized the audio to 0dB (Audacity; there's a click in the audio so the normalization effect gained not really much -- is it a blocker?).
  • Converted the result audio to a TZX file using tzxwave from the tzxtools toolkit.

The program in the extracted TZX file does not produce the exact tune that can be heard in the video, so I definitely did some mistakes in the middle (no "R Tape loading error" though). Here is what I was able to extract (in Base64): https://pastebin.com/3hBLbCzx.

What were my mistakes trying to extract the program in 100% accuracy?


I forgot to mention that I only converted the "best audio" youtube-dl was able to download from OPUS to WAV in order to process that WAV file, not the OPUS one. I'm still not sure about the entire audio "pipeline" configuration before decoding the audio into a TZX file. So, I'm thinking of two ways:

  • either my audio processing "pipeline" is wrong so that tzxwave extracts what it actually can (+ there are some more options in tzxwave that I didn't experiment with);
  • or the video features a perfect (despite lossy back to the early YouTube days) audio that may provide a real 100% working program, but the featured program generates a tune that slightly differs from what can be heard in the video by design (no intention to share a program track source by the author, copyright grounds, whatever). Why? No idea. tzxwave might do some corrections fixing "R Tape loading error" itself in certain cases, but I'm not sure about this too because I had tape loading errors multiple times before getting an audible result I shared with PasteBin.
  • 8
    I just wanted to say how much I appreciate your question. It is questions similar to yours that make me want to come to Retrocomputing at Stack Exchange. – introspec Apr 16 at 10:23
  • Cool project. Are you sure it is the/a real program at all and at full length? The Video is obvious created by cuting and editing various shots. It might be an idea to ask the creator if the loading section is really a complete recording. Not to request the program, but to learn if the task to take it from the video solvable at all. – Raffzahn Apr 16 at 11:25
  • @introspec the strange thing is that I never wondered what program is "aired" in the video for ten years. Yesterday I suddenly just tried to google for a TAP or a TZX, and found nothing to download. This led me to some experiments, but since ZX-Spectrum is only a part of my gaming childhood that still keeps sweet memories, and I'm not a sound engineer, my inaccurate attempt led me here. – fluffy Apr 16 at 12:34
  • @Raffzahn well, it sounds so and the stuff I was able to extract seems to be loaded without errors but the running result sounds slightly distorted (wrong notes, tempo, etc -- it makes me think that I might use wrong audio adjustments). Regarding the creator: I'll try to ask him. Thank you for the idea! – fluffy Apr 16 at 12:35
  • 2
    Well, in that case (distortion, wrong notes) it might as well be a filming of a previous version than the one used in the later video. It's worth to keep in mind that the desired result was a cool remix video. Here elements get mixed for their audio-visual effects, not transport the exact same code as used for the song. We're extreme nerdy here, aren't we? And I definitely like it – Raffzahn Apr 16 at 13:14
49

First, many thanks for the great question. This may well be my favourite retrocomputing video of them all, so I contemplated having a look at the executable for a while myself. So, this is what I did:

  1. To download the audio, I went to the same YouTube video and used 4K Video Downloader (mainly because it clearly shows which audio is the original one, so that I can avoid an extra re-recompression stage).
  2. I trimmed the relevant audio using Audacity, just like you did. The contents of the right channel has a large DC offset, so I assumed that the left channel must be closer to the original signal: enter image description here

  3. The quality of the signal is pretty low, but to a significant extent this is due to its very low amplitude. In the areas of pilot tone the signal is quite clean: enter image description here

  4. At the same time, where the actual data is recorded, the quality of signal is pretty poor, with rectangular shapes strongly distorted, I'd guess mostly due to the .mp3 compression: enter image description here

  5. Having said that, I think it is also clear that signals are distinguishable, with the bits in my screenshot being 0,1,0,0,1,1,... etc. This gives us hope that something can be recovered here.

  6. There are many programs created for recovery of tape data from audio files. One of the more recent ones is called TapeRecover, written by Andrei Titov (use Chrome to translate the page from Russian). I used this specific program because several people mentioned to me that it works well. It requires a very particular kind of input file: 48K mono .wav file. Transcoding from one discretization frequency to another is not a particularly great step to make, but I had no choice here.

  7. As we might have expected, the program struggled to recover the data from our original file. So, I prepared another one, with +40db amplification and hard clipping, to get closer to the shape these signals were supposed to have originally. This is what the resulting data looked like: enter image description here

  8. This turned out to be sufficient to recover the original data, which you can download here: http://introspec.retropc.ru/other/james%20houston%20-%20big%20ideas.tap. I verified it and can see that the binary is 100% the same as the one you recovered, so this is reassuring.

Of course, I couldn't just stop here and had a look at what it does. It turns out that the file plays music on AY8912 chip that was installed into every variation of ZX Spectrum with 128K of memory. The actual driver that plays music is extremely primitive; technically, it is a simple .psg-like player. .psg file format describes the values that have to be written into the sound chip during each interrupt cycle (which happen at frequency close to 50Hz). Since the information is stored as register values, the original editable file cannot be easily recovered. This is the disassembly of the player in case you are interested:

; this player is, effectively, the v-blank interrupt handler.
; it is automatically called approximately 50 times per second

    ld hl,(CurPos)      ; current position in the track

FrameLoop:
    ld a,(hl) : or a : jr nz,SkipFrame

        inc hl : ld a,(hl)
        cp #FF : jr z,CommandFF     ; end-of-track marker
        cp #FE : jr z,CommandFE

        ; the actual data is a pair of two numbers:
        ; a register number...
        ld bc,#FFFD : out (c),a
        ; ...followed by the register value
        inc hl : ld a,(hl)
        ld b,#BF : out (c),a : inc hl
        jr FrameLoop

SkipFrame:  ; non-zero bytes are decremented until we get to zero,
    ; i.e. they define a wait time in frames.
    ; this means in particular, that the data gets destroyed
    ; during playback (repeated playback is not possible!)
    ld (CurPos),hl
    dec a : ld (hl),a
    ei : ret

CommandFE:  ; the purpose of this command is not clear
    ; (it simply silently skips some bytes)
    ; luckily, it is never actually used
    inc hl : inc hl : ld (CurPos),hl
    ei : ret

CommandFF:  ; at the end of the track colour
    ; the border black and freeze
    xor a : out (254),a
    jr $

CurPos:     dw MusicPSG     ; current position in the track

MusicPSG:   ; music data follows here
    ; (32841-42169,9329)

However, listening to the tune it is clear that not only the main "voice" of the melody is coming out. I know that your assumption has been that it must mean that your capture has been somehow incorrect. However, I do not think that the chances for this are all that high. We used two different methods and recovered identical result. In addition, somewhat tuneless sounds you can hear - they may well be tuneless because they may be driving devices that introduce further distortions (i.e. detuning may be necessary to get them in tune).

In my opinion, all voices you can hear in the video - rhythm section on the printer, base line on the scanner (with the only exception of vocals) - are originally driven by ZX Spectrum's sound chip. My guess is that sound channels which would normally be joined together and outputted onto the speaker have been separated and used to drive other devices.

Last but not least, do not forget that the video itself has been edited and processed. Just as a somewhat relevant anecdote, I was the main coder for the MMCM's chiptune album: The Blossoming Years. Track 24 of this album is an electronic version of the album, effectively, tape recording of the demo program for 48K ZX Spectrum with an external AY interface. The album was released on the same day as the accompanying demo. However, the demo was not fully ready at the time when the album was being mastered, so as the result, the version of the demo that you will find by recovering Track 24 is not the same as the demo that was actually released.

UPDATE (18/04/2020)

Well, I really liked the theory that ZX Spectrum's AY chip was driving all these devices in the video, but sadly it is not the case. My checks of the music data seemed to indicate that instruments "jump" from channel to channel. This tends to happen when the track is not hand-made, but auto-generated from another format, most likely MIDI. Hence, I did a search for MIDI converters for playing tunes back on ZX Spectrum and found this thread on World of Spectrum: midi2ay 0.1. (The program is no longer available from Geocities, but Archive.org still has it.) The converter takes a .mid file and generates a corresponding .tap image automatically. In fact, the source of the assembly re-player there is also included with the program, from which you can immediately see that it is 100% identical to the re-player we downloaded.

Overall, then, my conclusion is as follows: the music was made elsewhere. The converted midi file loaded into ZX Spectrum and apparently playing in the video is highly unlikely to actually participate in the final mix.

| improve this answer | |
  • 5
    Wow! This is truly and incredibly fascinating! Your version sounds much cleaner than mine, and I'm sorry I don't have much knowledge in processing audio -- my steps were as primitive as they might be so this is why my program sounds less accurately than yours, obviously. Now I feel as if I've been told the greatest secret of all times! :) By the way: my broken version does not report tape loading error, but it's definitely wrong. Is the ZX-Spectrum data-to-audio encoding scheme not that error-resistant? – fluffy Apr 16 at 13:31
  • 1
    And one more question please: how did you figure out how the program plays the sound? I mean: do you probably recognize it by ear, or did you probably do some disassembly, or maybe some dump recognition? Thanks! – fluffy Apr 16 at 13:35
  • 1
    @fluffy, first, and foremost, I checked (and updated my post). Your program is 100% identical to mine. Binary equivalent. So even if it sounds better to you, it does the same thing. Second, I added a clearer discussion of why it may be doing what it does. – introspec Apr 16 at 13:58
  • 5
    The author is looking for the original, and mentions that the program needs at least a Spectrum+. – Stephen Kitt Apr 17 at 9:09
  • 2
    @Spektre, the disassembled code above is literally 95% of code. It definitely does not do anything beyond playing what it is playing. Sadly, the incorrect model of ZX Spectrum in the video seems to be not the only unauthentic thing about the video :) – introspec Apr 18 at 8:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.