Author Topic: "Effects"  (Read 2930 times)

Murinus

  • Posts: 26
"Effects"
« on: 14 Jan '13 - 15:24 »
Hello, I'm testing this awesome library and a little stuck
I'm using this code to get the FFt Data and put the data to the output
Code: [Select]
procedure FormCreate(Sender: TObject);

function RecordingCallback(Handle: HRECORD; buffer: Pointer; length, user: DWORD): boolean; stdcall;
  var
    I: integer;
  begin
    BASS_StreamPutData(output, buffer, length); // feed recorded data to output stream
    Result := True; // continue recording
  end;

begin
output := BASS_StreamCreate(44100, 1, 0, STREAMPROC_PUSH, NIL);
  input  := BASS_RecordStart(44100, 1, MakeLong(0, 10), @RecordingCallback, nil); // Recording Channel
end;

procedure Timer1Timer(Sender: TObject);
begin
  BASS_ChannelGetData(input, @FFt, BASS_DATA_FFT1024); // get the FFT data
end;

Its seems that if i use this way in the timer without the RecordingCallBack doesn't work :
Code: [Select]
BASS_ChannelGetData(input, @FFt, BASS_DATA_FFT1024); // get the FFT data
  BASS_StreamPutData(output, @FFt, BASS_STREAMPROC_END);
and i want to change the FFt Value, for an example

I'm speaking the letter aaaaaaa, which uses the values from FFt[100] to FFt[400] but another noise was recorded which is in the range FFt[600] to FFt[800] how can i set the value from this range to 0 and recording it so i will only listen to the aaaaaa?
there's a way that i can do it?
there's a way that i can play a sound with the FFt Data only?

thanks for answering and sorry about the bad English

saga

  • Posts: 2179
