24 May '13 - 22:56 *
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: Question about reading the channel levels, VB2010  (Read 433 times)
catman8120
Posts: 6


« on: 19 Aug '12 - 00:06 »
Reply with quoteQuote

I am trying to sample the level of mp3 files to find the beginning and end of the music and also testing for the audio levels at 100 ms points throught the song to get an average volume and a peak volume to do some rough automatic volume processing.  But I cannot seem to get this code segment to return samples reliably.  Some mp3s work pretty good, some not at all.  I have stripped out all but the bare minimum of code to simplify my question.  If you feed this thing an mp3 file I think it should fill the LevelLst with 25ms sample levels taken every 100ms.  Different mp3s return different results.  Usually returns a few samples then just 0's.  However a specific mp3 will always return the same results.  What am I doing wrong?


Public Sub ScanTest2(ByVal SongPath As String, LevelLst As List(Of Integer))
        Dim DecodeStreamId As Int32 = Bass.BASS_StreamCreateFile(SongPath, 0, 0, BASSFlag.BASS_STREAM_DECODE)  'open the decode_stream
        Dim StreamLength As Integer = Bass.BASS_ChannelGetLength(DecodeStreamId)
        If DecodeStreamId <> 0 Then
            Dim Result As Boolean = True
            Dim Level As Integer
            Dim LeftLevel As Integer
            Dim RightLevel As Integer
            Dim AudioLevel As Integer
            Dim SamplePosition As Int64
            Dim SampleInterval As Integer = 7056 * 3

            Do While Result = True
                Level = Bass.BASS_ChannelGetLevel(DecodeStreamId)
                LeftLevel = Utils.LowWord32(Level)
                RightLevel = Utils.HighWord32(Level)
                AudioLevel = (LeftLevel + RightLevel) / 2
                LevelLst.Add(AudioLevel)
                SamplePosition = Bass.BASS_ChannelGetPosition(DecodeStreamId)
                Result = Bass.BASS_ChannelSetPosition(DecodeStreamId, SamplePosition + SampleInterval, 0)   'move to next sample
            Loop
            Bass.BASS_StreamFree(DecodeStreamId)
        End If
    End Sub

 Huh
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #1 on: 20 Aug '12 - 14:44 »
Reply with quoteQuote

Please try adding the BASS_STREAM_PRESCAN flag to your BASS_StreamCreateFile call, to have it pre-scan the MP3 file for seek points.
Logged
catman8120
Posts: 6


« Reply #2 on: 20 Aug '12 - 19:54 »
Reply with quoteQuote

Thanks Ian,


I have tried that but it extends the time from about a half second to over 3 seconds which makes this too slow for live dj.  I have tried the DecodeAllData function and it is acceptably fast but also works sometimes.  Why do these work on some mp3s or part of some?  Is this not what these functions are for?  These functions do not return any error just no data.

catman8120
Logged
Chris
Posts: 1507


« Reply #3 on: 20 Aug '12 - 21:33 »
Reply with quoteQuote

Hi
I think a better way ist to use the beatstuff of the bass_fx lib.
Just catch the Level inside the Beatproc.
Chris
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #4 on: 22 Aug '12 - 15:50 »
Reply with quoteQuote

I have tried that but it extends the time from about a half second to over 3 seconds which makes this too slow for live dj.  I have tried the DecodeAllData function and it is acceptably fast but also works sometimes.  Why do these work on some mp3s or part of some?  Is this not what these functions are for?  These functions do not return any error just no data.

Seeking (via BASS_ChannelSetPosition) won't be exact on MP3 files unless the BASS_STREAM_PRESCAN flag is used. Also, due to the way that MP3 works, the decoder will produce a short silence after seeking unless that flag is used, which will affect your BASS_ChannelGetLevel call. If you don't need the position to be exact, and you just want to avoid the silence, then you could add another BASS_ChannelGetLevel call to skip the silence, eg. add a BASS_ChannelGetLevel call after the BASS_ChannelSetPosition call and ignore the return value.

Alternatively, you could add the BASS_POS_DECODETO flag to your BASS_ChannelSetPosition call, so that it decodes its way (rather than jumping) to the wanted position.
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines