25 May '13 - 03:21 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1] 2  All
  Reply  |  Print  
Author Topic: Normalize output sound?!  (Read 16879 times)
Largie
Posts: 110


« on: 16 May '02 - 23:24 »
Reply with quoteQuote

Does anybody know any filter or logic that can make every output at the same level.

I am currently making a player that play mp3 sounds and am using bass.

I have heard that is it is a system where you 40% sound loss on every tune, but the output level is the same regardless of how much the level really are.

Any clue anyone?! Wink
Logged
wombat
Posts: 29


« Reply #1 on: 17 May '02 - 10:36 »
Reply with quoteQuote

There are two solutions for that... neither one is perfect.

First option: Decode the whole output to memory first, check the average sound level _or_ the loudest peak, and normalize accordingly during playback (use a DSP routine for that).

Second option: Dynamically adjust the gain level by using some kind of prebuffering (say, buffer 2 secs ahead) and then calculate the gain. This will mess up royally if your mp3/mod has a quiet piece in it.

For averaging the volume: You can usually assume that the average of all your sample values is _roughly_ 1/3rd of the peak value. So, get the average of whatever buffer you chose, then calculate the difference between your desired volume (divide by three) and your average. This gives you a multiplier which you can use in your DSP procedure.

If you go for peak value, you might get odd results if the original recording is noisy and has spikes. It does usually work well for clean CD-rips though.
Logged
Sl@jaR
Posts: 81


« Reply #2 on: 17 May '02 - 12:02 »
Reply with quoteQuote

The first version is the only one which is a normalization  Grin
The second one would be a compression, but i don't think it's good. Realtime Normalization isn't possible...
--> you cann't normalize streams.
Logged
wombat
Posts: 29


« Reply #3 on: 17 May '02 - 12:37 »
Reply with quoteQuote

It can be done for file streams _and_ live streams, if you prebuffer them enough. It's admittedly a pain in the rearside, but I'd think it would be doable with BASS by combining the raw output functions with stream input and whatnot...

Btw, one program which does dynamic gain is ModPlug Player.
Logged
Sl@jaR
Posts: 81


« Reply #4 on: 17 May '02 - 12:45 »
Reply with quoteQuote

but it's not a exact normalization Sad
Logged
wombat
Posts: 29


« Reply #5 on: 17 May '02 - 12:54 »
Reply with quoteQuote

True... more like dynamic gain control (I think they even call it that in the software)
Logged
Largie
Posts: 110


« Reply #6 on: 17 May '02 - 20:59 »
Reply with quoteQuote

OK.

So if you eg. put in a 40% reduction on the outputlevel and let every peak be "normalized" after that, that would work wouldn't it?!

Do you have an example of a gain controll.. The silent part is no problem for me, because the system is based on a crossfading system and just techno songs is usally played...

I just wanne se some example code of such a solution...

But is there another word for "getting the same output gain" on every song... Is it smart using the "compressor" built in the DirectX system and then get the "same" effect?!

Please help me out here... Discussing if it is normalizing or not is not the issue here. The issue is getting this f*** thing to give the same output on the songs... Smiley
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #7 on: 18 May '02 - 16:35 »
Reply with quoteQuote

Here's a simple dynamic amplification DSP...
#define amptarget 30000 // target level
#define ampquiet 800 // quiet level
#define amprate 0.02f // amp adjustment rate

typedef struct {
     float gain; // amplification level
     int delay; // delay before increasing level
     int count; // count of sequential samples below target level
     int high; // the highest in that period
     int quiet; // count of sequential samples below quiet level
} AUTOAMPSTUFF;

