Author Topic: BASS.NET API 2.4.12.7  (Read 783367 times)

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.0
« Reply #1325 on: 25 May '15 - 08:27 »
As far as I know, does BASS not support this.
It basically allows you to play MIDI files using a soundfont.

Amx Vector

  • Guest
Re: BASS.NET API 2.4.11.0
« Reply #1326 on: 3 Jun '15 - 18:24 »
Can I make open source software using BASS.NET ?  ???

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.0
« Reply #1327 on: 3 Jun '15 - 20:17 »
Yes, but note, that you can only distribute the dll library.
And you are not allowed to provide any registration keys.
And you must inform your users to get an individual registration key and/or license by their self - depending on what software they will build on top or how they use your software.

mrjoey

  • Posts: 31
Re: BASS.NET API 2.4.11.0
« Reply #1328 on: 18 Jun '15 - 10:43 »
hello , can you give me an example of doing a peak meter with peak hold bitmap like this?
or can you please implement a "CreatePeakmeter(handle.....colors...)as bitmap like you do in the spectrum? Big thanks.

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1329 on: 7 Jul '15 - 13:15 »
07.07.2015: Version 2.4.11.1 is out!

General update to all latest versions!
The BASS_FX PITCHSHIFT effect is now visible in the iOS and Android version.


Full Install:
 www.un4seen.com/filez/4/Bass24.Net.zip

Lib only:
 www.un4seen.com/filez/4/Bass24.Net_update.zip

djagab1

  • Guest
Re: BASS.NET API 2.4.11.1
« Reply #1330 on: 17 Jul '15 - 07:33 »
Hello.

I found a possible bug in the BasswasapiHandler class.
for some reason I cannot put it into exclusive mode, at the following conditions:

-playback material: dsd64 (created stream)

- freq=176400
-chan=2
-exclusive=true
-buffersize default
-period default
Bass version : 2.4.11
Bass.net : 2.4.11.0
Dsdlib version: latest
wasapilib version:
windows settings:

allow applications to take over control.
My DAC accepts the following sample formats: 32/44.1/48/88.2/96/176.4/192/358.5/384.


Even though the handler was created successfully and the members all indicate that the chosen settings are accepted, exclusive mode is not enabled. I discovered this because I still can modify the mixer sound level on my windows 7 64 bit machine and dsd DoP playback is producing noise on my DAC. To verify this I used
another program (JRiver media center) in the exact same setup and this one was capable of setting wasapi to exclusive mode, hence bypassing the windows mixer and playing my dsd file perfectly!

If I use the methods:

BassDsd.BASS_DSD_StreamCreateFile(.........);
BassWasapi.BASS_WASAPI_Init(12, 176400, 2, BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE, 0.5f, 0.5f, new WASAPIPROC(callback), IntPtr.Zero));
BassWasapi.BASS_WASAPI_Start();

Exclusive mode request is honored and dsd  DoP is playing beautifully.

So, is there a bug in the wasapihandler or am I missing something?

Thanks in advance for your reply.


radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1331 on: 17 Jul '15 - 08:17 »
Can you show me your code how you use the BassWasapiHandlder.
You might check the 'Exclusive' property once you initialized your handler to see, what happended,
By default the handler also just adds the BASS_WASAPI_EXCLUSIVE flag - so I can not see what might go wrong in my code?!

djagab1

  • Guest
Re: BASS.NET API 2.4.11.1
« Reply #1332 on: 17 Jul '15 - 21:38 »
Hello Bernd,

Thank you for your reply.

I copied the code responsible for the issue described earlier, below.

I also checked the _wasapiout members for their values after wasapi.init.
They all seem to be correct to me:
Exclusive is true.
Sample Rate = 176400
volume 1.0
internal mixer has a valid handle

Result:

Noise is played through the dac with a low sound level of music.
I can still modify the windows mixer level so it is not bypassed.
Could it be the wasapihandler's internal mixer is causing this?

Thank you

....

Code: [Select]
main()

{
if (init)
{
testDSDPlayback();
}
}


bool init()
{
 if (!Bass.BASS_Init(0,
                                176400,
                                BASSInit.BASS_DEVICE_FREQ,
                               System.IntPtr.Zero))
            {
               
                LatestErrorCode += DateTime.Now.ToString() + "BASS init reported: " + Bass.BASS_ErrorGetCode() + Environment.NewLine;
                return false;
            }

            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_BUFFER, 500);//make this changeable from outside the program.
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 20);
            return true;
}



void testDSDPlayback()
{
int stream =0;
BassWasapiHandler _wasapiOut;
 var flags = BASSFlag.BASS_SAMPLE_FLOAT |BASSFlag.BASS_STREAM_DECODE|BASSFlag.BASS_DSD_DOP;
BASS_CHANNELINFO ci = new BASS_CHANNELINFO();
           
stream = BassDsd.BASS_DSD_StreamCreateFile(@"mydsdtestfile.dsf", 0L, 0L, flags, 0);
Bass.BASS_ChannelGetInfo(stream, ci); // get the sample format
 _wasapiOut = new BassWasapiHandler(12,true, ci.freq, ci.chans, 500 / 1000.0f, 0.5f);
 if (!_wasapiOut.Init())
            {
                LatestErrorCode += " " + DateTime.Now.ToString() + " " + "could not init wasapi out " + Bass.BASS_ErrorGetCode() + Environment.NewLine;

            }

if (!_wasapiOut.AddOutputSource(stream, flags))
            {
                LatestErrorCode += " " + DateTime.Now.ToString() + " " + "could not create wasapihandler " + Bass.BASS_ErrorGetCode() + Environment.NewLine;

            }

            success = _wasapiOut.Start();

            if (!success)
            {
                LatestErrorCode += " " + DateTime.Now.ToString() + " " + "could not start wasapi out " + Environment.NewLine;
            }
}

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1333 on: 19 Jul '15 - 12:03 »
Looks all okay - unfortunately I haven't any DSD device here to test with.
But I also do call BASS_WASAPI_Init with the BASS_WASAPI_EXCLUSIVE flag - that's it.
So I can not spot why this shouldn't work ?

djagab

  • Posts: 35
Re: BASS.NET API 2.4.11.1
« Reply #1334 on: 19 Jul '15 - 21:49 »
Thanks for your reply. Not the answer I was looking for, though ;). I don't think it's dsd related. If you try a normal stream say from a wav file, the behavior is exactly the same. You might not notice it because the sound is playing,  just not in exclusive mode. So what's going on here?

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1335 on: 20 Jul '15 - 08:51 »
Maybe Ian can shed some light into this. Here is what I am doing inside Bass.Net:

1) Constructor of the BassWasapiHandler:
new BassWasapiHandler(int device, bool exclusive, int freq, int chans, float buffer, float period)
in your case:
new BassWasapiHandler(12, true, 176400, 2, 0.5f, 0.5f);

_internalMixer = BassMix.BASS_Mixer_StreamCreate(freq, chans, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_RESUME);

That's it!


2) Now, when you invoke the Init() method, the following is done:

BassWasapi.BASS_WASAPI_Init(12, 176400, 2, BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE, 0.5f, 0.5f, internalWasapiProc, IntPtr.Zero);

That's it!


3) Finally you add a source channel:
wasapiOut.AddOutputSource(stream, flags)
This would result in:

BassMix.BASS_Mixer_StreamAddChannel(_internalMixer, stream, flags | BASSFlag.BASS_MIXER_DOWNMIX);





djagab1

  • Guest
Re: BASS.NET API 2.4.11.1
« Reply #1336 on: 20 Jul '15 - 09:39 »
Thanks for the explanation.
For bit perfect DSD playback the BASSFlag.BASS_MIXER_DOWNMIX flag might be a problem, I would say. But I will leave this to the experts.

I'm curious about Ian's thoughts.


Ian @ un4seen

  • Administrator
  • Posts: 20427
Re: BASS.NET API 2.4.11.1
« Reply #1337 on: 20 Jul '15 - 12:59 »
I will send you debug BASSWASAPI version to confirm what it's seeing there.

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1338 on: 20 Jul '15 - 16:43 »
@djagab1: you might try this out yourself, as the BASS_MIXER_DOWNMIX flag is only applied in your version unless you specify some SPEAKER_FLAGS, e.g. BASS_SPEAKER_FRONT.

But in case your file is a standard stereo file, the BASS_MIXER_DOWNMIX should make any trouble.
Especially it shouldn't affect the Exclusive mode!

djagab1

  • Guest
