"Ohne Dich": Play digital audio from tape in real-time

Discuss anything related to the VIC
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

"Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

This piece is supposed to play a pulse width modulated tune from tape at four bits resolution. Sampling rates of up to 6kHz are possible without additional distortion.

4kHz version with some geek trying to sing:

PAL version: http://hugbox.org/pixel/software/vic-20 ... ch_pal.zip
NTSC version: http://hugbox.org/pixel/software/vic-20 ... h_ntsc.zip

Another version with a well–known jump'n-run theme:

PAL version: http://hugbox.org/pixel/software/vic-20/mario_pal.zip
NeverTheSameColor version: http://hugbox.org/pixel/software/vic-20/mario_ntsc.zip

A preview package of both tunes at 6kHz sampling rate is laying around here:
http://hugbox.org/pixel/external/denial/ohne_dich6k.zip
Last edited by pixel on Sun Apr 17, 2016 11:34 am, edited 1 time in total.
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

The timer is now self-adjusting at the cost of sound quality. IMHO there's no way around that.

All files have been updated again.
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by Boray »

I thought only one bit was possible...?
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

It's pulse width modulated. So, this thing uses 16 different pulse lengths. And now it constantly calculates the average pulse width to keep the needle in place.
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

Here's the code from the first version without timer adjustment. Things quite fell into place at ~4kHz.

Code: Select all

average_loop_cycles = @(half (+ 4 2 2 3))
sure_delay = 7
timer = @(- (* 8 audio_longest_pulse) average_loop_cycles sure_delay)

tape_audio_player:
    ; Start tape motor.
    lda $911c
    and #$fd
    sta $911c

    ; Initialize VIA2 timer 1.
    ldx #0      ; one-shot mode
    stx $912b
    lda #<timer
    sta $9124
    ldy #>timer

    ; Play.
f:  lda $9121   ; Reset the VIA2 CA1 status bit.
l:  lda $912d   ; (4) Read the VIA2 CA1 status bit.
    lsr         ; (2) Shift to test bit 2.
    lsr         ; (2) Could be "and #2" but these uneven cycles dither the output nicely.
    bcc -l      ; (2/3) Nothing happened yet. Try again…

    lda $9124   ; (4) Read the timer's low byte which is your sample.
    sty $9125   ; (4) Write high byte to restart the timer.
    lsr         ; Reduce sample from 7 to 4 bits.
    lsr
    lsr
    sta $900e   ; Play it!
    sta $900f   ; Something for the eye.
    jmp -f
EDIT: Removed a leftover "tax".
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

OK. I guess it won't get any better. My flatmate's brain has been formatted with the Super Mario theme, so I'll get dragged back into life anyhow. Here's the version with self-adjustment. If anybody would go through the trouble of testing the TAPs on a real machine – that would be lovely! :)

Code: Select all

current_low = 4                                                                 
average = 5
tleft = 7

average_loop_cycles = @(half (+ 4 2 2 3))
sure_delay = 7
timer = @(- (* 8 audio_longest_pulse) average_loop_cycles sure_delay)

tape_audio_player:
    ; Start tape motor.
    lda $911c
    and #$fd
    sta $911c

    ; Initialize VIA2 timer 1.
    ldx #0      ; one-shot mode
    stx $912b
a:  lda #0
    sta tleft
    sta average
    sta @(++ average)
    lda #<timer ; Set to countdown from longest pulse length in theory.
    sta current_low
    ldy #>timer

    ; Play.
f:  lda $9121   ; (4) Reset the VIA2 CA1 status bit.
l:  lda $912d   ; (4) Read the VIA2 CA1 status bit.
    lsr         ; (2) Shift to test bit 2.
    lsr         ; (2)
    bcc -l      ; (2/3) Nothing happened yet. Try again…

    lda $9124   ; (4) Read the timer's low byte which is your sample.
    sty $9125   ; (4) Write high byte to restart the timer.
    tax
    lsr         ; (2) Reduce sample from 7 to 4 bits.
    lsr         ; (2)
    lsr         ; (2)
    sta $900e   ; (4) Play it!
    sta $900f   ; (4) Something for the eye.

    ; Make sum of samples of which we'll draw the average later on.
    txa
    clc
    adc average
    sta average
    bcc +n
    inc @(++ average)
    bne -f   ; (unconditional jump)
n:

    ; Make the great divide if we've summed up 128 samples.
    dec tleft
    bne -f

    ; Correct timer if average pulse length doesn't match our desired value.
s:  lda @(++ average)   ; average / 256
    tax
    cmp #$29            ; 41… why? Should be 64.
    beq +j
    bcc +n
    dec current_low
    bne +d     ; (unconditional jump)
n:  inc current_low
d:  lda current_low
    sta $9124

    ; Divide average by 128 and restart summing up samples.
j:  txa
    asl
    sta average
    lda #0
    rol
    sta @(++ average)
    lda #128
    sta tleft
    bne -f   ; (another unconditional jump)
Last edited by pixel on Tue Apr 28, 2015 1:56 pm, edited 1 time in total.
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
freshlamb
Vic 20 Dabbler
Posts: 76
Joined: Sun Apr 04, 2004 5:38 pm
Website: http://www.rufnoiz.com
Location: Prince Albert SK Can

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by freshlamb »

Works exactly the way you said it would for the NTSC version on a real Vic! I will post video when I get a chance.
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

YES!!1!!!1! Wanna see it! Thanks 1E6! :D
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

Freshlamb: I was just wondering how you got the thing on tape and what type of tape you used. If somebody converts one of those TAPs to an audio file with 48kHz sampling rate it'd end up with less than three bits per sample. My thinking is that I'd have to get one of those sexy SD2IEC devices and to code a tape writer to get it done for real.

The original intent was to also put on some video as well. But before you're totally convinced that I'm off-the-map nuts: back in the days it was almost no problem to record 4.8kbits/s on an Amstrad CPC464 tape drive and what we have here is some kind of analogue recording that ignores errors.

Anybody an idea what the physical limits are?
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

I've put 48kHz WAV files for the tapes online as well.

Turn down the volume before playing these like regular music unless you want a new haircut!

http://hugbox.org/pixel/software/vic-20 ... al.wav.zip
http://hugbox.org/pixel/software/vic-20 ... sc.wav.zip
http://hugbox.org/pixel/software/vic-20 ... al.wav.zip
http://hugbox.org/pixel/software/vic-20 ... sc.wav.zip
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
freshlamb
Vic 20 Dabbler
Posts: 76
Joined: Sun Apr 04, 2004 5:38 pm
Website: http://www.rufnoiz.com
Location: Prince Albert SK Can

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by freshlamb »

I used AudioTap to convert, Wavelab for any adjusting, and just recorded on my tape deck. So perhaps there is a degrading of the sound. Here is a video link. https://www.youtube.com/watch?v=PahhRvIVdVM
User avatar
Jeff-20
Denial Founder
Posts: 5759
Joined: Wed Dec 31, 1969 6:00 pm

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by Jeff-20 »

Rock Band for the Vic 20. Coming soon.


Sent from my phizzone
High Scores, Links, and Jeff's Basic Games page.
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

Thany you for that wonderful video! I'm seriously baffled about it working at all on a real machine… :shock: I had to sleep over it first. Boray probably has no idea how many days and nights his player has been running here as an inspiration. :mrgreen:

I didn't really understand what's going on in the last few seconds of the video, though.

If you want to hack in your own samples they have to be 4-bit, as you might have guessed, but they also have got to be unsigned. Then add $18 to each sample and, voila, you have the TAP data. The "sox" audio converter gave me terrible results, so I'm actually converting 16-bit samples myself. Don't let your audio converter dither the samples! They're are dithered by the player already! Also, a lowpass filter at 2kHz, as suggested by boray, is a real quality enhancer. Another problem: "Ohne Dich" rumbles a lot, because the bass is too strong. Last but not least a compander brings back silent passages. Writing the player was no problem in matters of time – but converting the music took _ages_!

I'm super-glad because this brings "Pulse" close to a tape release. An SD2IEC is on it's way now (I hope) to write the tapes.

Yeah! Vic Band! Teeheeheeh! For SD2IEC and tape, please! I guess disk drives won't be of much help?
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
User avatar
freshlamb
Vic 20 Dabbler
Posts: 76
Joined: Sun Apr 04, 2004 5:38 pm
Website: http://www.rufnoiz.com
Location: Prince Albert SK Can

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by freshlamb »

Probably around the same time you were making your player (because I have no SDIEC) I was wondering if I could make samples play from memory, so that is what the last part of the video is. Just me experimenting.

I looked at the code for your player, and have yet to wrap my head around it. Because I use synths I vaguely understand PWM, but I'm not sure how it applies. At any rate the player is very, very cool. I want to try the new WAV's you put up, as soon as I can.
User avatar
pixel
Vic 20 Scientist
Posts: 1342
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: "Ohne Dich": Play digital audio from tape in real-time

Post by pixel »

I'm afraid the VIA chip isn't explained in very enjoyable ways anywhere.
Had to grab a sheet of paper and lay out the register and bits myself to
get it in.

The two VIAs have two timers each that count down at the speed of the CPU
clock. Timer 2 in each chip has the advantage that it has "latches". If
you write the low byte of the timer, it goes into the latch without
affecting the timer. As soon as you write the high byte the timer is set
to the written values, counting down. If you set the timer to 256 on a NTSC
VIC it'll count down to 0 in 1027270 / 256 = 1/4013s.
Fortunately, the timers can also be read.

The VIA can tell you if the signal from tape went low – the end of a
pulse; that's that status bit. It has to be reset manually.

Now, that's all we need. The recorded pulses look like this:

Code: Select all

          192 cycles       | 128 cycles max.
    ------------------------FEDCBA9876543210 <- sample values for each 8
    |                      |    variable   |    extra cycles
    | minimum pulse width  |   additional  |
    |                      |     width     |
    Longest pulse is 310 cycles. ---------->
    Average is 256 cycles ---------->
                                    +       
                                    | +     
                                    |  +    
                                    |   +   
                                    |   +   
                                    |  +    
                                    | +     
                                    |+      
                                    +  <- our audio wave
                                   +|       
                                  + |       
                                 +  |       
                                +   |       
                                +   |       
                                 +  |       
                                  + |       
                                   +|       

We need the minimum pulse width to actually output the samples and to
do the bookkeeping. More about that later on.

Now for the actual playing. We set the timer to the longest pulse length of
210. When the minimum pulse width has passed the timer counted down to
128. When the pulse stops a little bit later we get some value from 120
to 127. That shifted three bits to the right gives us the sample value 15.
When the status bit signals that the pulse ended we just read the low byte
of the timer, immediately reset the timer by writing its high byte, then we
shift the value we've just read and output it.

That's where the trouble starts. One cannot assume that all tape drives
have the same speed and we need some way to adjust the maximum pulse length
somehow. If we calculate the average value of all samples, we get the sample
value that lies on the center of our audio wave. The timer should've counted
down to 64 if the timing was perfect. (Sure as hell that's only the case in
VICE.) If the average timer value is above our desired value, we decrement
the longest pulse width or we increment it or we leave it alone when it's
right. BUT you have to take the time into account that is not measured
from the point when the status bit isn't yet detected (average loop cycles)
and the sure time not measured until the timer is restarted. Maybe that's
why the desired average is 41, not 64.

How the average is calculated isn't very obvious since the player isn't
initialized properly. Since it's self-adjusting it simply doesn't have to
be. It sums up the last 256 samples in chunks of 128 to let the former
averages flow in, so the change would be gradual. I've no bloody clue
about mathematics. It just hit me on the throne and it works. Might also
a flaw in this algorithm that skewed the desired average sample.

I'm sure that everything will be explained some day.
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
Post Reply