English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 14 March 2023, 04:33   #1
remz
Registered User
 
Join Date: May 2022
Location: Canada
Posts: 138
Streaming audio from fast ram

Hi Amiga coders,

Recently I've had an idea of storing sound effect samples in fast ram, then "streaming them" into chip ram on demand when the game wants to play a sound.

Since in my game, I am limiting sfx to a single audio channel, there can ever only be one sfx being played at a time. And depending on the period (i.e.: sample rate), the number of bytes per frame is manageable:

For example, taking the worst-case scenario, the highest possible sample rate quality (period 124), 28867hz, this translates to 28867/50 = 578 bytes per frame of sound data. Using movem copying 56 bytes at a time, I got the streaming function down to 6.2 scanlines per frame, yielding approximately 4.7 cy per bytes for the copy (on plain 68000 running of chip ram during non-display portion of the raster).

I was wondering if this was a common technique back-in-the-days?
remz is offline  
Old 14 March 2023, 10:32   #2
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by remz View Post
For example, taking the worst-case scenario, the highest possible sample rate quality (period 124), 28867hz, this translates to 28867/50 = 578 bytes per frame of sound data. Using movem copying 56 bytes at a time, I got the streaming function down to 6.2 scanlines per frame, yielding approximately 4.7 cy per bytes for the copy (on plain 68000 running of chip ram during non-display portion of the raster).

I was wondering if this was a common technique back-in-the-days?
Yes, this is the common way, but the calculations must be done very precisely in order not to run into problems.

The primary issue is the size of the buffer in chip-ram because it defines how often you have to correct in relation to the (possible) double-buffer (which is mandatory if you use a 'minimal buffer').
The second no less important issue is to use correct values .
Since I see that you used 50 as the video frequency I assume you are using a PAL system: then 50 is not perfectly exact, the same for 28867.

Forget those values entirely.
The key point is the base frequency of the internal bus, which in PAL is CCK=3546895 Hz.
Define a period for your audio and find how many cycles are in a frame.

Let's take the 'minimal case' and define the double buffer size in chip-ram, for example using the worst case, where the buffer is filled completely during a frame.
Practical example: period p=124 and a standard non-interlace PAL long frame (CCK_per_line*lines=227*313=71051 tot_CCK per frame).

buffer = (ceil(f/v)+1)&0xFFFE
(where: f = audio frequency, v = video frequency, the remainder of the formula to align to the DMA fetch which is 1 word minimum)

However, you have to bring everything to the granularity of the base frequency, so:
f = CCK/p, v = CCK/tot_CCK
f/v = (CCK/p)/(CCK/tot_CCK) = tot_CCK/p

buffer = (ceil(71051/124)+1)&0xFFFE = 574 bytes

Not much different from your value.. but it helps you understand why after a while you would have problems.
In each frame you 'accumulate' advantage in the play of the samples, because audio and video are desynchronized (or better, the audio fetch is in advantage).
And now you can easily calculate 'the error'.

err = buffer-(tot_CCK/p) = 1,008064516 byte/frame.
From this you can find out every how many seconds you have to correct your play:
t_owf = (buffer/err)/v = ~11.41 sec.

Of course if your sound effect lasts less than 11 sec you don't have to do anything.
And if you use a different (much bigger, single) buffer you can differ the problem later in time.

Most audio player use a single large buffer that fills each frame with buffer bytes and allows the hardware to directly restart from the start (so it never changes AUDxLC).
This allows the problem to be deferred much later in time (even by many minutes).
But the problem exists and should be theoretically taken into consideration...

However you can often even ignore it altogether and live peacefully.
And then in the worst case you would have a little audio 'click' (under the aforementioned extreme conditions).


Last edited by ross; 14 March 2023 at 11:07. Reason: additional informations
ross is offline  
Old 14 March 2023, 11:57   #3
remz
Registered User
 
Join Date: May 2022
Location: Canada
Posts: 138
Thank you very much for the detailed calculations, ross.
Indeed the approach I took was allocating a 'large buffer' of 65536 bytes, which I went with the assumption that any sound effect must fit in that buffer.
Then during vblank interrupt, I stream in a fixed amount of bytes into the buffer. To make calculation simpler, I used 512 bytes per frame:
using your calculation with Protrack frequencies:
note G-3 = 24803Hz (24803.462Hz, period 143)
= 498 bytes per frame

This means my streaming copy is always ahead of Paula's DMA, and I don't have to worry about DMA starvation (and no need for double buffer either, as you mentioned).
The difference between 512 and 498 allows for small variation of period, which makes sound effects feel slightly less repetitive: I am using period = 140 + (rand() & 7); (period is randomized from 140 up to 147).

Thanks again!
remz is offline  
Old 14 March 2023, 14:18   #4
A10001986
Registered User
 
A10001986's Avatar
 
Join Date: Jun 2017
Location: 1986
Posts: 79
Why not use 2 smaller buffers, and use the level 4 interrupt? Spares you all the calculations.
A10001986 is offline  
Old 14 March 2023, 20:09   #5
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by A10001986 View Post
Why not use 2 smaller buffers, and use the level 4 interrupt? Spares you all the calculations.
Yes, this is absolutely a possibility and is the usual usage for IRQ4s.

But it depends if you can/want to use it.
It is possible that you have been interrupting a lower IRQ for too long, or you have been interrupted for too long by a higher one.
It really depends on how you structure your code (especially if you disable the system).

The OP was talking about syncing to frame so I answered in topic
ross is offline  
Old 15 March 2023, 16:23   #6
A10001986
Registered User
 
A10001986's Avatar
 
Join Date: Jun 2017
Location: 1986
Posts: 79
You don't have to do everything inside level 4, you can switch down to a lower level, or trigger another level from within level 4.
A10001986 is offline  
Old 15 March 2023, 18:19   #7
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by A10001986 View Post
You don't have to do everything inside level 4, you can switch down to a lower level, or trigger another level from within level 4.
Yes, of course.
It's all a balance of how much you're willing to give up in programming speed and convenience.
There are so many ways to do the same thing, to each his own
ross is offline  
Old 15 March 2023, 18:41   #8
alexh
Thalion Webshrine
 
alexh's Avatar
 
Join Date: Jan 2004
Location: Oxford
Posts: 14,337
Quote:
Originally Posted by remz View Post
I was wondering if this was a common technique back-in-the-days?
Would this really have been a technique "back in the days"?

Surely most Amiga users had only ChipRAM or ChipRAM + SlowRAM.
alexh is offline  
Old 15 March 2023, 19:47   #9
remz
Registered User
 
Join Date: May 2022
Location: Canada
Posts: 138
Quote:
Originally Posted by alexh View Post
Would this really have been a technique "back in the days"?

Surely most Amiga users had only ChipRAM or ChipRAM + SlowRAM.
Slowram is the main motivation for me in my case:
in order to have high quality sound effects on a 512KB+512KB machine, the solution I came up with is streaming audio from "non-chip ram".
The music and graphics and sprites and raster must be chip, no way around that.
But sound effects, that is manageable.

Of course this is highly dependent on the game specific, case-by-case.
remz is offline  
Old 15 March 2023, 22:06   #10
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
Playing back sound from Slow RAM was one of the main motivations for me to create my audio mixer, though it does go further than only playing from Fast/Slow RAM.

If you're interested in the underlying code (might save you some time), you can find the source for it at https://powerprograms.nl/amiga/audio-mixing.html
roondar is offline  
Old 16 March 2023, 20:41   #11
remz
Registered User
 
Join Date: May 2022
Location: Canada
Posts: 138
Quote:
Originally Posted by roondar View Post
Playing back sound from Slow RAM was one of the main motivations for me to create my audio mixer, though it does go further than only playing from Fast/Slow RAM.

If you're interested in the underlying code (might save you some time), you can find the source for it at https://powerprograms.nl/amiga/audio-mixing.html
Awesome and excellent article, roondar.
I recall a hundred years ago, I did a software mixing routine on DOS for soundblaster, and the way I did to add 8-bit channels together was a hybrid between your normal and your high-quality mixer:
I added up the samples, for example +70 (8bit) and +110 (8bit), total +180 (9 bit),
and then I used a lookup table of 512 elements to "remap" the value back into 8-bit: this table was logarithmic, which helped it sound louder since it would mainly compress just 'high peaks'. Also it distorts much less than a flat clipping.
remz is offline  
Old 16 March 2023, 22:00   #12
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,409
Quote:
Originally Posted by remz View Post
Awesome and excellent article, roondar.
I recall a hundred years ago, I did a software mixing routine on DOS for soundblaster, and the way I did to add 8-bit channels together was a hybrid between your normal and your high-quality mixer:
I added up the samples, for example +70 (8bit) and +110 (8bit), total +180 (9 bit),
and then I used a lookup table of 512 elements to "remap" the value back into 8-bit: this table was logarithmic, which helped it sound louder since it would mainly compress just 'high peaks'. Also it distorts much less than a flat clipping.
That is a very interesting approach. Probably quite a bit faster than what I use, thanks for the idea
roondar is offline  
Old 16 March 2023, 22:44   #13
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by roondar View Post
That is a very interesting approach. Probably quite a bit faster than what I use, thanks for the idea
This was used in the past in Amiga also (in different variants) (like even for 8+8+8+8 bit -> 1024 bytes LUT).
If I'm not mistaken it was mentioned in a thread a couple of years ago.
ross is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
sidecar ram, plus fast ram, chip ram behavior kaluce support.Hardware 6 21 May 2019 17:38
Os4.1 Fe1 YT.rexx really fast streaming tips White support.Apps 13 29 December 2017 10:19
A600 multi-upgrade (Chip RAM + Fast RAM + ROM + IDE2CF) Astrofra Hardware pics 15 18 February 2014 21:27
Use of 4MB PCMCIA Fast Flash Memory as Fast RAM in A1200 nkarytia support.Hardware 10 16 September 2011 13:37
32-bit FAST RAM vs. ZII FAST RAM polbit support.Hardware 16 28 January 2007 20:16

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 10:04.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.41505 seconds with 15 queries