PCM player using SCC

Pagina 13/33
6 | 7 | 8 | 9 | 10 | 11 | 12 | | 14 | 15 | 16 | 17 | 18

Van dvik

Prophet (2200)

afbeelding van dvik

23-10-2007, 10:21

The scary thing is that these roms can be replayed on a standard MSX1 with 8kB ram and its technology that existed and was commonly used back then Smile Too bad its in french Wink

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 10:44

Not too bad huh? At least not in the emus. There are some more noise on the real cart but it may be the electronics in the SCC. I don't have the equipment to sample the real SCC atm so I can't do any analysis of it.

NYYRIKKI thinks that it could arise when the z80 accesses too frequently to the SCC ram area while the SCC is playing.

IMHO the latest technique (that updates only the "used" samples) already reduced a lot the number of
accesses wrt to the other one that "polls" the channel4.

Have you seen if the two versions have different level of noise ?

If NYYRIKKI's intuition is correct the "polling" technique should be noisier than the latter solution.

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 10:56

The scary thing is that these roms can be replayed on a standard MSX1 with 8kB ram and its technology that existed and was commonly used back then Smile Too bad its in french Wink

Consider also the fact that you can have up 3 PCM samples at the same time
or PCM + 2 channels SCC music + PSG...

Big smile

The sole problem is that in real games for MSX1 you cannot rely on HINTs
so the sole possibility I see is to limit the max duration of each branch of the main
loop to max 32/Fs secs.... is it ?
If yes, it is possible, but limiting.

The poliphase solution could instead be called only ONCE per frame leading to Fs=7680Hz ....

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 11:08

[EDIT]
No bug, just a comment to be changed

Change the comments of this:

SccInit:
        ;RRB000XX
        ld  a,00100000b ; Rotate only CH4 & CH5 common waveform. Waveform will be rotated with CH4 freq.
        ld  (98E0h),a
        [...]

in this

SccInit:
              ;RRB000XX
        ld  a,00100000b ; Init the sample play when frequency is written
        ld  (98E0h),a
        [...]

Van hap

Paragon (2042)

afbeelding van hap

23-10-2007, 12:26

Thanks for creating a program that, next to being a nice replayer, tests/confirms SCC deformation register emulation Smile

Van Manuel

Ascended (19270)

afbeelding van Manuel

23-10-2007, 13:27

It does sound superb!! Smile (Except for the noise that's jittering through the sample... but the rest is quite clear!)

How much free CPU time left with that LEILA.ROM, dvik?

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 14:20

If it is at 22KHz, you should have more than the 50% of the cpu free

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 16:10

Could the "offset" depend on the time rotation of ch4 started wrt the time you read it the first time?
Could this be an implementation detail that differ among emulators and among emulators and the real HW?

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------


        fname "sccplay.rom"
        org 4000h
        dw  4241h,START,0,0,0,0,0,0


Bank1:  equ      05000h
Bank2:  equ      07000h
Bank3:  equ      09000h
Bank4:  equ      0B000h


SampleFrequency: equ 11025

Period: equ      3579545 / 11025

;-------------------------------------
; Entry point
;-------------------------------------
START:
        call powerup
        xor a
        call 005Fh

        di
        
        ld  a,3Fh
        LD  (Bank3),A

       
        call    ReplayerInit
 	call    SccInit			; here Ch4 starts rotating 
.oloop:
        call    ReplayerUpdate	; the closer to the start of the counter

        ld      a,r
        and 127
        ld      b,a			; variable lenght LOOP!!! Just to show off about the use of this replayer ;-)
.iloop:
        ld      a,r
        out     (99h),a
        ld      a,128+7
        out     (99h),a
        djnz    .iloop

        jp      .oloop        
        ret        
        

SccInit:
             ;RRB000XX
        ld  a,00100000b ; reset the play of the waveform if freq is written.
        ld  (98E0h),a
        
        ld  a,15
        ld  (988Ah),a       ; volume ch1

        xor a
        ld  (988Bh),a       ; volume ch2
        ld  (988Ch),a       ; volume ch3
        ld  (988Dh),a       ; volume ch4
        ld  (988Eh),a       ; volume ch5

        ld  a,00011111b     ;   ALL channels active
        ld  (988Fh),a

        ld  hl,9800h+32*3   ; counter in channel 4
        ld  bc,32*256
.counter:
        ld  (hl),c
        inc hl
        inc c
        djnz  .counter

        ld  hl,Period
        ld  (9880h),hl
        ld  (9886h),hl 	; here CH4 restarts its play on emulators
        ld  (9888h),hl  ; here CH4 restarts its play on the real thing

             ;RRB000XX
        ld  a,10000000b ; Rotate only CH4 & CH5 common waveform. Waveform will be rotated with CH4 freq.
        ld  (98E0h),a   ; here Ch4 starts rotating
        ret    
    
    

