Saturday, January 12, 2013

Paula sound, so where does that 14bit audio come from?

So where does that 14bit stereo sound come from? You might have wondered, well after reading the hardware reference manual, it explains that 4 audio channels can be combined in to two.

In this mode, one of channels controls the volume (a value from 0 to 63) 6bits, and wave from is (127 to -127) 8bit, so if you add that up 6+8 = 14bit.

This not a hack, that's a urban myth, it was designed to be like this. Its properly more complicated to calculate wave form and volume, and also it does not take advantage of all bits in the audio channels, plus it does need a bit more CPU if I'm not mistaken.

Its a shame they did not provided a proper 16bit D/A converter instead, anyway the sound was not that bad compared some early sound blaster sound cards that sounded a bit sour.


I think this graph illustrates the dilemma, where audio quality is better at lower amplitude, then on higher, as as the amplitude increases, because the 8bits are more compressed at lower volume. So you do not get popper 14bit, where the bits are evenly spread out, what you get if you made a sinus or a sawtooth, you see that top and bottom of sinus are more pixelated then in the center of sinus.

I have also played whit Paula whit some help, few small errors, and this codes players a beep. I have not really found out about interrupts, the DMA is supposed to trigger a interrupt when sound was played, so you fill the buffer whit new sound, but I can't find any interrupt vector to configure in the hardware reference manual.


EXECBASE EQU 4

OldOpenLibrary EQU -$0198
WriteChars EQU -$03AE
CloseLibrary EQU -$019E
Delay EQU -198

ALLOCMEM    EQU -198
FREEMEM        EQU    -210

CUSTOM        EQU    $DFF000
AUD0LCH        EQU    $0A0
AUD0LCL        EQU $0A2
AUD0LEN        EQU $0A4
AUD0VOL        EQU    $0A8
AUD0PER        EQU    $0A6
DMACON        EQU $096

    SECTION MAIN,CODE

MAIN:
        LEA DOS(pc),A1
        MOVE.l #0,D0
        MOVE.l EXECBASE,a6
        jsr     OldOpenLibrary(a6)
        move.l  d0,DOSBASE
        beq.s   .Out

        move.l  #msg_start,d1
        moveq  #9,d2
        JSR .Write

        ; Alloc Sound wave
        MOVE.l #100,D0    ; size
        MOVE.l #2,D1        ; chip mem
        MOVE.l EXECBASE,a6
        JSR ALLOCMEM(a6)
        MOVE.l d0,SINDATA
        BEQ.s    .NOMEM
   
        ; Setup sound wave
        MOVE.L SINDATA,a1
        MOVE.b 0,0(a1)
        MOVE.b 90,1(a1)
        MOVE.b 127,2(a1)
        MOVE.b 90,3(a1)
        MOVE.b 0,4(a1)
        MOVE.b -90,5(a1)
        MOVE.b -127,6(a1)
        MOVE.b -90,7(a1)

        ; Play sound
        LEA.l CUSTOM,a0
        MOVE.l SINDATA,AUD0LCH(a0)  ; sound wave to play
        MOVE.W #4,AUD0LEN(a0) ; length of sound wave
        MOVE.W #64,AUD0VOL(a0) ; sound volume
        MOVE.W #447,AUD0PER(a0) ; set audio period
        ; enable (bit 15) dma (bit 9), audio channel 0 (bit 0)
        MOVE.W #$8201,DMACON(a0)

        ; Wait for sound to be played
        move.l DOSBASE,A6
        move.l #40,D1
        JSR Delay(A6)

        LEA.l CUSTOM,a0
        MOVE.W #1,AUD0VOL(a0) ; sound volume
        MOVE.W #0,AUD0LEN(a0) ; length of sound wave
        MOVE.W #220,AUD0PER(a0) ; set audio period
        MOVE.W #$0001,DMACON(a0)

        move.l  #msg_step,d1
        moveq  #7,d2
        JSR .Write

        ; Wait for sound to be played
        move.l DOSBASE,A6
        move.l #20,D1
        JSR Delay(A6)

        ; Free sound wave
        MOVE.l #100,D0
        MOVE.l SINDATA,a1
        MOVE.l EXECBASE,a6
        JSR FREEMEM(a6)

        move.l  #msg_ok,d1
        moveq  #7,d2
        JSR .Write
        JMP .Out      
.NOMEM:
        move.l  #msg_nomem,d1
        moveq  #13,d2
        JSR .Write
        JMP .Out      
.Write:
        move.l DOSBASE,A6
        jsr     WriteChars(a6)
        RTS
.Out:
        move.l  DOSBASE,a1
        move.l  EXECBASE,a6
        jsr     CloseLibrary(a6)
        RTS
DOS:
        dc.b    "dos.library",0
DOSBASE:
        dc.l 0
SINDATA:
        DC.L    0
msg_start:
        dc.b   "START!!!",$A,0
msg_step
        dc.b    "STEP!!",$A,0
msg_ok:
        dc.b    "OK!!!!",$A,0
msg_nomem:
        dc.b    "AllocMem failed, no memory!",$A,0

No comments:

Post a Comment