Wave-player (digi) code for Vic-20

Basic and Machine Language

Moderator: Moderators

Post Reply
Athlor
Vic 20 Drifter
Posts: 30
Joined: Mon Sep 01, 2008 11:58 pm

Wave-player (digi) code for Vic-20

Post by Athlor »

Anybody know of any Vic-20 programs that used wave-playing/audio code? I got the asm source for the kepu demo but how about any others.
JJ Abrams Star Trek: Boldly going where we've already been...
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

You mean .wav files??? Or just any samples? It's just to put the samples one after the other into the volume control. That's it.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
User avatar
Schema
factor
Posts: 1430
Joined: Tue Mar 23, 2004 7:07 am
Website: http://www.jammingsignal.com
Location: Toronto, Ontario

Post by Schema »

Athlor
Vic 20 Drifter
Posts: 30
Joined: Mon Sep 01, 2008 11:58 pm

Post by Athlor »

I meant any wav/digital audio format. But, Schema, that was exactly what I was talking about. You did it with samples in under 512 bytes. Man, if we could only go back in time. That was freak'n sweet and I bow'eth before thee. :shock:
You don't mind if I disassemble it and use it in the future? Naturally, I would credit you for the code.
JJ Abrams Star Trek: Boldly going where we've already been...
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Adam Klotblixt also experimented with 256 byte samples already for the Veni Vidi VIC! demo (1996) but that player took up about 100% CPU time so it was never used. I think it was discussed before in this forum, see:

http://sleepingelephant.com/ipw-web/bul ... .php?t=866
Anders Carlsson

Image Image Image Image Image
Athlor
Vic 20 Drifter
Posts: 30
Joined: Mon Sep 01, 2008 11:58 pm

Post by Athlor »

Actually I did catch the post, Carlsson, after I posted this. I since went further back through the programming forum's messages. I'm going to study that one as well.
Schema's little gem I have disassembled and looked at, he did post the C64 source so I figured it would be alright. Now as I understand it both 4-bit samples are combined to form a byte. A question for him is what's the sampling rate for the samples? Is there any easy tool around to make 4-bit samples from 8-bit ones or even combine them?
Ideally, I'd like to make a simple digi player that uses the timer. I got no problems with either the sampling rate or length of 256 bytes. This could be a boom to sound programming for the Vic.
JJ Abrams Star Trek: Boldly going where we've already been...
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

To convert samples from 8 to 4 bit, you can just use the 4 most significant bits... Easiest way to do that is probably to perform four right shifts.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

You could store two 4 bit samples in every byte to save space and make a player that reads and plays that...
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

Maybe this thread should be moved to the programming section?
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
User avatar
Schema
factor
Posts: 1430
Joined: Tue Mar 23, 2004 7:07 am
Website: http://www.jammingsignal.com
Location: Toronto, Ontario

Post by Schema »

Athlor wrote:A question for him is what's the sampling rate for the samples? Is there any easy tool around to make 4-bit samples from 8-bit ones or even combine them?
It's been a while, so I forget what the original sampling rate was! :oops: 8Khz maybe? But I re-processed them quite a bit. Here is a technical article I wrote for our club newsletter back then that fills in some of the details.


The World's Smallest "DIGI"!

By Leif Bloomquist

About Digis on the Commodore 64

As a Commodore owner, you're aware of how innovative the SID chip was for its time, with its three voices and different waveforms. But the
SID has another way to produce sound - a "fourth voice", if you will,
in the form of digitized sound samples. These are usually referred to
as "digis".

Digis work by manipulating the volume register (54296 or $D418 hex) at
high speed. You can hear this effect yourself. Turn on your C64,
turn the volume on your monitor or speakers up a bit, and then type:

POKE 54296,15

You will hear a slight "pop" from the speaker. The effect is even
more pronounced on older C64s, due to a slight design flaw in the SID
circuit. But this flaw was used by programmers to great effect for
digitized speech or drums in game music.

By changing this register very quickly, you can play back digitized
samples on the C64. With 4 bits dedicated to the volume register, you
even get 16 levels of sampling resolution which makes them sound even
better.


The TinySID Contest

The TinySID contest, organized by Stefano Tognon in Italy, is an
"online C64 music-programming competition made in love of SID music."
It challenges people to write songs for the C64 and SID chip, that are
either 256 bytes (yes, *bytes*), 512 bytes, or 1,024 bytes (1KB) in
length.

The website for the contest is here. This is the second year it has been held.

http://digilander.libero.it/ice00/tsid/ ... index.html

I decided to enter the contest this year. I had been playing around
with digis on the C64 and thought - what is the smallest digi
possible?

With some experimentation, I found that 256 byes was about the
smallest digi that still sounded good. Any less than that and the
sample became too rough and crackly.

However, I still needed room for the code to play back the digi, and
to store the notes for a short "song". So I would not be able to
enter the 256 byte category, I had to move up to the 512 byte
category.


Creating the Mini Digi

To start, I needed samples to work with. Note that a digi has 4-bit
resolution, but a byte has 8 bits. So I was actually able to cram
*two* digis together, one in the upper four bits, and one in the lower
four bits.

Also, it is possible to change the pitch or frequency of a digi, by
playing it back faster or slower. So I decided to make my entry a
drum solo, with two different instruments. By changing the pitch, I
could simulate more instruments.

To create the drum sound digis, I used a Windows program called
'FruityLoops'. Fruityloops (http://www.fruityloops.com) is a PC-based music and "looping" software for creating electronic music. I created a
bass drum sample, and a snare drum sample.

From there, I manipulated the sample in another Windows program called
GoldWave (http://www.goldwave.com) to be only four bits per sample. Finally, I wrote my own software in Microsoft Visual Basic (the modern version of BASIC on the C64!) to change the samples so they contained only positive numbers.

Now that I had my samples, I needed to write software in Machine
Language on the C64 to play them back. Machine Language is necessary
to get the playback speeds, BASIC is too slow!

Each note in the "song" has three elements:

-Which sample to play (1 or 2)
-Playback frequency
-Duration (time before the next note)

I came up with a scheme where I could pack all this information into a
single byte. The highest bit determined the sample. Three bits were
used for the playback frequency. Four bits were used for the
duration. This way, I had 16 choices for the duration, which could be
evenly divided into whole, quarter, half, and sixteenth notes. I used
the C64's Jiffy clock to determine the elapsed time.

By changing the frequency, I could simulate other instruments: When
sped up, a bass drum sounds like a tom-tom drum. A snare when played
faster sounds like a hi-hat.


Pulling it all Together

The last thing to do was to actually write the drum solo. Using Excel
on the PC, I generated a spreadsheet that would allow me to easily
write the song as a series of notes. Excel would then "pack" the song
into the bytes using the format described above.

I assembled the song, software, and digis together using the DASM
Assembler (http://www.atari2600.org/DASM/) on my PC and transferred it
to my C64. From there, I tweaked the solo a little bit and went
through a few iterations until I was happy with how it sounded.

Here's the breakdown of the final program:

Samples: 256 bytes
Playback code: 143 bytes
The song: 109 bytes
TOTAL: 508 bytes

Then two bytes are needed for the load address ($0801) and I was done,
with two bytes to spare!

If you want to learn more, the source code to the program is available
at the contest website (given above), along with all the other
entries.
Athlor
Vic 20 Drifter
Posts: 30
Joined: Mon Sep 01, 2008 11:58 pm

Post by Athlor »

I put together a tiny 19 byte digi player that pokes into the RS232 area (664) and tryed using the last 256 bytes of Basic area on an unexpanded as the storage. The results haven't been good, yet. I was using Wave lab but it only samples down to 8-bit 2000 samples/sec and my card won't play anything under 6000 or so. I did find a couple interesting programs from the C64 side, Pack4bit and Konv1. One takes a .wav and after converting it to 4-bit packs every 2 bytes into a hi/low nibble byte cutting the size in half. The other takes 2 wav's and creates a single file with each occupying a hi/lo nibble, which is the way you, Schema, also did it. There are a few more things I'd like to try like a packed sample in the cassette buffer. It's even less than 256 bytes at 204 but a packed sample could be 408 bytes then. I've got another wave util on a CD somewhere, Sound Forge if I'm not mistaken, I'm going to try that.
JJ Abrams Star Trek: Boldly going where we've already been...
Athlor
Vic 20 Drifter
Posts: 30
Joined: Mon Sep 01, 2008 11:58 pm

Post by Athlor »

To finish off this tangent, here was the unbelievably simple code:

Code: Select all

  processor 6502
  org $0298       ; Rs-232 area

start:
    ldx #$00
loop:
    lda $0334,x   ; Sample value (cassette buffer)
    sta $900E     ; Volume (bit 0-3 vol)
    ldy #$80      ; Delay value
delay:
    dey
    bne delay

    inx
    cpx #$cb      ; Cassette buffer max
    bne loop

    rts
And finally I modified Csabo's Digi_128 little drm and bass demo code for the Plus4 to work on the Vic. It's just over 128 bytes and has 3 16-byte 'samples' for DASM. It sounds surprisingly good!

Code: Select all

; Digi 128 - Written by Csabo of LOD, 2003
; Converted from Plus4 version for Vic & DASM 
  processor 6502
  org $1001

  .word $100D,0       ; line # 0
  .byte $9E           ; token for 'SYS'
  .byte "4109",0,0,0  ; SYS4109 & eol data

restart:
  INC count     ; Increase pattern counter
  LDA count
  AND #$1F      ; Limit to 32 bytes in pattern
  TAX
  LDA track,x
  STA datapos+1 ; Load data position for current
  LDY #$00      ; Starting frequency

main:
  INX
  TXA
  AND #$0F
  TAX
datapos:
  LDA snare,x
  STA $900E     ; Volume (bit 0-3 vol)
  STY wait
delay:
; ASL $A9       ; Just to make it slower (unneeded on Vic)
  DEC wait      ; Delay loop
  BNE delay

  INY
  CPY #$B0      ; Ending frequency
  BNE main

  BEQ restart   ; Always jump

noise:   ;Quiet noise to emulate hihat or silence
  .byte $05,$04,$05,$07,$05,$07,$05,$04 
  .byte $05,$04,$05,$07,$05,$07,$05,$04

bass:    ;Sine wave to emulate bass drum
  .byte $00,$00,$01,$03,$05,$07,$09,$0d 
  .byte $0b,$09,$07,$05,$03,$01,$00,$00

snare:   ;Random white noise to emulate snare
  .byte $00,$08,$02,$04,$07,$04,$03,$01 
  .byte $05,$02,$0d,$06,$01,$08,$02,$03
  
b = bass & 255
h = noise & 255
s = snare & 255

track:   ;The beat
  .byte b,h,h,h, s,h,h,b, h,h,b,h, s,h,h,h
  .byte b,h,h,h, s,h,h,b, h,h,b,h, s,h,h,b

wait:  .byte $EF
count: .byte $EE
JJ Abrams Star Trek: Boldly going where we've already been...
Post Reply