Re: "Effects"
« Reply #1 on: 14 Jan '13 - 16:58 »
BASS won't let you do spectrum (FFT) editing. For this, you'll need some FFT library (Kiss FFT is a tiny library, but getting it to run with Pascal/Delphi might be tricky if you're not experienced with C libraries) to convert the signal into the frequency domain (like ChannelGetData does), edit it and then convert it back into the time domain. However, in your specific case, it might already be enough to apply a low-pass filter (I suppose BASS_FX provides one), since you only want to get rid of frequencies above the wanted frequencies. That way, you can also get rid of the long delay that is introduced by the FFT algorithm.

Murinus

  • Posts: 26
Re: "Effects"
« Reply #2 on: 14 Jan '13 - 17:29 »
i have no experience in C or C++ programming, im a delphi/pascal programmer
there's a buffer : Pointer var in the RecordingCallBack funtion
couldnt i convert it to an array of single?

another question
how can i get the FFt complex data in delphi?
Code: [Select]
BASS_ChannelGetData(handle, fft, BASS_DATA_FFT1024|BASS_DATA_FFT_COMPLEX);and
Code: [Select]
(BASSData)128didnt work

Ian @ un4seen

  • Administrator
  • Posts: 20400
Re: "Effects"
« Reply #3 on: 15 Jan '13 - 14:03 »
To use the new BASS_DATA_FFT_COMPLEX option that's in the latest stuff, you will need to add this to the BASS.PAS file...

Code: [Select]
  BASS_DATA_FFT_COMPLEX = $80;   // FFT flag: return complex data

When using that, make sure you have increased the size of your "fft" array accordingly, as described here...

   http://www.un4seen.com/forum/?topic=14174.msg98707#msg98707

Murinus

  • Posts: 26
Re: "Effects"
« Reply #4 on: 7 Apr '13 - 05:46 »
i have tried all of this ways and none worked, i got 512 FFt value max, i use delphi
BASS_ChannelGetData(input, @FFt, BASS_DATA_FFT1024  +,-,|,and,or,xor  BASS_DATA_FFT_COMPLEX);

Ian @ un4seen

  • Administrator
  • Posts: 20400
Re: "Effects"
« Reply #5 on: 8 Apr '13 - 14:20 »
The BASS_DATA_FFT_COMPLEX option was introduced quite recently, so if it appears to be having no effect, perhaps an old BASS.DLL version is getting loaded? You can use BASS_GetVersion to confirm what version is loaded. If the BASS version is fine (eg. 0x02040A00), then please post your code to show how you are making the BASS_ChannelGetData call.

Murinus

  • Posts: 26
Re: "Effects"
« Reply #6 on: 9 Apr '13 - 00:50 »
i download the latest version from un4seen
i used this line "ShowMessage(IntToStr(BASS_GetVersion));" to get the version, it gave me this number 33818624

Source code:

Code: [Select]
BASS_ChannelGetData(input, @FFtComplex, BASS_DATA_FFT1024 or BASS_DATA_FFT_COMPLEX);
where
Code: [Select]
input : HRecord;
FFtComplex : array[0..2048] of single;

I put the values in a stringgrid
Code: [Select]
for i := 0 to 2048 do
begin
 StringGrid.Cells[1, i] := FloatToStr(FFtComplex[i]);
end;

then i get 512 lines of FFt and 1536 lines with 0;

thanks for reply xD

Ian @ un4seen

  • Administrator
  • Posts: 20400
Re: "Effects"
« Reply #7 on: 9 Apr '13 - 13:17 »
33818624 = 0x02040800 = 2.4.8.0. So it does look like the problem is that an old BASS.DLL version is being loaded. Did you put the latest BASS.DLL in the same folder as your EXE, and what version does the file's properties show?

Murinus

  • Posts: 26
Re: "Effects"
« Reply #8 on: 9 Apr '13 - 14:51 »
oh... thanks
i replaced all the bass.dll files but the one that was in the bin Folder
i will test it now
thanks again ^^

Murinus

  • Posts: 26
Re: "Effects"
« Reply #9 on: 9 Apr '13 - 15:19 »
here i am again...

i read this
Quote
BASS_DATA_FFT_COMPLEX   Return the complex FFT result rather than the magnitudes. This increases the amount of data returned (as listed above) fourfold, as it returns real and imaginary parts and the full FFT result (not only the first half). The real and imaginary parts are interleaved in the returned data.

and im using this code:
Code: [Select]
BASS_ChannelGetData(input, @FFtComplex, BASS_DATA_FFT1024 or BASS_DATA_FFT_COMPLEX);
The BASS_DATA_FFT1024 Returns me 512 values, but since BASS_DATA_FFT_COMPLEX returns the real and the imaginary parts i get an array of 2048 values. and that gave me this:
i was wondering why sometimes the values is negative and other times its positive and why the 2nd value is always 0...
« Last Edit: 9 Apr '13 - 15:55 by Murinus »

Ian @ un4seen

  • Administrator
  • Posts: 20400
Re: "Effects"
« Reply #10 on: 9 Apr '13 - 16:41 »
Negative values are normal in the complex data. The 2nd value is the imaginary part of the DC component, which is indeed always 0. If the complex data isn't giving you what you were expecting, please describe what you were expecting :)

Murinus

  • Posts: 26
Re: "Effects"
« Reply #11 on: 9 Apr '13 - 21:23 »
Hmm, let me see if i get it
the 1st and 2nd value i ignore?
then it start like

# 2 # Normal value (positive)
# 3 # Normal imaginary value (positive?)
# 4 # Complex value (positive and negative)
# 5 # Complex imaginary valur (positve and negative)?
# 6 # Normal value
# 7 # and so on?

another question
if the Normal value gives me the amplitude and the complex gives me the magnitude? What the imaginary parts gives me?
thanks, and sorry about the bad grammar

Actually i was expecting to make an espectrum of the frequency and the format of the wave... or something similar
« Last Edit: 10 Apr '13 - 17:00 by Murinus »

Ian @ un4seen

  • Administrator
  • Posts: 20400
Re: "Effects"
« Reply #12 on: 10 Apr '13 - 17:46 »
If you just want a spectrum display, you probably don't need to bother with the BASS_DATA_FFT_COMPLEX option. Please see the SPECTRUM (or LIVESPEC) example in the BASS package for a demonstration. Anyway, to clarify what the BASS_DATA_FFT_COMPLEX option does...

When you use the BASS_DATA_FFT_COMPLEX flag, you will receive complex data, which means there will be a "real" and "imaginary" part for each FFT bin:

  index 0 = 1st bin (DC component) real part
  index 1 = 1st bin (DC component) imaginary part
  index 2 = 2nd bin real part
  index 3 = 2nd bin imaginary part
  index 4 = 3rd bin real part
  ...

When you don't use the BASS_DATA_FFT_COMPLEX flag, you get this:

  index 0 = 1st bin (DC component) magnitude
  index 1 = 2nd bin magnitude
  index 2 = 3rd bin magnitude
  ...

The data is scaled by BASS_ChannelGetData so that the FFT magnitude is equal to the waveform amplitude, eg. a sine wave with 0.5 amplitude will result in the corresponding FFT bin having a 0.5 magnitude (may be bit less if the wave's frequency is between 2 bins). The magnitude can also be gotten from complex data like this...

Code: [Select]
magnitude[x] = sqrt(cfft[x*2]*cfft[x*2] + cfft[x*2+1]*cfft[x*2+1]);

Where "cfft" holds the complex data from a BASS_ChannelGetData call. The phase can also be calculated like this...

Code: [Select]
phase[x] = atan2(cfft[x*2+1], cfft[x*2]);

Murinus

  • Posts: 26
Re: "Effects"
« Reply #13 on: 14 Apr '13 - 20:03 »
oh, got it, i was wrong about my concept of it :P
was thinking that i would get the timbre with complex numbers

thank you!