diff --git a/SoundEngine/famistudio_asm6.asm b/SoundEngine/famistudio_asm6.asm index 28108c636..798d9d801 100644 --- a/SoundEngine/famistudio_asm6.asm +++ b/SoundEngine/famistudio_asm6.asm @@ -1,6 +1,6 @@ ;====================================================================================================================== -; FAMISTUDIO SOUND ENGINE (4.1.0) -; Copyright (c) 2019-2023 Mathieu Gauthier +; FAMISTUDIO SOUND ENGINE (4.2.0) +; Copyright (c) 2019-2024 Mathieu Gauthier ; ; Copying and distribution of this file, with or without ; modification, are permitted in any medium without royalty provided @@ -145,6 +145,9 @@ FAMISTUDIO_CFG_NTSC_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_STREAMS = 2 +; Multiple sound effects are overlaid from beginning to end, mixed and played back. For reused channels, some sound effects may sound strange. +; FAMISTUDIO_CFG_SFX_MIXED = 1 + ; Blaarg's smooth vibrato technique. Eliminates phase resets ("pops") on square channels. ; FAMISTUDIO_CFG_SMOOTH_VIBRATO = 1 @@ -346,12 +349,17 @@ FAMISTUDIO_USE_ARPEGGIO = 1 .ifndef FAMISTUDIO_CFG_SFX_SUPPORT FAMISTUDIO_CFG_SFX_SUPPORT = 0 FAMISTUDIO_CFG_SFX_STREAMS = 0 + FAMISTUDIO_CFG_SFX_MIXED = 0 .endif .ifndef FAMISTUDIO_CFG_SFX_STREAMS FAMISTUDIO_CFG_SFX_STREAMS = 1 .endif +.ifndef FAMISTUDIO_CFG_SFX_MIXED + FAMISTUDIO_CFG_SFX_MIXED = 0 +.endif + .ifndef FAMISTUDIO_CFG_C_BINDINGS FAMISTUDIO_CFG_C_BINDINGS = 0 .endif @@ -6532,6 +6540,37 @@ famistudio_sfx_play: asl a tay +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS = 4 ; Check if the high priority sound effects is playing + cpx #FAMISTUDIO_SFX_CH3 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 3 + cpx #FAMISTUDIO_SFX_CH2 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 2 + cpx #FAMISTUDIO_SFX_CH1 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH3 + bne @ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH2 + bne @ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH1 + bne @ignore_channel + .endif +.endif + +@write_channel: jsr famistudio_sfx_clear_channel ; Stops the effect if it plays lda famistudio_sfx_addr_lo @@ -6545,6 +6584,7 @@ famistudio_sfx_play: lda (effect_data_ptr),y sta famistudio_sfx_ptr_hi,x ; This write enables the effect +@ignore_channel: rts ;====================================================================================================================== @@ -6567,12 +6607,50 @@ famistudio_sfx_update: bne @update_buf ; Just mix with output buffer @no_repeat: +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + stx tmp + .endif +.endif lda famistudio_sfx_ptr_hi,x ; Check if MSB of the pointer is not zero - bne @sfx_active + bne @clear_other_channel rts ; Return otherwise, no active effect +@clear_other_channel: +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + cpx #FAMISTUDIO_SFX_CH0 + beq @sfx_active + + ldx #FAMISTUDIO_SFX_CH0 + jsr famistudio_sfx_clear_channel + ldx tmp + cpx #FAMISTUDIO_SFX_CH1 + beq @sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + ldx #FAMISTUDIO_SFX_CH1 + jsr famistudio_sfx_clear_channel + ldx tmp + cpx #FAMISTUDIO_SFX_CH2 + beq @sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + ldx #FAMISTUDIO_SFX_CH2 + jsr famistudio_sfx_clear_channel + .endif +.endif + @sfx_active: - sta effect_data_ptr+1 ;load effect pointer into temp +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + ldx tmp ;load effect pointer into temp + lda famistudio_sfx_ptr_hi,x + .endif +.endif + sta effect_data_ptr+1 lda famistudio_sfx_ptr_lo,x sta effect_data_ptr+0 ldy famistudio_sfx_offset,x @@ -6615,13 +6693,9 @@ famistudio_sfx_update: sta famistudio_sfx_ptr_hi,x ; Mark channel as inactive @update_buf: - lda famistudio_output_buf ; Compare effect output buffer with main output buffer - and #$0f ; If volume of pulse 1 of effect is higher than that of the main buffer, overwrite the main buffer value with the new one - sta tmp - lda famistudio_sfx_buffer+0,x + lda famistudio_sfx_buffer+0,x ; Overwrite pulse 1 of main output buffer if it is active and #$0f - cmp tmp - bcc @no_pulse1 + beq @no_pulse1 lda famistudio_sfx_buffer+0,x sta famistudio_output_buf+0 lda famistudio_sfx_buffer+1,x @@ -6630,13 +6704,9 @@ famistudio_sfx_update: sta famistudio_output_buf+2 @no_pulse1: - lda famistudio_output_buf+3 - and #$0f - sta tmp lda famistudio_sfx_buffer+3,x and #$0f - cmp tmp - bcc @no_pulse2 + beq @no_pulse2 lda famistudio_sfx_buffer+3,x sta famistudio_output_buf+3 lda famistudio_sfx_buffer+4,x @@ -6645,7 +6715,7 @@ famistudio_sfx_update: sta famistudio_output_buf+5 @no_pulse2: - lda famistudio_sfx_buffer+6,x ; Overwrite triangle of main output buffer if it is active + lda famistudio_sfx_buffer+6,x beq @no_triangle sta famistudio_output_buf+6 lda famistudio_sfx_buffer+7,x @@ -6654,13 +6724,9 @@ famistudio_sfx_update: sta famistudio_output_buf+8 @no_triangle: - lda famistudio_output_buf+9 - and #$0f - sta tmp lda famistudio_sfx_buffer+9,x and #$0f - cmp tmp - bcc @no_noise + beq @no_noise lda famistudio_sfx_buffer+9,x sta famistudio_output_buf+9 lda famistudio_sfx_buffer+10,x diff --git a/SoundEngine/famistudio_ca65.s b/SoundEngine/famistudio_ca65.s index 088c7450d..d24efd74e 100644 --- a/SoundEngine/famistudio_ca65.s +++ b/SoundEngine/famistudio_ca65.s @@ -1,6 +1,6 @@ ;====================================================================================================================== -; FAMISTUDIO SOUND ENGINE (4.1.0) -; Copyright (c) 2019-2023 Mathieu Gauthier +; FAMISTUDIO SOUND ENGINE (4.2.0) +; Copyright (c) 2019-2024 Mathieu Gauthier ; ; Copying and distribution of this file, with or without ; modification, are permitted in any medium without royalty provided @@ -146,6 +146,9 @@ FAMISTUDIO_CFG_NTSC_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_STREAMS = 2 +; Multiple sound effects are overlaid from beginning to end, mixed and played back. For reused channels, some sound effects may sound strange. +; FAMISTUDIO_CFG_SFX_MIXED = 1 + ; Blaarg's smooth vibrato technique. Eliminates phase resets ("pops") on square channels. ; FAMISTUDIO_CFG_SMOOTH_VIBRATO = 1 @@ -347,12 +350,17 @@ FAMISTUDIO_USE_ARPEGGIO = 1 .ifndef FAMISTUDIO_CFG_SFX_SUPPORT FAMISTUDIO_CFG_SFX_SUPPORT = 0 FAMISTUDIO_CFG_SFX_STREAMS = 0 + FAMISTUDIO_CFG_SFX_MIXED = 0 .endif .ifndef FAMISTUDIO_CFG_SFX_STREAMS FAMISTUDIO_CFG_SFX_STREAMS = 1 .endif +.ifndef FAMISTUDIO_CFG_SFX_MIXED + FAMISTUDIO_CFG_SFX_MIXED = 0 +.endif + .ifndef FAMISTUDIO_CFG_C_BINDINGS FAMISTUDIO_CFG_C_BINDINGS = 0 .endif @@ -6578,6 +6586,37 @@ famistudio_sfx_play: asl a tay +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS = 4 ; Check if the high priority sound effects is playing + cpx #FAMISTUDIO_SFX_CH3 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 3 + cpx #FAMISTUDIO_SFX_CH2 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 2 + cpx #FAMISTUDIO_SFX_CH1 + beq @write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH3 + bne @ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH2 + bne @ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH1 + bne @ignore_channel + .endif +.endif + +@write_channel: jsr famistudio_sfx_clear_channel ; Stops the effect if it plays lda famistudio_sfx_addr_lo @@ -6591,6 +6630,7 @@ famistudio_sfx_play: lda (@effect_data_ptr),y sta famistudio_sfx_ptr_hi,x ; This write enables the effect +@ignore_channel: rts ;====================================================================================================================== @@ -6613,12 +6653,50 @@ famistudio_sfx_update: bne @update_buf ; Just mix with output buffer @no_repeat: +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + stx @tmp + .endif +.endif lda famistudio_sfx_ptr_hi,x ; Check if MSB of the pointer is not zero - bne @sfx_active + bne @clear_other_channel rts ; Return otherwise, no active effect +@clear_other_channel: +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + cpx #FAMISTUDIO_SFX_CH0 + beq @sfx_active + + ldx #FAMISTUDIO_SFX_CH0 + jsr famistudio_sfx_clear_channel + ldx @tmp + cpx #FAMISTUDIO_SFX_CH1 + beq @sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + ldx #FAMISTUDIO_SFX_CH1 + jsr famistudio_sfx_clear_channel + ldx @tmp + cpx #FAMISTUDIO_SFX_CH2 + beq @sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + ldx #FAMISTUDIO_SFX_CH2 + jsr famistudio_sfx_clear_channel + .endif +.endif + @sfx_active: - sta @effect_data_ptr+1 ;load effect pointer into temp +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + ldx @tmp ;load effect pointer into temp + lda famistudio_sfx_ptr_hi,x + .endif +.endif + sta @effect_data_ptr+1 lda famistudio_sfx_ptr_lo,x sta @effect_data_ptr+0 ldy famistudio_sfx_offset,x @@ -6661,13 +6739,9 @@ famistudio_sfx_update: sta famistudio_sfx_ptr_hi,x ; Mark channel as inactive @update_buf: - lda famistudio_output_buf ; Compare effect output buffer with main output buffer - and #$0f ; If volume of pulse 1 of effect is higher than that of the main buffer, overwrite the main buffer value with the new one - sta @tmp - lda famistudio_sfx_buffer+0,x + lda famistudio_sfx_buffer+0,x ; Overwrite pulse 1 of main output buffer if it is active and #$0f - cmp @tmp - bcc @no_pulse1 + beq @no_pulse1 lda famistudio_sfx_buffer+0,x sta famistudio_output_buf+0 lda famistudio_sfx_buffer+1,x @@ -6676,13 +6750,9 @@ famistudio_sfx_update: sta famistudio_output_buf+2 @no_pulse1: - lda famistudio_output_buf+3 - and #$0f - sta @tmp lda famistudio_sfx_buffer+3,x and #$0f - cmp @tmp - bcc @no_pulse2 + beq @no_pulse2 lda famistudio_sfx_buffer+3,x sta famistudio_output_buf+3 lda famistudio_sfx_buffer+4,x @@ -6691,7 +6761,7 @@ famistudio_sfx_update: sta famistudio_output_buf+5 @no_pulse2: - lda famistudio_sfx_buffer+6,x ; Overwrite triangle of main output buffer if it is active + lda famistudio_sfx_buffer+6,x beq @no_triangle sta famistudio_output_buf+6 lda famistudio_sfx_buffer+7,x @@ -6700,13 +6770,9 @@ famistudio_sfx_update: sta famistudio_output_buf+8 @no_triangle: - lda famistudio_output_buf+9 - and #$0f - sta @tmp lda famistudio_sfx_buffer+9,x and #$0f - cmp @tmp - bcc @no_noise + beq @no_noise lda famistudio_sfx_buffer+9,x sta famistudio_output_buf+9 lda famistudio_sfx_buffer+10,x diff --git a/SoundEngine/famistudio_nesasm.asm b/SoundEngine/famistudio_nesasm.asm index b3029cb5b..530dc9791 100644 --- a/SoundEngine/famistudio_nesasm.asm +++ b/SoundEngine/famistudio_nesasm.asm @@ -1,6 +1,6 @@ ;====================================================================================================================== -; FAMISTUDIO SOUND ENGINE (4.1.0) -; Copyright (c) 2019-2023 Mathieu Gauthier +; FAMISTUDIO SOUND ENGINE (4.2.0) +; Copyright (c) 2019-2024 Mathieu Gauthier ; ; Copying and distribution of this file, with or without ; modification, are permitted in any medium without royalty provided @@ -164,6 +164,9 @@ FAMISTUDIO_CFG_NTSC_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_SUPPORT = 1 ; FAMISTUDIO_CFG_SFX_STREAMS = 2 +; Multiple sound effects are overlaid from beginning to end, mixed and played back. For reused channels, some sound effects may sound strange. +; FAMISTUDIO_CFG_SFX_MIXED = 1 + ; Blaarg's smooth vibrato technique. Eliminates phase resets ("pops") on square channels. ; FAMISTUDIO_CFG_SMOOTH_VIBRATO = 1 @@ -362,12 +365,17 @@ FAMISTUDIO_DUAL_SUPPORT = 0 .ifndef FAMISTUDIO_CFG_SFX_SUPPORT FAMISTUDIO_CFG_SFX_SUPPORT = 0 FAMISTUDIO_CFG_SFX_STREAMS = 0 +FAMISTUDIO_CFG_SFX_MIXED = 0 .endif .ifndef FAMISTUDIO_CFG_SFX_STREAMS FAMISTUDIO_CFG_SFX_STREAMS = 1 .endif + .ifndef FAMISTUDIO_CFG_SFX_MIXED +FAMISTUDIO_CFG_SFX_MIXED = 0 + .endif + .ifndef FAMISTUDIO_CFG_SMOOTH_VIBRATO FAMISTUDIO_CFG_SMOOTH_VIBRATO = 0 .endif @@ -6591,6 +6599,37 @@ famistudio_sfx_play: asl a tay + .if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS = 4 ; Check if the high priority sound effects is playing + cpx #FAMISTUDIO_SFX_CH3 + beq .write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 3 + cpx #FAMISTUDIO_SFX_CH2 + beq .write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS = 2 + cpx #FAMISTUDIO_SFX_CH1 + beq .write_channel + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH3 + bne .ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH2 + bne .ignore_channel + .endif + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + lda famistudio_sfx_ptr_hi+FAMISTUDIO_SFX_CH1 + bne .ignore_channel + .endif + .endif + +.write_channel: jsr famistudio_sfx_clear_channel ; Stops the effect if it plays lda famistudio_sfx_addr_lo @@ -6604,6 +6643,7 @@ famistudio_sfx_play: lda [.effect_data_ptr],y sta famistudio_sfx_ptr_hi,x ; This write enables the effect +.ignore_channel: rts ;====================================================================================================================== @@ -6626,12 +6666,50 @@ famistudio_sfx_update: bne .update_buf ; Just mix with output buffer .no_repeat: + .if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + stx tmp + .endif + .endif lda famistudio_sfx_ptr_hi,x ; Check if MSB of the pointer is not zero - bne .sfx_active + bne .clear_other_channel rts ; Return otherwise, no active effect +.clear_other_channel: +.if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + cpx #FAMISTUDIO_SFX_CH0 + beq .sfx_active + + ldx #FAMISTUDIO_SFX_CH0 + jsr famistudio_sfx_clear_channel + ldx tmp + cpx #FAMISTUDIO_SFX_CH1 + beq .sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 2 + ldx #FAMISTUDIO_SFX_CH1 + jsr famistudio_sfx_clear_channel + ldx tmp + cpx #FAMISTUDIO_SFX_CH2 + beq .sfx_active + .endif + + .if FAMISTUDIO_CFG_SFX_STREAMS > 3 + ldx #FAMISTUDIO_SFX_CH2 + jsr famistudio_sfx_clear_channel + .endif +.endif + .sfx_active: - sta <.effect_data_ptr+1 ;load effect pointer into temp + .if FAMISTUDIO_CFG_SFX_MIXED = 0 + .if FAMISTUDIO_CFG_SFX_STREAMS > 1 + ldx tmp ;load effect pointer into temp + lda famistudio_sfx_ptr_hi,x + .endif + .endif + sta <.effect_data_ptr+1 lda famistudio_sfx_ptr_lo,x sta <.effect_data_ptr+0 ldy famistudio_sfx_offset,x @@ -6674,13 +6752,9 @@ famistudio_sfx_update: sta famistudio_sfx_ptr_hi,x ; Mark channel as inactive .update_buf: - lda famistudio_output_buf ; Compare effect output buffer with main output buffer - and #$0f ; If volume of pulse 1 of effect is higher than that of the main buffer, overwrite the main buffer value with the new one - sta <.tmp - lda famistudio_sfx_buffer+0,x + lda famistudio_sfx_buffer+0,x ; Overwrite pulse 1 of main output buffer if it is active and #$0f - cmp <.tmp - bcc .no_pulse1 + beq .no_pulse1 lda famistudio_sfx_buffer+0,x sta famistudio_output_buf+0 lda famistudio_sfx_buffer+1,x @@ -6689,13 +6763,9 @@ famistudio_sfx_update: sta famistudio_output_buf+2 .no_pulse1: - lda famistudio_output_buf+3 - and #$0f - sta <.tmp lda famistudio_sfx_buffer+3,x and #$0f - cmp <.tmp - bcc .no_pulse2 + beq .no_pulse2 lda famistudio_sfx_buffer+3,x sta famistudio_output_buf+3 lda famistudio_sfx_buffer+4,x @@ -6704,7 +6774,7 @@ famistudio_sfx_update: sta famistudio_output_buf+5 .no_pulse2: - lda famistudio_sfx_buffer+6,x ; Overwrite triangle of main output buffer if it is active + lda famistudio_sfx_buffer+6,x beq .no_triangle sta famistudio_output_buf+6 lda famistudio_sfx_buffer+7,x @@ -6713,13 +6783,9 @@ famistudio_sfx_update: sta famistudio_output_buf+8 .no_triangle: - lda famistudio_output_buf+9 - and #$0f - sta <.tmp lda famistudio_sfx_buffer+9,x and #$0f - cmp <.tmp - bcc .no_noise + beq .no_noise lda famistudio_sfx_buffer+9,x sta famistudio_output_buf+9 lda famistudio_sfx_buffer+10,x