;-------------------------------------
; Initialize replayer
;-------------------------------------
ReplayerInit:
        ld      hl,9800h
        ld      (WavePos),hl
        ld      hl,6000h
        ld      (SamplePos),hl
        ld      a,1
        ld      (SamplePage),a
        ld      (Bank2),a
        ret
        

;-------------------------------------
; Moves sample pointer to next page
;-------------------------------------
ReplayerNextPage:
        ld      hl,6000h
        ex     af,af'
        ld      a,(SamplePage)
        cp      (SAMPLE_END - SAMPLE_START + 1FFFh)/2000h
        jp      nz,.norewind
        xor     a
.norewind:
        inc     a
        ld      (SamplePage),a
        ld      (Bank2),a
        ex     af,af'
        ret
        

;-------------------------------------
; Updates the SCC wave table. This method needs
; to be called at least once every 32 samples
; (in reality at least every 28 samples or so)
;-------------------------------------
ReplayerUpdate:
        ld      de,(WavePos)
        ld      hl,(SamplePos)

        ld      a,(9800h+32*3+0)    ; no sure any more about +2, it sounds like it could be 0.Does it depend on the Fs you set? how is it on the HW?
        jp      .tst
.loop:        
        ldi
        res     5,e                 ; Sample pos mod 32
        bit     7,h
        call    nz,ReplayerNextPage
.tst:   cp      e
        jp      nz,.loop
        
        ld      (SamplePos),hl
        ld      (WavePos),de
        ret




;-------------------------------------
;   Powerup routine for non-Z180 code.
;   set pages and subslot
;-------------------------------------
powerup:
        call    0x138
        rrca
        rrca
        and     0x03
        ld      c,a
        ld      b,0
        ld      hl,0xfcc1
        add     hl,bc
        or      (hl)
        ld      b,a
        inc     hl
        inc     hl
        inc     hl
        inc     hl
        ld      a,(hl)
        and     0x0c
        or      b

        ld      h,0x80
        call    0x24

        ret

        
;-------------------------------------
; To make rom guesseres happy
;-------------------------------------
dummy:
        xor     a
        ld      (Bank1),a
        ld      (Bank3),a
        ld      (Bank1),a
        ld      (Bank3),a
        ret
        
;-------------------------------------
; Padding for rom player
;-------------------------------------
        DS (6000h - $)


;-------------------------------------
; Sample data
;-------------------------------------
SAMPLE_START:
        incbin "handel.raw",0,(56+64+128)*1024
SAMPLE_END:


;-------------------------------------
; Padding, align rom image to a power of two.
;-------------------------------------

SAMPLE_LENGTH:  equ SAMPLE_END - SAMPLE_START

        IF (SAMPLE_LENGTH <= 6000h)
        DS (6000h - SAMPLE_LENGTH)
        ELSE
        IF (SAMPLE_LENGTH <= 10000h-2000h)
        DS (E000h - SAMPLE_LENGTH)
        ELSE
        IF (SAMPLE_LENGTH <= 1E000h)
        DS (1E000h - SAMPLE_LENGTH)
        ELSE
        IF (SAMPLE_LENGTH <= 3E000h)
        DS (3E000h - SAMPLE_LENGTH)
        ELSE
        IF (SAMPLE_LENGTH <= 7E000h)
        DS (7E000h - SAMPLE_LENGTH)
        ELSE
        DS (FE000h - SAMPLE_LENGTH)
        ENDIF
        ENDIF
        ENDIF
        ENDIF
        ENDIF



FINISH:


;---------------------------------------------------------
; Variables
;---------------------------------------------------------
        org $c000
        
WavePos:        rw  1
SamplePos:      rw  1
SamplePage:     rb  1

Van Guillian

Prophet (3516)

afbeelding van Guillian

23-10-2007, 16:31

Based on Hyroyuki's code and information I made two simple demos of playing PCM sound using the SCC.
Demo 1
Demo 2

It plays a 15.75KHz sample using as timer the VDP status register 2 (horizontal scanning flag). Of course, it also uses the mode setting register/deformation register to rotate the waves.

Van ARTRAG

Enlighted (6923)

afbeelding van ARTRAG

23-10-2007, 16:35

can you translate site & docs ?

babelfish failed Sad

Why it needs the 15KHz hfreq if it uses the rotation of ch4 as timer ?

Very curious about it, how does it work ?

Does it use ch4 as timer ?
Question

I've the feeling like we invented the cold water Tongue

Pagina 13/33
6 | 7 | 8 | 9 | 10 | 11 | 12 | | 14 | 15 | 16 | 17 | 18