Author Topic: BASS_SAMPLE_FX  (Read 6450 times)

Paddy (Guest)

  • Guest
BASS_SAMPLE_FX
« on: 28 Aug '01 - 15:33 »
Just realized that if I use the DX8 EQ, I lose the ability to modify the pitch of a stream by changing its sample rate...
:o

I need to have both EQ and pitch for the application I'm developing.

Is there a way around this? Maybe a patch on BASS 1.1 could correct this?

Please help.... :-/


gregm

  • Posts: 49
Re: BASS_SAMPLE_FX  
« Reply #1 on: 28 Aug '01 - 19:54 »
Ugh, Yeah I realized this too (actually I noticed a while ago, thought it was a problem with my program, and I just haven't had time to look at it in a week or so)..

This is a bit of a problem .. Is there a better way to modify the pitch a`la DX8 or is it a problem with DX8 that the freq can't be changed?


Ian @ un4seen

  • Administrator
  • Posts: 20210
Re: BASS_SAMPLE_FX  
« Reply #2 on: 29 Aug '01 - 01:32 »
Yep, it is a limitation of DX8: you can't have both FX and sample rate control on a single channel.

Microsoft most likely made it like this because the sample rate affects the effect calculations - buffer sizes etc...

But it would be possible to simulate it via the trusty old dsp & custom stream method ;D

Paddy (Guest)

  • Guest
Re: BASS_SAMPLE_FX  
« Reply #3 on: 29 Aug '01 - 07:43 »
Do you also know that with DX8 enabled, you can no longer set a position to jump to if your MP3 file exceeds a certain size (or length) ?  AAAARRRRRGGHHHH! :o

Please Ian, implement EQ internally and release it in 1.2. DX8 will bring previously non-existent bugs into BASS.DLL. :'(

We all know how reliable Micro$oft products are! ::)

Rgds,

Paddy.

Ian @ un4seen

  • Administrator
  • Posts: 20210
Re: BASS_SAMPLE_FX  
« Reply #4 on: 29 Aug '01 - 13:09 »
Quote

Do you also know that with DX8 enabled, you can no longer set a position to jump to if your MP3 file exceeds a certain size (or length) ?  AAAARRRRRGGHHHH! :o

hmmm.... I've never heard of that before. It's not really possible for DX8/FX to have any effect on seeking, as far as DX is concerned it's just another stream.

How big is the MP3 file? Could you post an example source-code here that recreates the problem please?

steel

  • Posts: 8
Re: BASS_SAMPLE_FX  
« Reply #5 on: 29 Aug '01 - 17:53 »
I create a stream with:
Code: [Select]
   
StreamHandle = BASS_StreamCreateFile(BASSFALSE, MP3_filename, 0, 0, BASS_MP3_SETPOS & BASS_SAMPLE_FX)


I then seek using:
Code: [Select]

retval = BASS_ChannelSetPosition(StreamHandle, newPosition)


This works fine for MP3 files less than approx 2MB. Then suddenly if I stream a big file, say, 8MB+...... nothing!

Could be caused by bitrate because some small MP3 files (less than 1MB) could not be seeked too!

Everything works fine when I comment out the BASS_SAMPLE_FX flag as below:

Code: [Select]

   StreamHandle = BASS_StreamCreateFile(BASSFALSE,MP3_filename, 0, 0, BASS_MP3_SETPOS)    '     //comment... & BASS_SAMPLE_FX)


Try it with a 10MB Mp3.


« Last Edit: 29 Aug '01 - 18:00 by steel »

Ian @ un4seen

  • Administrator
  • Posts: 20210
Re: BASS_SAMPLE_FX  
« Reply #6 on: 29 Aug '01 - 19:08 »
Quote

I create a stream with:
Code: [Select]
   
StreamHandle = BASS_StreamCreateFile(BASSFALSE, MP3_filename, 0, 0, BASS_MP3_SETPOS & BASS_SAMPLE_FX)

Should that be "Or" instead of "&" ?

Quote

I then seek using:
Code: [Select]

retval = BASS_ChannelSetPosition(StreamHandle, newPosition)


This works fine for MP3 files less than approx 2MB. Then suddenly if I stream a big file, say, 8MB+...... nothing!

Could be caused by bitrate because some small MP3 files (less than 1MB) could not be seeked too!

What does BASS_ChannelSetPosition return? Have you checked that you are not seeking past the end? Use BASS_StreamGetLength to check the length.

Quote

Try it with a 10MB Mp3.

It worked :)

steel

  • Posts: 8
LOL!
« Reply #7 on: 30 Aug '01 - 07:13 »
;D

Thanks Ian. I've sorted it out (it was the &).

What are the chances of having both Pitch and EQ working together in a future version of bass?  :D ... and how soon would that be? Should I implement a DSP (ugh!) for pitch or maybe a version 1.11 can be launched to cater for this?

What exactly are the overheads or tradeoffs involved?  :-/

manu

  • Posts: 51
Re: BASS_SAMPLE_FX  
« Reply #8 on: 7 Sep '01 - 01:15 »
Hi All,

I need EQ and Pitch for my application too.  
Why don't you implement a EQ function into bass directly. A
3 band Equalizer is good enough...
But the best would be to have both DX8 Sample FX AND FREQUENCY changing ability!
...
hmmm why don't you program a VST or DX Plugin Interface for bass? There are so many quallity Freeware plugins ( EQ too) ... Bass would be a real killer api if it could support these plugins.  

greetz
manu

manu

  • Posts: 51
Re: BASS_SAMPLE_FX  
« Reply #9 on: 14 Sep '01 - 02:15 »
@ steel

Hi, I hacked some code into a class and finally it's a 3 Band Equalizer. You can use it in a DSPCallback function.
Since It's in a Class it's really easy to inplement it. You have use for it?

manu

  • Posts: 51
Re: BASS_SAMPLE_FX  
« Reply #10 on: 14 Sep '01 - 02:16 »
oops ,I forgot to mention that pitch changing is possible ;)

FormulaV8

  • Posts: 47
Re: BASS_SAMPLE_FX  
« Reply #11 on: 14 Sep '01 - 02:41 »
It the class for VB?

steel

  • Posts: 8
Re: BASS_SAMPLE_FX  
« Reply #12 on: 18 Sep '01 - 10:27 »
Manu,

Sure! How do I get it? Can you post it to this thread?

Rgds.

manu

  • Posts: 51
Re: BASS_SAMPLE_FX  
« Reply #13 on: 19 Sep '01 - 10:06 »
Hi,
sorry FormulaV8 it's c++ code .
Ok here we go....

For a description of the bandpass code go to
http://users.iafrica.com/k/ku/kurient/dsp/effects.html

listing of Equalizer.h

Code: [Select]


class Bandpass
{
 private:
 float PI;
 int freq;        //  center freq in Hz
 int freq_s;     //  Sampling Freq.
 float res;       //  resonance [0 - 1]  (minimum - maximum)
 float sf;        //  scaling factor
 float xOld[3];
 float yOld[3];
 float a0,a1,a2,b1,b2;        //  Filter coefficients
 void  Add2Old( float input, float* dest );
 short Clip(float input);
 public:
 Bandpass(int samplerate);
 Bandpass();
 void Reset();
 void Run(void* buf ,unsigned int length);
 void Set(int freq,float g, float q,int samplerate);
 };

class Equalizer
{
private:
Bandpass Band1;  // Low Bandpass
Bandpass Band2;  // Mid Bandpass
Bandpass Band3;  // Hi Bandpass

public:
 void SetGain(float Again_low, float Again_mid, float Again_high);
 void Run(void* buf ,unsigned int length);                              
 void Reset();
 void Update();
 int samplerate;
 float gain_low,gain_mid,gain_high;
 int freq_low,freq_mid,freq_high;
 float q_low,q_mid,q_high;
 Equalizer();
};



listing of Equalizer.cpp

Code: [Select]

#include <math.h>
#include "Equalizer.h"

Bandpass::Bandpass()
{
sf = 1 / 32768.0;
PI = 3.141592654;
Reset();
}
void Bandpass::Add2Old(float input, float* dest)
{

for (int i=2;i > 0;i--)
 {
  dest[i] = dest[i-1];
 }
  dest[0] = input;
}
Bandpass::Bandpass(int samplerate)
{
sf = 1 / 32768.0 ;
PI = 3.141592654;
Reset();
Set(22050.0,0.0,0.0,samplerate);
}
void Bandpass::Set(int freq,float g, float q,int samplerate)
{

freq_s =  samplerate;

float a,b,c,e;

float Wn,Wp;

float gain=g/6.6;

if (freq > freq_s/2) freq = freq_s/2 ;  

Wn=1/(2*PI*freq);                      

Wp=(Wn/tan(Wn/(2*freq_s)));      

a=(Wn*Wn*Wp*Wp);

b=(3+gain)*Wn*Wp*q;

c=(3-gain)*Wn*Wp*q;

e=1.0;

b2 = (e-c+a)/(a+c+e);

a2 = (e-b+a)/(a+c+e);

b1 = 2*(e-a)/(a+c+e);

a1 = 2*(e-a)/(a+c+e);

a0 = (a+b+e)/(a+c+e);

}

void Bandpass::Run(void* buf ,unsigned int length)
{
 short *d = (short*) buf;
 float out, input ;

     for (;length;length-=4,d+=2)
       {
        input = (float)d[0];
        Add2Old( sf * input - b1*xOld[0] - b2*xOld[1] , xOld );
        out  = a0*xOld[0] + a1*xOld[1] + a2*xOld[2];
        d[0] = Clip( out /sf );

        input = (float)d[1];
        Add2Old( sf * input - b1*yOld[0] - b2*yOld[1], yOld );
        out  = a0*yOld[0] + a1*yOld[1] + a2*yOld[2];
        d[1] = Clip( out /sf );
       }
}
void Bandpass::Reset()
{
for (int i=0;i<3 ;i++)
{
 xOld[i]=0.0;
 yOld[i]=0.0;
}
}

short Bandpass::Clip(float input)
{
if      (input < -32768) input = -32768;
else if (input >  32767) input =  32767;
return (short)input;

}

/*   Equalizer    ------------------------------------------------------------*/
Equalizer::Equalizer()
{
// Default values ----------------------
freq_low = 100;
freq_mid = 6000;
freq_high = 12000;
q_low = q_mid = q_high = 0.5;
gain_low = gain_mid = gain_high = 0.0001;
samplerate = 44100;
// --------------------------------------
Reset();
Update();
}

void Equalizer::Reset()
{
Band1.Reset();
Band2.Reset();
Band3.Reset();
}
void Equalizer::Run(void* buf ,unsigned int length)
{
Band3.Run(buf,length);
Band2.Run(buf,length);
Band1.Run(buf,length);
}
void Equalizer::SetGain(float Again_low,float Again_mid, float Again_high)
{
gain_high = Again_high ;
gain_mid  = Again_mid ;
gain_low  = Again_low ;
Update();
}
void Equalizer::Update()
{
Band1.Set(freq_low,gain_low,q_low,samplerate);
Band2.Set(freq_mid,gain_mid,q_mid,samplerate);
Band3.Set(freq_high,gain_high,q_high,samplerate);
}


As you see the equalizer is a straight forward implementation . If you want more control of the frequency band then add more Bandpass filters to the class .
The Default values need some tweaking.

How to use it with Bass?

Declare  
Code: [Select]
Equalizer MyEqualizer ; ;

then in DSP Callback pass the buffer and length to the Equalizer.Run procedure .
Code: [Select]

MyEqualizer.Run(buffer,length);


and to change the Gain call
Code: [Select]

MyEqualizer.SetGain( low , mid , high );
 

the gain is measured in dB

It worked for me hope it does for you too.

manu




manu

  • Posts: 51
Re: BASS_SAMPLE_FX  
« Reply #14 on: 19 Sep '01 - 10:22 »
Oh I forgot that when changeing Pitch you need to
Code: [Select]

MyEqualizer.samplerate = TheNewSamplerate ;
MyEqualizer.Update();

;)


steel

  • Posts: 8
Re: BASS_SAMPLE_FX  
« Reply #15 on: 21 Sep '01 - 07:01 »
Thanks Manu, I'll give it a shot!

;D