Re: BASS.NET API 2.4.11.1
« Reply #1339 on: 21 Jul '15 - 14:37 »
Ian suggested me to send I a RAW pcm copy of the output to the wasapi device by means of a modified wasapi dll he sent me. So I did.
It appeared that I had to add the flag BASS_MIXER_NORAMPIN to the AddOutputSource call in order to prevent ramping in at start of playback. It confused my DAC and started playback noise and did not honor the wasapi exclusive request. After adding this flag, the BassWasapiHandler Radio42 supplies is able to play DSD (DoP) perfectly! Even the windows mixer got bypassed as it should in exclusive mode.

@Radio42, @Ian: Thank you both for your assistance.

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1340 on: 21 Jul '15 - 14:47 »
I am glad we (you and Ian) figured it!
As I really couldn't think of anything else.
However, it is funny, that the (missing) NORAMPIN options confused your DAC/driver, as it basically just amplifies the initial samples - so I really wonder how your DAC/driver can even recognize that?!
But however, it is like it is ;-)

Ian @ un4seen

  • Administrator
  • Posts: 20427
Re: BASS.NET API 2.4.11.1
« Reply #1341 on: 21 Jul '15 - 15:13 »
It appeared that I had to add the flag BASS_MIXER_NORAMPIN to the AddOutputSource call in order to prevent ramping in at start of playback. It confused my DAC and started playback noise and did not honor the wasapi exclusive request. After adding this flag, the BassWasapiHandler Radio42 supplies is able to play DSD (DoP) perfectly! Even the windows mixer got bypassed as it should in exclusive mode.

Great to hear that DoP output is working with your DAC now. I think it's unlikely that the ramping-in will have somehow disabled exclusive mode (I don't see how it could). It seems more likely that the device/driver wants to see DoP data straight away to enable DSD mode, and the ramping-in would have prevented that.

deromas

  • Posts: 2
Re: BASS.NET API 2.4.11.1
« Reply #1342 on: 22 Jul '15 - 02:53 »
I believe there is an error in this version of bass.net
I always receive  this message from Visual Basic 2010.

'BASS_ChannelGetLevel' is ambiguous because multiple kinds of members with this name exist in class 'Un4seen.Bass.Bass'


all programs also examples
with a instead old dll's all ok

how do I download older versions? dll I have is really very old.

djagab

  • Posts: 35
Re: BASS.NET API 2.4.11.1
« Reply #1343 on: 22 Jul '15 - 07:05 »
Thank you guys for the replies. I did a little background search and found the DSD DoP open standard to contain the following sentences:

In order to switch from PCM to DSD mode the receiver has to detect 32 consecutive DSD marker bytes on all channels used.

In order to switch from DSD to PCM mode the receiver has to detect at least 1 single missing DSD marker byte in at least 1 channel.

I would say that ramping in could indeed have an effect on DSD detection reading this spec. If the USB receiver in my DAC follows these specs at a strict level, it might decide to use PCM in stead of DSD and produce noise.

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1344 on: 22 Jul '15 - 10:02 »
@deromas: Can you please post the exact error, as I guess it is NOT coming from Bass.Net.
And of course there are multiple OVERLOADs of 'BASS_ChannelGetLevel' existing, but all with a different signature - so that shouldn't be any issue.
Please also confirm what programming language and OS you are using...

deromas

  • Posts: 2
Re: BASS.NET API 2.4.11.1
« Reply #1345 on: 22 Jul '15 - 12:27 »
@radio42
let's take a practical example of the program not written by me.

https://www.youtube.com/watch?v=dwhQrgCOGBw

code:
Code: [Select]
Imports Un4seen.Bass
Imports BassUn4SeenEQualizer.Net.BassEQualizer

Public Class Form1
    Inherits Form

    Private fDlg As System.Windows.Forms.OpenFileDialog
    Private paramEQ As BASS_DX8_PARAMEQ
    Private fxEQ As Integer()
    Private strm As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        RegistrationBassNet("email", "serials")
        Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Me.Handle.ToInt32)
        KnobVol.Value = KnobVol.MaxValue / 2
        Bass.BASS_SetVolume(1.0 / 2)
        KnobPeq1.Value = KnobPeq1.MaxValue / 2
        KnobPeq2.Value = KnobPeq2.MaxValue / 2
        KnobPeq3.Value = KnobPeq3.MaxValue / 2
    End Sub

    Public Sub New()
        MyBase.New()
        InitializeComponent()
        Me.CenterToScreen()
        fDlg = New System.Windows.Forms.OpenFileDialog
        Timer1.Interval = 50
        BtnLound.ForeColor = Color.Black
        paramEQ = New BASS_DX8_PARAMEQ
        fxEQ = New Integer(2 - 0) {}
        fDlg.FileName = Nothing
        fDlg.Filter = "Song File(*.mp3;*.wav)|*.mp3;*.wav"
    End Sub

    Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
        If fDlg.ShowDialog = Windows.Forms.DialogResult.OK Then
            Bass.BASS_StreamFree(strm)
            strm = Bass.BASS_StreamCreateFile(fDlg.FileName, 0, 0, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MUSIC_LOOP)
            LblDuration.Text = Utils.FixTimespan(Bass.BASS_ChannelBytes2Seconds(strm, Bass.BASS_ChannelGetLength(strm)), "mm:ss")
            slidePos.Maximum = Bass.BASS_ChannelBytes2Seconds(strm, Bass.BASS_ChannelGetLength(strm, BASSMode.BASS_POS_BYTES))
            slidePos.TickFrequency = slidePos.Maximum / 100 * 10
            BASS_TableVolParamEQ()
        End If
    End Sub

    Private Sub btnPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlay.Click
        If strm <> 0 Then
            Bass.BASS_ChannelPlay(strm, True)
            BASS_TableVolParamEQ()
            Timer1.Enabled = True
        End If
    End Sub

    Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
        If strm <> 0 Then
            Bass.BASS_ChannelStop(strm)
            Timer1.Enabled = False
        End If
    End Sub

    Private Sub KnobVol_ValueChanged(ByVal sender As System.Object, ByVal e As DevComponents.Instrumentation.ValueChangedEventArgs) Handles KnobVol.ValueChanged
        BASS_VolumeWave()
    End Sub

    Private Sub KnobBal_ValueChanged(ByVal sender As Object, ByVal e As DevComponents.Instrumentation.ValueChangedEventArgs) Handles KnobBal.ValueChanged
        BASS_VolumeBalance()
    End Sub

    Private Sub BASS_VolumeWave()
        Bass.BASS_SetVolume(1.0! / 100 * CSng(KnobVol.Value))
        ToolTip1.SetToolTip(KnobVol, CStr(Math.Round(1.0! / 100 * CSng(KnobVol.Value) * 100)))
        Return
    End Sub

    Private Sub BASS_VolumeBalance()
        Bass.BASS_ChannelSetAttribute(strm, BASSAttribute.BASS_ATTRIB_PAN, CSng(KnobBal.Value) / 100.0! * 10)
        ToolTip1.SetToolTip(KnobBal, CStr(Math.Round(CSng(KnobBal.Value) / 100.0! * 100)))
        If CStr(Math.Round(CSng(KnobBal.Value) / 100.0! * 100)) = -50 Then
            LedMeter1.Led1ColorOn = Color.DarkGreen
            LedMeter1.Led2ColorOn = Color.Olive
            LedMeter1.Led3ColorOn = Color.Maroon
            LedMeter2.Led1ColorOn = Color.LimeGreen
            LedMeter2.Led2ColorOn = Color.Yellow
            LedMeter2.Led3ColorOn = Color.Red
            Return
        End If
        If CStr(Math.Round(CSng(KnobBal.Value) / 100.0! * 100)) = 50 Then
            LedMeter2.Led1ColorOn = Color.DarkGreen
            LedMeter2.Led2ColorOn = Color.Olive
            LedMeter2.Led3ColorOn = Color.Maroon
            LedMeter1.Led1ColorOn = Color.LimeGreen
            LedMeter1.Led2ColorOn = Color.Yellow
            LedMeter1.Led3ColorOn = Color.Red
            Return
        End If
        If CStr(Math.Round(CSng(KnobBal.Value) / 100.0! * 100)) = 0 Then
            LedMeter1.Led1ColorOn = Color.LimeGreen
            LedMeter1.Led2ColorOn = Color.Yellow
            LedMeter1.Led3ColorOn = Color.Red
            LedMeter2.Led1ColorOn = Color.LimeGreen
            LedMeter2.Led2ColorOn = Color.Yellow
            LedMeter2.Led3ColorOn = Color.Red
            Return
        End If
        Return
    End Sub

    Private Sub KnobPeq1_ValueChanged(ByVal sender As Object, ByVal e As DevComponents.Instrumentation.ValueChangedEventArgs) Handles KnobPeq1.ValueChanged
        BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 0, CSng(KnobPeq1.Value) / 10)
        ToolTip1.SetToolTip(KnobPeq1, CStr(Math.Round(CSng(KnobPeq1.Value) / 10 * 10)))
    End Sub

    Private Sub KnobPeq2_ValueChanged(ByVal sender As Object, ByVal e As DevComponents.Instrumentation.ValueChangedEventArgs) Handles KnobPeq2.ValueChanged
        BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 1, CSng(KnobPeq2.Value) / 10)
        ToolTip1.SetToolTip(KnobPeq2, CStr(Math.Round(CSng(KnobPeq2.Value) / 10 * 10)))
    End Sub

    Private Sub KnobPeq3_ValueChanged(ByVal sender As Object, ByVal e As DevComponents.Instrumentation.ValueChangedEventArgs) Handles KnobPeq3.ValueChanged
        BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 2, KnobPeq3.Value / 10)
        ToolTip1.SetToolTip(KnobPeq3, CStr(Math.Round(CSng(KnobPeq3.Value) / 10 * 10)))
    End Sub

    Private Sub BASS_TableVolParamEQ()
        BASS_ChannelSetFXEQ(strm, paramEQ, fxEQ, 3)
        BASS_FXSetParametersFXEQ(paramEQ, fxEQ, 120.0!, 0)
        BASS_FXSetParametersFXEQ(paramEQ, fxEQ, 1000.0!, 1)
        BASS_FXSetParametersFXEQ(paramEQ, fxEQ, 15000.0!, 2)
    End Sub

    Private Sub slidePos_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles slidePos.Scroll
        Bass.BASS_ChannelSetPosition(strm, Bass.BASS_ChannelSeconds2Bytes(strm, CDbl(slidePos.Value)))
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim sTime As Double = Bass.BASS_ChannelBytes2Seconds(strm, Bass.BASS_ChannelGetPosition(strm, BASSMode.BASS_POS_BYTES))
        Dim lTime As Double = Strings.Right(Strings.Left(Bass.BASS_ChannelBytes2Seconds(strm, Bass.BASS_ChannelGetPosition(strm) - Bass.BASS_ChannelGetLength(strm)), 4), 3)
        Dim level As Integer = Bass.BASS_ChannelGetLevel(strm)
        LblStartPos.Text = Utils.FixTimespan(sTime.ToString, "mm:ss")
        LblLeftPos.Text = Utils.FixTimespan(lTime.ToString, "mm:ss")
        slidePos.Value = Bass.BASS_ChannelBytes2Seconds(strm, Bass.BASS_ChannelGetPosition(strm, BASSMode.BASS_POS_BYTES))
        LedMeter1.Level = Utils.LowWord32(level) * 1.8
        LedMeter2.Level = Utils.HighWord32(level) * 1.8
    End Sub

    Private Sub BtnLound_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnLound.Click
        Select Case BtnLound.ForeColor
            Case Color.Black
                BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 0, 12)
                BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 3, 12)
                BtnLound.ForeColor = Color.Red
            Case Else
                BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 0, CSng(KnobPeq1.Value) / 100 * 10)
                BASS_ChannelUpdateFXEQ(paramEQ, fxEQ, 3, CSng(KnobPeq1.Value) / 100 * 10)
                BtnLound.ForeColor = Color.Black
        End Select
    End Sub
End Class

I open it and I work with the program in which it was written: Visual Basic 2008 (but converts and works well with vb2010)
  version of the dll is 2.4.10.3



inserting the dll (always v2 runtime) you get the actual error



and this is ALWAYS
also with other programs and one in particular that I wrote (simple actually) that I can not run

if you want I will send you more photos with vb 2010

Ian @ un4seen

  • Administrator
  • Posts: 20427
Re: BASS.NET API 2.4.11.1
« Reply #1346 on: 22 Jul '15 - 18:00 »
Thank you guys for the replies. I did a little background search and found the DSD DoP open standard to contain the following sentences:

In order to switch from PCM to DSD mode the receiver has to detect 32 consecutive DSD marker bytes on all channels used.

In order to switch from DSD to PCM mode the receiver has to detect at least 1 single missing DSD marker byte in at least 1 channel.

I would say that ramping in could indeed have an effect on DSD detection reading this spec. If the USB receiver in my DAC follows these specs at a strict level, it might decide to use PCM in stead of DSD and produce noise.

Yes, the ramping-in would mean that the DAC starts in PCM mode, but it should then switch to DSD mode once the DoP data appears following the ramp-in. That doesn't seem to be happening in your case; it seems like the DAC/driver may be making a DSD/PCM mode decision at the start and then sticking with that, ie. it needs to see DoP data at the start to enable DSD mode.