void CALLBACK autoamp(HDSP handle, DWORD channel, void *buffer, DWORD length, AUTOAMPSTUFF *amp)
{
     short *data=(short*)buffer;
     DWORD c;
     for (c=0;c<length/2;c++) {
           int s=(int)(data[c]*amp->gain); // amplify sample
           int sa=abs(s);
           if (abs(data[c])<ampquiet)
                 amp->quiet++; // sample is below quiet level
           else
                 amp->quiet=0;
           if (sa<amptarget) { // amplified level is below target
                 if (sa>amp->high) amp->high=sa;
                 amp->count++;
                 if (amp->count==amp->delay) { // been below target for a while
                       if (amp->quiet>amp->delay)
                             // it's quiet, go back towards normal level
                             amp->gain+=10*amprate*(1-amp->gain);
                       else
                             amp->gain+=amprate*amptarget/amp->high; // increase amp
                       amp->high=amp->count=0; // reset counts
                 }
           } else { // amplified level is above target
                 if (s<-32768) s=-32768;
                 else if (s>32767) s=32767;
                 amp->gain-=2*amprate*sa/amptarget; // decrease amp
                 amp->high=amp->count=0;
           }
           data[c]=(short)s; // replace original sample with amplified version
     }
}

...

AUTOAMPSTUFF amp;

amp.gain=1;
amp.delay=BASS_ChannelSeconds2Bytes(handle,1)/2;
amp.count=amp.high=amp.quiet=0;
BASS_ChannelSetDSP(handle,(DSPPROC*)&autoamp,&amp);
Logged
Largie
Posts: 110


« Reply #8 on: 18 May '02 - 17:04 »
Reply with quoteQuote

Thanx Ian! Smiley

I will try this one... I have also sent a mail to the programmer of AudioStocker asking for some code! Smiley

http://
http://www.winamp.com/plugins/detail.jhtml?componentId=92157)


This one is really good... Do you think your code will be as good as AudioStocker?!
Logged
Largie
Posts: 110


« Reply #9 on: 19 May '02 - 16:33 »
Reply with quoteQuote

It seems to work real nice on every kind of music I tested... Smiley

GREAT IAN!!!

But of coz there are some questions...

#define amptarget 30000 // target level
#define ampquiet 800 // quiet level
#define amprate 0.02f // amp adjustment rate

The amptarget is that the "output" level you decide here (like 30000 is the highest peak where you reduce the output signal?)

And quiet is like the "lowest" level that should not be gained... So if you use this on for example orchestra music it will not "overgain" the quiet parts of it?! Smiley

And then the amprate is the steps between the gains so if it was to low the last time you add the amprate or if it was to high you reduce with the amprate.

Is this the right thinking of how this dynamic DSP output filter work?! Smiley

(I guess I'll have to buy a math and DSP filter book after this, because this is cool!!!!)
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #10 on: 20 May '02 - 13:38 »
Reply with quoteQuote

Quote
The amptarget is that the "output" level you decide here (like 30000 is the highest peak where you reduce the output signal?)

Yep, it's the target level... you don't want to reduce it too much, otherwise you reduce the music's dynamics (there's a smaller range of levels for each sample). Better to reduce the channel volume, if you want a lower output level.
Quote
And quiet is like the "lowest" level that should not be gained... So if you use this on for example orchestra music it will not "overgain" the quiet parts of it?! Smiley

Below the "quiet" level, it actually reduces the amplification instead of increasing it... did that for gaps between tracks (eg. when streaming), so that the next track does not start with ear pain Smiley

It seems to work quite well as it is, but it was hacked together in a few mins, so it can probably be fine-tuned some Smiley
Logged
FormulaV8
Posts: 47


« Reply #11 on: 20 May '02 - 18:20 »
Reply with quoteQuote

Can someone convert Ians code to VB?  Grin
Logged
Largie
Posts: 110


« Reply #12 on: 20 May '02 - 22:24 »
Reply with quoteQuote

Quote

It seems to work quite well as it is, but it was hacked together in a few mins, so it can probably be fine-tuned some Smiley


Smiley I guess it can... The thing that would be real cool to add, is a compression. (Then it is much easier to get the same soundpicture of different kinds of songs)

I guess you know what I compression is. But I tell i anyway.
It is like a 3 part band low/mid/high dynamic volume controller.

So you can actually boost the base and lower the mid on every stream dynamicly. Meaning that if you play techno songs you'll get more power to the bassdrums. And if you switch the music into eg disco tunes you still will get the same punch if any on the same gain level.

It is what AudioStocker calls compression to FM output. Meaning strong base and lower mid and high treble. This should be added to the great dynamic volume controller.

Ian: Which books are the best for learning DSP. Programming filters, creating generators and so on?! Smiley Please help me out here so I can start learning... Smiley
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #13 on: 21 May '02 - 17:22 »
Reply with quoteQuote

I can't really recommend any DSP books, as I don't have any Grin

But a good place to look, if you want to find out the theory behind the various effects, is http://www.harmony-central.com/Effects/effects-explained.html ... they also include references to books if you want to learn more about them.
Logged
paddy
Posts: 142


« Reply #14 on: 23 Jun '02 - 12:14 »
Reply with quoteQuote

Jobnik, How about adding a compressor to bassFX? It would also be nice to provide a bandwidth parameter to the dsp EQ.

Rgds.


Logged
(: JOBnik! :)
Posts: 984


« Reply #15 on: 24 Jun '02 - 01:38 »
Reply with quoteQuote

Hi Grin
Quote

Jobnik, How about adding a compressor to bassFX? It would also be nice to provide a bandwidth parameter to the dsp EQ.

* Sorry no Compressor yet.
* I've updated the EQ, so now it's using the BiQuad algorithm, and there's a Bandwidth parameter added too Smiley

I'll send the updated .DLL to Ian when I'll finish all optimizations.

Have fun!

Cool JOBnik! Cool
Logged
paddy
Posts: 142


« Reply #16 on: 25 Jun '02 - 11:58 »
Reply with quoteQuote

I just got an unhandled exception at bass_fx when using DSP. I'm not sure what caused it - my app was just playing fine then suddenly it crashes!

There could also be a bit of distortion (clicks) when adjusting the EQ at low frequencies eg 80-100.

Guess I wouldnt mind trying out the new EQ code. Smiley

Cheers!
« Last Edit: 25 Jun '02 - 12:00 by paddy » Logged
paddy
Posts: 142


« Reply #17 on: 25 Jun '02 - 12:39 »
Reply with quoteQuote

The bass_fx Error occurred again!

This is the info i got from the C++ Debugger:

01E823A0 C2 10 00             ret         10h
01E823A3 55                   push        ebp
01E823A4 8B EC                mov         ebp,esp
01E823A6 83 7D 0C 00          cmp         dword ptr [ebp+0Ch],0
01E823AA 56                   push        esi
01E823AB 57                   push        edi
01E823AC 8B 7D 08             mov         edi,dword ptr [ebp+8]
01E823AF 8B F1                mov         esi,ecx
01E823B1 0F 84 B6 00 00 00    je          01E8246D
01E823B7 53                   push        ebx
01E823B8 8D 5E 14             lea         ebx,[esi+14h]
01E823BB 0F BF 07             movsx       eax,word ptr [edi]

Error Occurs at the last line - ie
Quote

01E823BB 0F BF 07             movsx       eax,word ptr [edi]


The error message is:

Quote

Unhandled exception in bass_fx.dll:0xc0000005: Access Violation


Any idea as to what might have caused it?

Rgds.
Logged
(: JOBnik! :)
Posts: 984


« Reply #18 on: 25 Jun '02 - 14:54 »
Reply with quoteQuote

Hi Grin

hmmm....
Does the Error occur when you're using Reverb/Echo?
Or with any other effect?
Does it occur in Compiled/Non Compiled modes?

It seemed to be a Memory error...

I'll check it out Smiley

btw, could you please write a msg in BASS_FX section? Grin

Have fun!

Cool JOBnik! Cool
« Last Edit: 25 Jun '02 - 19:27 by JOBnik » Logged
paddy
Posts: 142


« Reply #19 on: 27 Jun '02 - 08:50 »
Reply with quoteQuote

Quote

Does the Error occur when you're using Reverb/Echo?
Or with any other effect?


I only use DSP EQ.

Quote

Does it occur in Compiled/Non Compiled modes?


Compiled.

Quote

It seemed to be a Memory error...


Could be. But I have 128MB Ram and lots of HDD space...

I've been trying out VB DSP callbacks in another separate app and it seems that bugs manifest themselves as memory problems (eg when dealing with Byval (pointers?) variables. Eg. Floating-Point Inexact Result Exceptions...

I'm slowly starting to get the hang of this DSP Call back thing - but I know I still kave a long way to go.

Rgds.
Logged
Pages: [1] 2  All
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines