19 Jun '13 - 13:01 *
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]
  Reply  |  Print  
Author Topic: Bass.BASS_ChannelGetLevel resolution problem  (Read 261 times)
DoctorDangerous
Posts: 17


« on: 15 May '13 - 20:15 »
Reply with quoteQuote

I'm using Bass.BASS_ChannelGetLevel(_recHandle), and triggering it every 3 ms (using a worker thread). My problem is that the actual values only change every 30ms or so. Why is that? And can I do anything to improve the sampling rate? See example output below.


Level =28469
Level =28469
Level =28469
Level =28469
Level =28469
Level =28469
Level =28469
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =15365
Level =24588
Level =24588
Level =24588
Level =24588
Level =24588
Level =24588
Level =24588
Level =24588
Level =24588
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =10263
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =27043
Level =21674
Level =21674
Level =21674
Level =21674
Level =21674
Level =21674
Level =21674
Level =21674
Level =21674

Logged
atza
Posts: 74


« Reply #1 on: 16 May '13 - 06:03 »
Reply with quoteQuote

That's because getlevel function is so built that it automatically takes an average of 20ms worth of data

Look at the getdata function instead
Logged
DoctorDangerous
Posts: 17


« Reply #2 on: 16 May '13 - 08:27 »
Reply with quoteQuote

Thanks! Next question - How do I use GetData to retrieve the instantaneous signal level?

TIA
Logged
BassUser
Posts: 111


« Reply #3 on: 16 May '13 - 09:03 »
Reply with quoteQuote

Maybe you can try to use an DSP in that channel.

In a DSP you have access to each sample.

However, sample accurate "level" is hard to define. What you get examining sample levels is the waveform itself...

What's the purpose of updating level every 3ms?
« Last Edit: 16 May '13 - 09:05 by BassUser » Logged
DoctorDangerous
Posts: 17


« Reply #4 on: 16 May '13 - 09:11 »
Reply with quoteQuote

3ms isn't a critical value, but it's based on a rough calculation:
I am trying to determine as precisely as possible the time and amplitude of a drum hit. It's for an analysis tool for drummers, to show them how close to a precise beat they are. Speed drummers can reach speeds of around 30 hits per second, so the interval between hits is about 30ms, but as the precise time of the hit is important, I used a sampling rate ten times faster than the drummer plays.
I am using the "level" to identify the hits amplitude, and the time they occur.
Logged
BassUser
Posts: 111


« Reply #5 on: 16 May '13 - 11:31 »
Reply with quoteQuote

...then a DSP is probably perfect. You don't need a timer (since timers aren't very reliable in windows) and you can detect waveform transients directly with sample precision.

DSP's provide a Notify callback and timing latency corresponds to the used buffer size.
Logged
DoctorDangerous
Posts: 17


« Reply #6 on: 16 May '13 - 13:48 »
Reply with quoteQuote

Sounds ideal. Could you point me to any sample code? (I'm a novice with BASS and audio processing. I'm just helping out a mate with his degree thesis in music)
Logged
BassUser
Posts: 111


« Reply #7 on: 16 May '13 - 14:13 »
Reply with quoteQuote

I'm working with C# and bass .net

Bass .net is well documented here: http://www.bass.radio42.com/help/Index.html

If you are new to bass .net read Bass.NET overview with the documentation. It provides you with concepts and examples.

In Un4seen.Bass.Misc namespace you'll find BaseDSP class you can derive your own DSP from. There is a C# code example to get you started how to do your own DSP code.

Basically you have to override BaseDSP.DSPCallback method and implement what you want to do with the audio buffer presented there.

Logged
DoctorDangerous
Posts: 17


« Reply #8 on: 16 May '13 - 14:54 »
Reply with quoteQuote

I'm also using C# and Bass .NET.  Smiley

So in the callback, I use the BASS_GetData method to get the level of the signal, and once it exceeds a certain threshold I treat that as a "hit". Is that correct?

Which leaves me to ask, what triggers the callback? How often is the callback triggered? Or have I misunderstood something?
Logged
Ian @ un4seen
Administrator
Posts: 15363


« Reply #9 on: 16 May '13 - 15:58 »
Reply with quoteQuote

I'm using Bass.BASS_ChannelGetLevel(_recHandle), and triggering it every 3 ms (using a worker thread). My problem is that the actual values only change every 30ms or so. Why is that? And can I do anything to improve the sampling rate?

The reason for that is that the recorded data arrives in blocks rather than in a constant stream of samples, meaning there will be fresh data for your BASS_ChannelGetLevel call to process periodically rather than constantly. Unfortunately, it isn't possible to adjust the block length when using the standard BASS/DirectSound recording, but you could try using ASIO or WASAPI instead, eg. via BASSASIO or BASSWASAPI. They do give control over the block length, via the BASS_ASIO_Start "buflen" parameter in the case of ASIO, and via the BASS_WASAPI_Init "period" parameter in the case of WASAPI.
Logged
BassUser
Posts: 111


« Reply #10 on: 17 May '13 - 15:19 »
Reply with quoteQuote

So in the callback, I use the BASS_GetData method to get the level of the signal, and once it exceeds a certain threshold I treat that as a "hit". Is that correct?

If you implement your processing as DSP you don't need Bass_GetData. The dsp callback is fed with a sample data buffer.

An advantage of a DSP is you can add instances to any bass audio channels you want. You also get simple access to sample buffer data.

It's true that you don't get callbacks per sample, so buffer latency is a factor when you want your analysis to be "realtime on sample"... but I guess you don't really need that. Just for non realtime processing it does not matter. In any case you can use the sample position to perfectly pin the timing point when your spike occurred.

To get better realtime behaviour you need small buffers. Follow Ian's recommendation and try WasApi or ASIO.

To experiment with Asio get the free "ASIO4all" driver to get asio with your built in sound card. Otherwise only special (external) audio interfaces come with dedicated asio driver support.

And BTW, read the introduction I've pointed to. It's very good and I refer myself to it with pleasure from time to time.  Wink
« Last Edit: 17 May '13 - 15:29 by BassUser » Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines