One hour of digitized music for your Vic-20
Moderator: Moderators
One hour of digitized music for your Vic-20
No, it's not april fools day!
Here:
http://user.tninet.se/~pug510w/datormus ... layer.html
Requirements: Unexpanded PAL Vic-20 + SD2IEC card reader
(or alternatively PAL VICE emulation).
This program might break a couple of world records: The longest sample ever played on a Vic-20? (my 25 minutes long Amzidus). It's probably also the largest Vic-20 application ever made. It's 6.8 MB in size!
Here:
http://user.tninet.se/~pug510w/datormus ... layer.html
Requirements: Unexpanded PAL Vic-20 + SD2IEC card reader
(or alternatively PAL VICE emulation).
This program might break a couple of world records: The longest sample ever played on a Vic-20? (my 25 minutes long Amzidus). It's probably also the largest Vic-20 application ever made. It's 6.8 MB in size!
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Today I experimented on increasing the sound quality a bit. I tried with 5.5kHz and some dithering and filters and stuff. It doesn't sound radically better but a little bit better. So I think I will release a second collection at some time. Maybe at the same time I release my next album or something.
Do any of you programming gurus have any ideas on how to improve the timing of the player? Some sort of timer? Right now I'm just using a delay and that makes the playback vary a bit because of the disk/sjload reading time.
The player looks (something) like this:
Do any of you programming gurus have any ideas on how to improve the timing of the player? Some sort of timer? Right now I'm just using a delay and that makes the playback vary a bit because of the disk/sjload reading time.
The player looks (something) like this:
Code: Select all
init:
LDX #$02
JSR $FFC6
opa:
JSR $FFCF
sta 36878
INC 36879
ldx #$21
ful1:
dex
bne ful1
clc
ror
clc
ror
clc
ror
clc
ror
TAY
JSR $FFb7
CMP #$00
BNE slut
stY 36878
DEC 36879
ldx #$12
ful2:
dex
bne ful2
jmp opa
slut:
lda #2
jsr $ffc3
rts
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
- Mike
- Herr VC
- Posts: 4845
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
As you already should have noticed, the variant execution time of CHRIN introduces a lot of jitter, the delay loop just makes it less apparent (sort of like the current limiting resistor in series to a LED). And it only works well on SD2IEC devices, where sector/track changes and decode times are insignificant.Boray wrote:Do any of you programming gurus have any ideas on how to improve the timing of the player?
- You could combine interrupt timing with a read ahead buffer. Then, a normal IRQ reads out the buffer at a programmed rate to play a sample. The interrupt could be blocked by the inner loop of the transfer routines, which is framed by SEI/CLI - reading a byte has to take place in a cycle-exact manner.
- Similarily, you could use the IRQ mainly to indicate the next sample should be played: IRQ just sets a memory location to 1 - main program reads a byte, waits for the memory location to become 1, resets it to 0 and writes the sample to the VIC registers. Would work without a read-ahead buffer, but can still suffer from a little jitter.
- A NMI instead of a IRQ in both cases above could ensure stricter timing, but it also could possibly fire just inside the byte transfer - and then you get errorneous results.
You really want to write own transfer routines which can be interrupted at any point. That's what recent demos use to stream data (not just only music) from disc. But that means of course a lot more work.
Cool idea nonetheless.
Thanks Mike! How would I set up the IRQ to be trigged at the exact sample rate? I don't know much about IRQ, only that you change the addresses 0314-0315 to point at your own routine. That's basically what I know about interrupts.
Thanks orion! Even if the music wouldn't be in your taste, I'm sure you will like track nr one!
Thanks orion! Even if the music wouldn't be in your taste, I'm sure you will like track nr one!
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
- orion70
- VICtalian
- Posts: 4341
- Joined: Thu Feb 02, 2006 4:45 am
- Location: Piacenza, Italy
- Occupation: Biologist
Tried it in VICE, and I must say it's not bad at all - you're such a skilled composer
I wonder how could you digitize it - some sort of strange dedicated hardware? I'm particularly thinking about the first track (invaluable to hear this in a VIC btw ).
Another question: is there a reason why the volume is soooo low?
I wonder how could you digitize it - some sort of strange dedicated hardware? I'm particularly thinking about the first track (invaluable to hear this in a VIC btw ).
Another question: is there a reason why the volume is soooo low?
I used the DAW software Reaper to render it down to 8 bit sound and then a program I made in Visual Basic to convert it to 4 bit sound (holding two samples in every byte). So it's not sampled on a Vic-20. It's playing through the volume register so that's why the volume is low. I think it's quite a bit louder on a real Vic-20 than on VICE though.
Mike: Is it really possible to set the timers for such a tiny interval?
Mike: Is it really possible to set the timers for such a tiny interval?
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
- Mike
- Herr VC
- Posts: 4845
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Yes, that's entirely possible. The SID Vicious Emulation, for example, uses an NMI at a rate of ~6 kHz.Boray wrote:Mike: Is it really possible to set the timers for such a tiny interval?
You'd use Timer 1 of VIA #2, controlling the IRQ. The low- and high byte are located in $9124 and $9125, respectively, and need to be written in that order to copy the period into the latch.
The value you need to write to the Timer 1 latch then is:
value := 1108405/rate - 2 for PAL or
value := 1022727/rate - 2 for NTSC.
The interrupt server should not end with the 'normal' exit to $EABF, because you really won't want to scan the keyboard 6000 times a second. Rather the keyboard can be left disabled while the sample plays, and the interrupt routine should just acknowledge the IRQ at the end and exit. That's most easily done with JMP $EB15.
It is not necessary to save the A, X and Y registers at the beginning of your own interrupt service routine, as this has already been done by the KERNAL before - and the routine at $EB15 equally well restores them.
It's a pity though, that it is not possible to map out the KERNAL ROM so the hardware IRQ vector on the VIC-20 could be changed through a value in RAM (like it is possible on the C64). The forced saving and restoring of the registers needs a lot of cycles, while the Flag byte I mentioned earlier could easily be set without touching any registers (with SEC:ROR Flag, for example) ...
Thank you very much Mike! I will try this out.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
You can't do anything about the saving of registers to the Stack when $FF72 kicks-in, but you don't have to restore them at the end of your custom IRQ handler if you haven't changed them - just pretend you restored them by pulling them off the Stack.Mike wrote:The forced saving and restoring of the registers needs a lot of cycles, while the Flag byte I mentioned earlier could easily be set without touching any registers (with SEC:ROR Flag, for example) ...
$EB15 does this:
Code: Select all
BIT LAB_9124 ; [4] acknowledge IRQ on VIA2
PLA ; [4] pull .Y from Stack to .A
TAY ; [2] restore .Y
PLA ; [4] pull .X from Stack to .A
TAX ; [2] restore .X
PLA ; [4] restore .A
RTI ; [6] return from interrupt handler
Code: Select all
PLA ; [4] pull .A from Stack (saved .Y)
PLA ; [4] pull .A from Stack (saved .X)
PLA ; [4] pull .A from Stack (saved .A)
BIT LAB_9124 ; [4] acknowledge IRQ on VIA2
RTI ; [6] return from interrupt handler
Using a buffer didn't help very much because the sjload code blocks the interrupts quite frequently i suspect. I got it more or less stable at 4kHz but above that, interrupts starts to miss, making it play slower than the frequency I set it to play at and getting the same kind of rhythmic disturbance as without interrupts. Maybe I can find a frequency where it sounds a bit better if I test for a while.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
It worked great in VICE though.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Well, it did help to synchronize better at 4kHz but my goal was to increase the frequency as well. Now I'm not sure if I will go with synchronized 4kHz or just use the first routine with a higher frequency.Boray wrote:Using a buffer didn't help very much....
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
If anyone is interested in interrupts, here's a nice page about it.
It's not Vic-20 specific, but 6502-specific.
http://www.6502.org/tutorials/interrupts.html
It's not Vic-20 specific, but 6502-specific.
http://www.6502.org/tutorials/interrupts.html
Here comes a little teaser:
http://youtu.be/eCWt0I7D9QA
http://youtu.be/eCWt0I7D9QA
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)