18

I am digitizing about 40 tapes with programs for the ZX Spectrum. I am somewhat puzzled by the waveform after digitization. The signal of most cassettes is meander-shaped. meander-shaped meander-shaped meander-shaped One of the cassettes can be downloaded from DropBox.

Some cassettes have a sinusoidal signal. This is an example of a cassette with a bad record. This cassette has an unstable amplitude. sine wave sine wave This cassette can be downloaded from DropBox

Sometimes there are records with "dancing" short pulses. short pulses

Questions: 1. What shape should the pulses be for successfully decoding programs recorded on these tapes?

  1. What programs can help in decoding or preparing audio files for processing?

  2. Any hacks for successful processing of tapes.

P.S. After some experiments with adjusting the signal level and the tape recorder head, I came to the conclusion that this is important for some audio tapes. And returning to the topic - the waveform must be sinusoidal.

Demonstration of the same piece of tape as an example (this files can be downloaded from Dropbox.):

Before adjust the tape recorder head enter image description here

...after adjust the tape recorder head enter image description here

A. Rumlin
  • 391
  • 3
  • 8
  • 3
    Are these commercial tapes, or 'home' (AKA pirated duplicate) recordings? Have you tried adjusting head azimuth on the weak recordings? What do the clipped 'meander' waveforms look like if you reduce the playback volume? – Bruce Abbott Nov 17 '19 at 10:09
  • 1
    These are commercial pirate tapes. Covers - https://www.dropbox.com/sh/t6uqlmwctsrhhi1/AABd-g8GODhJpNRmHQrDuIlia?dl=0 I do not plan to adjusting head azimuth until I digitize all the tapes, then I plan to return to those tapes that have problems. I can not yet reduce the playback volume. To do this, I need to disassemble the tape recorder. – A. Rumlin Nov 17 '19 at 12:31
  • 4
    The 'sinusoidal' tape with unstable amplitude sounds like an analog copy recorded through the mic input (or perhaps even with a mic) with ALC (automatic level control) turned on. This explains the varying amplitude ('breathing') poor bandwidth and noise in the gaps. ie. a typical amateur pirate copy. Might be readable if the amplitude is increased until clipping. – Bruce Abbott Nov 18 '19 at 03:08
  • 3
    If by "decoding" you mean reconstructing the data stored on the tape (rather than being able to read the tape on original or reproduction hardware), then the important characteristic to look for when decoding is the time delay between zero-crossings (where the signal crosses the red horizontal line in your pictures). Alternatively, it may work better to measure the time delay between points where the curve has maximum slope versus minimum slope but this requires more math and may only help with particularly bad recordings. lvd's answer lists the expected time delays you need to fit data to. – Ken Gober Nov 18 '19 at 14:47

7 Answers7

12

Those variable amplitudes looks like electronics problem like failing caps somewhere along the way (recording/playback) or unshielded too long cables or partial remagnetization or even HW bug (some recorders like ELTA have a bug in writing head circuitry that corrupted tapes a bit each time it was played ...)

the correct output should be a rectangular signal with 2 levels of amplitude.

I do not know any tools for tapes but audio people are using AUDACITY

However writing own SW recognizing pulses and correcting the signal should be easy to do...

Here is captured GIF from mine emulator executing:

SAVE "xxx" CODE 0,16384

SAVE capture

On the left is border and on the right is Oscillogram of the SOUND output going to Soundcard...

[Edit1]

I finally had some time/mood for this. I made an win32 app for filtering the wav files in manner I described in my comments. Here it is:

  • My Win32 ZX_emu 1.56 + tape wav filter app

    both apps are win32 standalone no need to install anything. Read the readme.txt inside zip to know how to use it ... I included also full source code for the filtering app (Borland/Embarcadero BDS 2006 Turbo C++)

    The filter sum all channels into mono and find local min/max peaks and center it around 0 and also rescale to uniform amplitude ... +/- some noise detection/handling. The filter itself is in

    riff_filter_tape.h 
    

    source file in case you want to tweak it ...

