Help with sample mixing routine please

All about modules/digital tunes in a variety of tracker & sampled formats

Moderators: Mug UK, lotek_style, Moderator Team

uko
Atari maniac
Atari maniac
Posts: 85
Joined: Sun Aug 25, 2019 6:45 pm
Location: France

Re: Help with sample mixing routine please

Post by uko »

unseenmenace wrote: Sat Oct 30, 2021 10:51 pm That's really cool, I'll be interested to hear how big the hit in sound quality and volume is. Not sure if I can make use of movep for buffering in my routine since it needs to be pretty adaptable for different output devices but I'll give it some thought :)
Concerning volume, a "classical" 2 voices mixing routine generally uses samples converted to 7 bits (so as the result has 8 bits).
With the add.l approach (or add.w as mentionned by dbug), you must convert to 6 bits (and unsigned) so as the addition works correctly. Therefore the amplitude of the signal will be divided by 2, so a loss of 6dB.

In the repository containing my replay code, there are also already compiled examples (require STe and probably 1 or 2 MBytes of RAM, I can't remember), using the different techniques I have implemented (and also different MOD files for some), so you will be able to compare the sound quality difference. They are here: https://github.com/Uko-TAL/STE_FullScre ... master/Bin
And the two following test programs use the same MOD file and allow to compare the two mixing techniques:
- MPL.TOS: mix using the move.l, add.l and movep.l technique
- MPFSOV.TOS: mix using move.b, add.b, and move.b
(When launched, wait few seconds until a text is displayed, then press the space bar)

And it is the move.l, add.l and movep.l option that I have also used in my latest demo (see my signature below).
David aka Uko, from T.AL
Take a look at our last STe demo ! The Star Wars Demo and to its "making of"
https://github.com/Uko-TAL
User avatar
unseenmenace
Atari God
Atari God
Posts: 1998
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Re: Help with sample mixing routine please

Post by unseenmenace »

Dbug wrote: Sun Oct 31, 2021 6:03 am you could just do a pass with simple move.w (an)+ (or even possibly movem.w to batch write registers) for the first channel, and then only use the optimized "odd access" code for the second channel.
Makes sense, I'll just have slightly different macros for DMA Left and DMA Right, and do the right channel first as words, then fill the gaps with the left channel afterwards. Cheers :)

uko wrote: Sun Oct 31, 2021 8:48 pm In the repository containing my replay code, there are also already compiled examples (require STe and probably 1 or 2 MBytes of RAM, I can't remember), using the different techniques I have implemented (and also different MOD files for some), so you will be able to compare the sound quality difference. They are here: https://github.com/Uko-TAL/STE_FullScre ... master/Bin
And the two following test programs use the same MOD file and allow to compare the two mixing techniques:
- MPL.TOS: mix using the move.l, add.l and movep.l technique
- MPFSOV.TOS: mix using move.b, add.b, and move.b
(When launched, wait few seconds until a text is displayed, then press the space bar)

And it is the move.l, add.l and movep.l option that I have also used in my latest demo (see my signature below).
Thanks, I'll have a look at that :)


For anyone that's interested, I'm currrently working on implementing volume adjustment. I'm only having 16 volume levels for now at least and I'm writing a bit of code that produces 256 separate tables, one for each combination of volumes for the 2 channels being mixed. Each table is 256 x 256 bytes and contains every combination of sample bytes adjusted for that specific combination of volumes. That way I just have to determine which table should be used before each buffering session, therefore having little if any impact on buffering speed. Hope that makes sense?
UNSEEN MENACE
2 original ST's, several STFM's, 2 STE's, a TT and a 14MB Falcon,
a Lynx 2 and Jaguar with JagCD
User avatar
unseenmenace
Atari God
Atari God
Posts: 1998
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Re: Help with sample mixing routine please

Post by unseenmenace »

unseenmenace wrote: Mon Nov 08, 2021 1:15 pm For anyone that's interested, I'm currrently working on implementing volume adjustment. I'm only having 16 volume levels for now at least and I'm writing a bit of code that produces 256 separate tables, one for each combination of volumes for the 2 channels being mixed. Each table is 256 x 256 bytes and contains every combination of sample bytes adjusted for that specific combination of volumes. That way I just have to determine which table should be used before each buffering session, therefore having little if any impact on buffering speed. Hope that makes sense?
So I've just realised this would use WAY more memory than I have available so I'm going to have a slight re-think :D
UNSEEN MENACE
2 original ST's, several STFM's, 2 STE's, a TT and a 14MB Falcon,
a Lynx 2 and Jaguar with JagCD
User avatar
unseenmenace
Atari God
Atari God
Posts: 1998
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Re: Help with sample mixing routine please

Post by unseenmenace »

So in the end I needed a couple more registers so I had to have less of them used globally by the YM playback code and just stack a couple of them for each Timer A interrupt. This meant I could have addresses of 2 volume adjustment tables handy in a3 and a4, which were generated from a set of 16 fractional multipliers at the start of the program:

Code: Select all

bufdmav	MACRO
*** a0 = mixing table address
*** a1 = sample 1 address
*** a2 = sample 2 address
*** a3 = sample 1 vol table address
*** a4 = sample 2 vol table address
*** a5 = destination buffer address
*** d1 = sample 1 increment fraction
*** d2 = sample 2 inc fraction (upper) & sample 1 inc integer (lower)
*** d3 = sample 2 increment integer
*** d4 = sample 1 offset fraction
*** d5 = sample 2 offset fraction (upper) & sample 1 offset integer (lower)
*** d6 = sample 2 offset integer (lower)
	move.b	(a1,d5),d0		get ch1 sample byte
	ext.w	d0
	move.b	(a3,d0),d0		get volume adjusted byte
	ext.w	d0
	move.b	(a2,d6),d7		get ch2 sample byte
	ext.w	d7
	move.b	(a4,d7),d7		get volume adjusted byte
	ext.w	d7
	add.w	d7,d0			add sample words
	move.b	0(a0,d0),(a5)		get result and write to buffer
	addq.l	#2,a5			skip over other DMA channel
	add.w	d1,d4			add sam1 inc fraction to sam1 offset fraction
	addx.l	d2,d5			add sam1 inc int to sam1 offset int (lower) &
*					add sam2 inc frac to sam2 offset frac (upper)
	addx.w	d3,d6			add sam2 inc int to sam2 offset int
	ENDM
I did it in a fairly crappy brute force way to start with, just to make sure it works as intended and now I'm trying to optimise it a bit :) Worst case scenario however it's still fast enough to buffer 6 channels with full resolution and volume control at 12.5KHz, which with full sample resolution sounds pretty good to me. Hopefully I can also get it fast enough to do 4 channels at 25KHz.
UNSEEN MENACE
2 original ST's, several STFM's, 2 STE's, a TT and a 14MB Falcon,
a Lynx 2 and Jaguar with JagCD
Post Reply

Return to “The Digital Department”