Question about the feasibility of a project

Started by Phil75,

Phil75

Hello everyone  :)

I have a project and I would like to know if you think it is feasible.

I would like to load a file with the "BASS_StreamCreateFile" function (reference file),
and do a frequency analysis on 10 bands, 20hz,100,300,600,1000,2000,3000,4000,5000,6000.
(I don't know if 10 frequency bands is enough).
I think it is possible using the "BASS_ChannelGetData" function (BASS_DATA_FFT).

And set a 10 band equalizer (BASS_FX_BFX_PEAKEQ) to get the same tone on another file.

I think it's called "EQ Matching".

But I don't know how to determine the Gain of the 10 frequency bands of the equalizer,
from the result of the frequency analysis of the two files.

Do you think this is achievable and not too difficult?

Phil75

Hello  :)

I created a small piano software with audio samples.
I recorded the piano note with a velocity of 127. And to simulate the other velocities,
I used a low-pass filter.
But the result was not very good.
So I recorded 2 notes, one with a velocity of 127, and another with a velocity of 40.
And depending on how hard I press the key when I play, I vary a "CrossFade" between the 2 Samples.
The result is better.
But I read on the internet that this could cause "Phase cancellation" problems.
I thought that the solution was perhaps to analyze the sound of the Sample recorded with a velocity of 40,
and to apply an Equalizer filter on the Sample recorded at 127, to obtain a sound almost identical to the
Sample recorded with a velocity of 40.

I use this to load the Samples :

Handle = Bass.BASS_StreamCreateFile(FileName, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
To retrieve the "FFT" data of the Sample recorded with a velocity of 40, I use this code.
Every 100ms, I retrieve the maximum values for the frequency list (TabloFreq) that I will use for the equalizer.
I use 30 frequencies for the equalizer.

l = Bass.BASS_ChannelSeconds2Bytes(Handle, 0.1)
            Do
                b = Bass.BASS_ChannelSetPosition(Handle, p)
                If b = True Then
                    Bass.BASS_ChannelGetData(Handle, FFTtemp, CInt(BASSData.BASS_DATA_FFT4096))
                    For i = 0 To 29
                        If FFTtemp(TabloFreq(i).Index) > SampleReference.FFT(i) Then SampleReference.FFT(i) = FFTtemp(TabloFreq(i).Index)
                    Next i
                    p = p + l
                Else
                    Exit Do
                End If
            Loop

To convert data to "Db", I use this code:
(I don't remember where I found this code, and I'm not sure I understand how it works...)

Const minDBValue As Double = -90
        Const maxDBValue As Double = 0
        Const dbScale As Double = (maxDBValue - minDBValue)

        For i = 0 To 29
            d = 20.0 * Math.Log10(CDbl(SampleReference.FFT(i)))
            dbValueReference = (d - minDBValue) / dbScale
            dbValueReference = dbValueReference * 15

            EQsettings = New BASS_BFX_PEAKEQ
            EQsettings.lBand = i
            Bass.BASS_FXGetParameters(handleEQ, EQsettings)
            EQsettings.fGain = CSng((dbValueReference / 4))
            Bass.BASS_FXSetParameters(handleEQ, EQsettings)
        Next i

So I apply the filter to the sample recorded with a velocity of 127, and the result is good.
I get a sound that is very similar to the sample recorded with a velocity of 40.
But after the equalizer, the sound is really very loud.
I use this code which usually works well, to limit the sound to -6 Db.

' Get the Level for 4 seconds (40 x 100ms)
        Bass.BASS_ChannelSetPosition(SampleToModify.Handle, 0)
        l100ms = CInt(Bass.BASS_ChannelSeconds2Bytes(SampleToModify.Handle, 0.1))
        Array.Resize(Datas, l100ms / 4)
        For j = 1 To 40
            Bass.BASS_ChannelGetData(SampleToModify.Handle, Datas, l100ms)
            Levels = Un4seen.Bass.Utils.GetLevel(Datas, 2, -1, -1)
            Level = Un4seen.Bass.Utils.LowWord(Levels)
            If Level > LevelPeak Then LevelPeak = Level
            Level = Un4seen.Bass.Utils.HighWord(Levels)
            If Level > LevelPeak Then LevelPeak = Level
        Next j
        VolumeParam = New BASS_FX_VOLUME_PARAM
        Bass.BASS_FXGetParameters(VolumeFX, VolumeParam)
        VolumeParam.fTarget = 0.5F / (LevelPeak / 32768)
        Bass.BASS_FXSetParameters(VolumeFX, VolumeParam)

But this time the code doesn't work very well.
"LevelPeak" rises to 32767, and the sound remains very loud.
How to do this without having to manually change the value of "VolumeParam.fTarget"?