I applied it on your GORR30_BallBreaker_A.wav here screenshot so you see the signal change after filtering:

filter preview

Your original wav does not load into my emulator. It does not go pass the first file header (no sync and no error). After filtering It got pass the file header:

header

but error while code:

error

so loader code is not correctly loaded (due to too much corruption of the tape):

code

So try to adjust the tape recorder head (with screw driver) first until you hear more clear sound, then play with volume ... digitize apply filter and try to load

Heh FUXOFT :) he had nice games, brings up memories

Spektre
  • 7,278
  • 16
  • 33
  • These are all tapes read on the same tape recorder. Most likely the tape is demagnetized. I saw a good review about tzxtools but have not tried this yet. https://github.com/shred/tzxtools – A. Rumlin Nov 17 '19 at 10:02
  • @A.Rumlin I added a GIF with what mine emulator creates while saving ... its just FM modulation, However passing such signal to the recorder will change it a bit (to more sinusoidal one) but there might be also other HW related quirks ... anyway repairing signal is easy you just substract sliding average from the signal and normalize amplitude (multiply and cut off) ... Do you have some sample wav files? – Spektre Nov 17 '19 at 10:10
  • 1
    PS the last image does not look demagnetized to me its more likely just a problem with higher frequency not passing correctly through the audio path so it has smaller amplitude... so either wrong cap or even not good metalic layer material for that bandwith or even not strong enough writing head as higher frequency needs more energy to magnetize – Spektre Nov 17 '19 at 10:16
  • @Spektre IIRC it's quite normal for bad quality tapes and simple recorders to limit the higher frequencies. Even good tapes tended to sound "muffled." – the busybee Nov 17 '19 at 14:27
  • 1
    What an emulator saves as a digital waveform is irrelevant for comparing with what a real (cheap and nasty) tape recorder saved on to real (cheap and nasty) tape - which is what the original spectrum decoder was designed to handle! – alephzero Nov 17 '19 at 15:11
  • @Spektre WAV has no significant differences from MP3 (example above) https://www.dropbox.com/s/yd4wgt01y20no8k/GORR30_BallBreaker_Saboteur_01.wav?dl=0 – A. Rumlin Nov 17 '19 at 15:32
  • 1
    @alephzero You missed my point I just wanted to show there is no nasty PWM technique used by native BASIC SAVE commands only simple FM modulation with 2 frequencies on data and 3th on sync (start) so amplitude of signal is irelevant ... and not some nasty encoding technique – Spektre Nov 17 '19 at 16:06
  • @A.Rumlin wav is signifficantly easier to decode ... so its much easier to write a simple tool for it then for mp3 which needs a lib for decoding ... – Spektre Nov 17 '19 at 16:21
  • 1
    @Spektre There are many utilities for converting MP3 to WAV, like ffmpeg. There is a fundamental difference in uploading and downloading files of different sizes to a file hosting service. In WAV - 1Gb, In MP3 - 150Mb. – A. Rumlin Nov 17 '19 at 16:37
  • @A.Rumlin Your wav is missing (cut off) the first sync beep or its a custom loader file (like some game additional code stuff. Some did not have the first sync beep because it was bypassed in ROM or the loader was completely custom) Now I get your point is about download size but I did not expect a hour long recording anyway. – Spektre Nov 17 '19 at 18:57
  • @Spektre The first record on the same tape - https://www.dropbox.com/s/n2upyq48xghwu91/GORR30_BallBreaker_A.wav?dl=0 – A. Rumlin Nov 17 '19 at 19:39
  • Pedant attack! WAV is a container format that's actually quite a lot of effort to support in its entirety — you need to cover at least PCM, ADPCM, a-law and µ-law encodings, and, strictly speaking, you'd need to be able to handle sampling rates of up to 2^32 Hz and possibly as many as 65535 channels. There are even a few other proprietary codecs you might encounter. WAVs are easy only if you limit yourself to the 80% case subset of PCM data, and probably only one or two channels. Supporting all possible MP3s is much easier than all possible WAVs. – Tommy Nov 17 '19 at 21:39
  • 1
    @A.Rumlin had some time to play with this today. It took me while to implement loading from wavs into my emulator but it finally works (till now it uses tap file and audio input but your recording is bad for going through DAC/ADC again). After sharpening the pulses the result is much better (hearable and also loading sripes apear as should) but still not good enough for sucesfull load so I need to test the centering of signal (center the peaks around zero and then amplify cut off ...) will get back with results but have no clue when as this week is full already... – Spektre Nov 18 '19 at 18:22
  • @Spektre What tool do you use to center the peaks around zero? – A. Rumlin Nov 18 '19 at 19:20
  • @A.Rumlin win32 C++ code ... that is why I wanted just wav so I do not have to work around mp3 codec.... playback is easy but to obtain raw data instead of sound is not possible with MCI and need a lib ... PCM avi RIFF is easy to implement (regardless of the possible sub formats) its much better than BMP where the same stuff make a real pain in the ass ... – Spektre Nov 18 '19 at 20:50
  • 1
    @A.Rumlin I added edit 1 with new stuff and also link to the filtering app ... – Spektre Nov 24 '19 at 12:18
  • 1
    @Spektre I edited my post. For some recordings, it is important to adjust the tape recorder head. – A. Rumlin Nov 25 '19 at 20:53
  • @A.Rumlin yep ... the reading head should be in position similar to where the writing head was while recording. There is a lot more going on than you see on the audio output as the tape was most likely pre-magnetized usually by AC 80-120 KHz signal (which is filtered out before playback) and different head gap position does not affect just amplitude but also the impedance/reluctance/inductance between head coils and medium changing the spectral response too... – Spektre Nov 25 '19 at 22:13
  • @A.Rumlin the new recording after filtering loads the custom loader but resets the emulator after while ... so its still not clear enough ... – Spektre Nov 25 '19 at 22:28
  • @Spektre I think it is likely that the program was recorded with an error initially. Pay attention to the labels of these cassettes. In this case, GORR30.jpg This program has no "+" label. It can be understood that the owner of these tapes had problems with this program initially. Perhaps a problem in one bit dramatically changes this program. https://www.dropbox.com/sh/ec3a4127y5gxgab/AADRPjl4zPWBQYvKtm2R2g7fa?dl=0 – A. Rumlin Nov 26 '19 at 05:38
10

Check this Spectrum tape interface:

Pulses

A 'pulse' here is either a mark or a space, so 2 pulses makes a complete square wave cycle.

Pilot tone: before each block is a sequence of 8063 (header) or 3223 (data) pulses, each of length 2168 T-states.

Sync pulses: the pilot tone is followed by two sync pulses of 667 and 735 T-states resp.

A '0' bit is encoded as 2 pulses of 855 T-states each.

A '1' bit is encoded as 2 pulses of 1710 T-states each (ie. twice the length of a '0')

The initial polarity of the signal does not matter - everything in the ROM loader is edge-triggered rather than level-triggered.

lvd
  • 10,382
  • 24
  • 62
  • 3
    With the potential caveat: tape input is achieved through the Z80 in a busy loop, constantly polling a 1-bit conversion of the input wave. So a commercial title can do pretty much anything it wants as to bit encoding and baud rate. – Tommy Nov 17 '19 at 21:31
  • How does this answer the question about waveforms? – Peter Mortensen Sep 13 '21 at 14:10
5

A1.

The shape is not as important as it looks. The Spectrum uses a primitive FSK decoding, so the amplitude of the audio signal is not used, nor if it is sinusoidal or squared. The key thing is "zero crossing points": the signal must be so that its level goes up and down the zero volts level and stay in either area the same time. During the decoding phase, the Spectrum detects edges (from low to high, or high to low) and measure how much time the signal stays in one half or the other.

So, any audio signal that meets this criteria, and has enough amplitude (about 3Vpp) so that the input can drive the small trigger schmitt input at the ULA should work. Ideally, edges should be as sharp as possible.

A2.

Any decent audio editor. Audacity can help you. I use Sound Forge more, and I've found the touch pencil tool to be extremely useful to perform fine editings to restore audio levels where the volume dropped out.

A3.

Use, when possible, a mono cassette, not a stereo one (the coil and aperture at the magnetic head is a little bigger and will help you to capture a better signal). Of course, demagnetize the reading head and adjust it. The Spectrum +2/+3 has a service mode in which a small utility to calibrate tape heads is available.

mcleod_ideafix
  • 18,784
  • 2
  • 70
  • 102
4

A possible tool is eightbitjim/cassette-nibbler: Data recovery from 8-bit computer cassette tapes (Commodore 64, Vic 20, ZX Spectrum, etc). I'm not sure how well it reads nonstandard loaders, but in listing mode (-destination=listing) it gave me this for the GORR34 tape converted to wav:

java -jar ../cassette-nibbler-0.1.jar -destination=listing ../GORR34_Firetrap_Carlos_Sainz.wav 
--------------------------------------------------------------------------------
cassette-nibbler v0.1
--------------------------------------------------------------------------------
Allow incorrect frame checksums : ON
Allow incorrect file checksums  : ON
Attempt to recover partial files: ON
Platforms enabled: commodore commodore16+4 c64-turbotape acorn300 acorn1200 spectrum oric1 oricatmos msx2400 msx1200 trs80 dragon32 apple2 amstrad atari 
../GORR34_Firetrap_Carlos_Sainz.wav--------------------------------------------
[#############################################################################]
(15) headless.data length 1796
0 FIRETRAP 1.bytes.4b3104c.ERR.zxspectrum.bin: 25190 bytes 
1 DR. BREE.program.5ac6307a.zxspectrum.bin: 1028 bytes 
2 D_BREED1.bytes.c1cbb19d.zxspectrum.bin: 2872 bytes 
3 LORNA.1.bytes.527e6822.zxspectrum.bin: 3663 bytes 
4 LORNA.2.incomplete.bytes.6c060aeb.ERR.zxspectrum.bin: 1 bytes 
5 CARLOS.program.b12f74ba.zxspectrum.bin: 527 bytes 
6 CARLOS.1.bytes.450493bd.zxspectrum.bin: 4217 bytes 
7 CARLOS.3.bytes.33b07286.zxspectrum.bin: 887 bytes 
8 INDY.program.d828517a.zxspectrum.bin: 255 bytes 
9 lucas.bytes.6728795d.zxspectrum.bin: 5120 bytes 
10 loader.bytes.d1d4554e.zxspectrum.bin: 256 bytes 
11 headlessFile95.incomplete.unknown.279f866f.ERR.zxspectrum.bin: 17421 bytes 
12 headlessFile114.incomplete.unknown.348fe7c0.ERR.zxspectrum.bin: 5039 bytes 
Processed 58 minutes 0 seconds (57.0x realtime)--------------------------------
[#############################################################################]
(15) headless.data length 1796

FIRETRAP seems to be a cracked copy of R-Type 2, from the loader information dumped by cassette-nibbler. By running the program with no special options then converting the CARLOS* TAP files to wav, joining them, then running the whole mess through fuse, I at least got a loading screen: Carlos Sainz loading screen, via cassette-nibbler With some more intelligent use than mine, I'm sure you could recover something.

Alternatively there's audio2tape from fuse-utils. It's very slow, and didn't do as good a job.

scruss
  • 21,585
  • 1
  • 45
  • 113
  • Unfortunately this does not work for me in Windows7: java -jar d:\Games\ZX\cassette-nibbler-master\target\cassette-nibbler-0.3.jar -destination=listing GORR34_Firetrap_Carlos_Sainz.wav cassette-nibbler v0.3 Allow incorrect frame checksums : ON Allow incorrect file checksums : ON Attempt to recover partial files: ON 100%: GORR34_Firetrap_Carlos_Sainz.wav (0 files extracted): GORR34_Firetrap_Car No files found Processed 57 minutes 59 seconds (24.0x realtime) (0 files extracted): Pro – A. Rumlin May 07 '21 at 05:03
  • I meant to say: I split the file to separate channels. Stereo computer audio seldom works – scruss May 07 '21 at 23:05
4

I did recover a GORR30_BallBreaker_A.wav, and, yes this record is initially broken. There are twenty seven (27) bits missed in middle of it. The broken part is marked with yellow circle on screenshot: GORR30_BallBreaker_A.wav

To repair a wav file, I had used my program ZXTapeReviver (64-bit Windows version 3)

You can freely try to use it to repair your ZX Spectrum tape records. But, please, keep in mind, that this program is in early development stage and can contain some bugs.

Program overview and how-to-use video you can watch here: https://youtu.be/i3FRRAro8hA

Recovered TAP file you can download here: https://cloud.mail.ru/public/uDTo/SoLjm4sf8

wizzwizz4
  • 18,543
  • 10
  • 78
  • 144
mdaemon
  • 41
  • 1
  • the program not worked in Win7x64. Error 0xc0000005 – A. Rumlin Sep 12 '21 at 04:36
  • Windows 7 is outdated for now, please consider to use recent OS, such a Windows 10 or higher or modern linux distribution. Additionally, you can try to manually build the app from sources under your Windows 7 installation (I'm not sure about Qt support of Windows 7, so maybe you'll be get failed), as I do not have Windows 7 on my PC and can't do that. – mdaemon Sep 15 '21 at 14:00
3

Waveform like on image #3 (https://i.stack.imgur.com/AmFn5.png) should work.

The perfect audio signal looks like this:

enter image description here

The procedure to achieve perfect copy:

  1. load original signal to PC (use Audacity free);
  2. correct signal if needed (Audacity);
  3. convert audio to digital TAP format (open in emulator, save as TAP);
  4. convert TAP to WAV for use on real Spectrum (Tap2Wav free).

If input audio signal is bad, try to tune audio head on cassette player by listening tone on headphones. Also, try to lower volume to 75%, as high amplification can make it sound worse. Don't bother saving games that you can download from some of the ZX Spectrum archives.

Sasha381
  • 31
  • 3
  • 4
    That's not the waveform you'd get out of a cassette, though: what you're showing there is the theoretically perfect square wave output from a program like tap2wav. Real tapes are much messier, and the OP is asking about existing tapes they wish to digitize, not ones they wish to create. So you're not really answering the question. – scruss Apr 09 '20 at 16:28
2

Just my 2 cents on this. The Spectrum tapes you are looking at use Frequency Modulation (FM) instead of Amplitude Modulation (AM). This makes them incredibly resilient to amplitude noise, such as you are showing a lot of. So, the actual data values are not encoded by the amplitude of the signal, rather the frequency of it.

I assume that you'd need a frequency demodulator, either software or hardware.

But that's only half of your problem. The other half is that I assume that whatever data you have on there needs to run on a spectrum emulator, so you need to piece it back together correctly. Simply capturing the signal won't work, so I'd look for an emulator that has the ability to load from audio files, then save a snapshot of the memory right after loading.

I listened to some of the tapes you attached, and for the fun of it, I manually decoded the first header of the GORR11_A_SDII_B_TLL, it looks something like this:

01010011 S
01010010 R
01001001 I
01001001 I
00100000 space
00100000 space
00100000 space
00100000 space
00100000 space
00100000 space
-> Title seems to be SRII

10100100 164 00000010 2 -> 676 bytes

00000000 00000000 -> to load at 0?

10100100 00000010 00000001

Blake
  • 29
  • 1