radio42

  • Posts: 4576
Re: BASS.NET API 2.4.11.1
« Reply #1347 on: 23 Jul '15 - 09:33 »
@deromas:

Maybe it is coming from the external "BassUn4SeenEQualizer" or "VU_MeterLibrary" project which you also include?!
But for sure within Bass.Net there is definitely only ONE overload with that signature ("int Bass.BASS_ChannelGetLevel(int handle") existing.

When you are within VisualStudio you might use 'Go to Definition' or press 'CTRL+J' to invoke the IntelliSense options; this should actually tell you where the two method re ambiguous...

You might also try the provided VB.Net samples; they also contain some BASS_ChannelGetLevel and they compile fine here - also with the v2 runtime.
Just make sure to also use the v2.0 Bass.Net version!

mcooper

  • Posts: 38
Re: BASS.NET API 2.4.11.1
« Reply #1348 on: 23 Jul '15 - 10:17 »
Hello,

I'm using BASS.NET on Android, and trying to use BASS_ChannelGetData and FFTFrequency2Index to get the levels for different frequencies (e.g. bass, mid, and treble), but the numbers don't seem to make sense.

I was previously using this code to get the overall peak (between 0 and 1):

long length = Bass.BASS_ChannelSeconds2Bytes(CurrentHandle.Value, 0.020);
float[] data = new float[length/4];

int got = Bass.BASS_ChannelGetData(CurrentHandle.Value, data, (int)length | (int)BASSData.BASS_DATA_FLOAT);

float max = 0;
for (int a = 0; a < got/2; a++)
{
    var abs = Math.Abs(data[a]);               
    if (abs > max)
        max = abs;
}

This seems to work, but I'd like to get different values for frequency ranges, so I tried something like this:

float[] data = new float[2048];

Bass.BASS_ChannelGetData(CurrentHandle.Value, data, (int)BASSData.BASS_DATA_FFT4096);
            
float max = 0;
for (int a = 0; a < 2048; a++)
{
   var frequency = Utils.FFTFrequency2Index (a, 4096, 44100);
   Logger.Debug (this, "Level: {0}, Frequency {1}, Index: {2}", data [a], frequency, a);
   var abs = Math.Abs(data[a]);

   if (abs > max)
      max = abs;
}

I was going to check the frequency and then return 3 different max values, but the frequency and the value (e.g. data[a]), seem wrong to me.  Index 1621 - 1631 all return a frequency of 151 and very small values (e.g. 8.418E-05).

Am I doing something wrong here?

Thanks,

Matt

Ian @ un4seen

  • Administrator
  • Posts: 20427
Re: BASS.NET API 2.4.11.1
« Reply #1349 on: 23 Jul '15 - 14:48 »
...
for (int a = 0; a < 2048; a++)
{
   var frequency = Utils.FFTFrequency2Index (a, 4096, 44100);
   Logger.Debug (this, "Level: {0}, Frequency {1}, Index: {2}", data [a], frequency, a);
...

It looks like you should be using FFTIndex2Frequency rather than FFTFrequency2Index there, ie. you want to translate an index (a) to a frequency.

Regarding the main question of getting the level in 3 bands, you could indeed use FFT for that, but you probably don't need particularly great frequency resolution, so you could use a smaller FFT size (eg. 512 samples rather than 4096) to reduce CPU usage. For example, if your mid band is 300-3000 Hz, then you could do something like this:

Code: [Select]
float freq, fft[256], level[3]={0, 0, 0};
BASS_ChannelGetAttribute(handle, BASS_ATTRIB_FREQ, &freq); // get sample rate
BASS_ChannelGetData(handle, fft, BASS_DATA_FFT512); // perform 512 sample FFT
int be=300*512/freq+0.5; // low band ends @ 300 Hz
if (be>256) be=256; // just in case
int b=1; // skip 1st bin (DC component)
for (;b<be; b++) {
if (level[0]<fabs(fft[b])) level[0]=fabs(fft[b]); // found new peak low level
}
be=3000*512/freq+0.5; // mid band ends @ 3000 Hz
if (be>256) be=256; // just in case
for (;b<be; b++) {
if (level[1]<fabs(fft[b])) level[1]=fabs(fft[b]); // found new peak mid level
}
for (;b<256; b++) {
if (level[2]<fabs(fft[b])) level[2]=fabs(fft[b]); // found new peak high level
}
// "level" array now contains low/mid/high band levels