Problems displaying wave data for visualisation...

Started by kchabot, 16 Jun '03 - 15:05

kchabot

During the playback of a song, I created a synched decoding stream hDA...
Now, I can succesfully display the wave-data-to-come for about 5 sec by decoding the whole 5 sec everytime, but that uses a lot of cpu is you do this 15/times a second per song... Now I used the code bellow to only decode the time needed and add it to the end of the wave-data array used to draw the wave but I have a problem...
After the data of the first full decode (fe first 5 sec) has passed, all the new decoded stream data is seperated from each other by the same size of that new stream data.
fe: IIIIIIIIIIIII     IIIII     IIIII     IIIII
    (BuffSize * 2)    Delta     Delta     Delta

I don't know why, and I can't figure it out :s can anyone help me? My code is listed bellow where:
cPos = current position
vALastPos = last start position of decoded stream
vALastSize = buffer size last decoded
vaDelta = difference, size of stream to be decoded
arr = new stream data array (int)
arrZ = buffer (delta) stream data array
vaLastArr = array stream data that was last displayed

cPos = BASS_ChannelGetPosition(hA)
If (cPos < vALastPos) Or (vALastPos = 0) Then
    vALastPos = cPos
    BASS_ChannelSetPosition hDA, cPos
    vALastSize = bufSize * 2
    BASS_ChannelGetData hDA, arr(0), bufSize * 2
    vALastArr = arr
Else
    vADelta = cPos - vALastPos
    If Not vADelta = 0 Then
        dDel = vADelta / 2
        For i = vADelta To vALastSize - 1
            arr(i - vADelta) = vALastArr(i)
        Next
        ReDim arrZ(vADelta + 1)
        BASS_ChannelSetPosition hDA, vALastPos + vALastSize - vADelta
        BASS_ChannelGetData hDA, arrZ(0), vADelta
        dOff = vALastSize / 2 - dDel
        If dOff > 0 Then
            For i = 0 To vADelta - 1
                arr(dOff + i) = arrZ(i)
            Next
            vALastPos = cPos
            vALastArr = arr
        Else
            vALastPos = 0
            arr = vALastArr
        End If
    Else
        arr = vALastArr
    End If
End If

Any help is welcome :)



Irrational86

I see no one is helping i think i should say what i think...I cant really understand whats wrong, explain in a little bit more plain english.. :-/


kchabot

Ok, I started from scratch now :)
After a while I seemed to be close to the solution... There is something I do not understand about bass...

When I need to retreive 5 seconds (f.e.: 44100*5) I needed to increase this value by 2, even if the stream was mono.
In the example bellow it seemed to work at first, but when I retreived the delta sample data (data needed to compleet the waveform) I retreived only half the amount I needed, even if I multiplied by 2... I don't really know why...

The result was a waveform that was stretched 2x in time after the first build (of the full 5 seconds) has passed.
To counteract this effect, i simply decreased the avgSize by 2 calculating medium values over half only half the first wave data...

Anyway, it works now, here is the code...

'general declarations
Public vALastPos As Long 'Position when last data was retr.
Public vALastArr() As Integer 'Last data retreived
Public vALastSize As Long 'Last size of data retreived
Public vADelta As Long 'The size of the data that tobe added
Public vADeltaGraf As Long 'The last graph data
'This array contains the waveform for it's predefined length
'From 0 to 100...

'At 50ms do the calculations...
Dim mPos As Single 'used to get the music position in sec
Dim fPos As Long 'Actual position of decoding stream (mono)
Dim bufSize As Long 'Buffer data size used
Dim arr() As Integer 'Temporary array of new data
Dim avgSize As Long 'Size of data that is covered when
'calculating the average value of the wavedata
Dim res As Integer 'Resolution of calculating the aver.data
Dim m As Long 'Loop index value
Dim mOff As Long 'Used to hold the offset of an arr in loop
bufSize = 44100 * 4 'Set the size of the buffer

'Seek current position
mPos = BASS_ChannelBytes2Seconds(hA, BASS_ChannelGetPosition(hA))
fPos = BASS_ChannelSeconds2Bytes(hDA, mPos)

'If the current position = last position, no nothing
If vALastPos = fPos Then GoTo novis
'Calculate average and resolution
avgSize = bufSize / UBound(GrfA)
'visAcuracy is the value of samples taken. 32 or 64 is a
good value... 128 is better
res = avgSize / visAcuracy '= step size in calculation

'If last position was not set, decode the whole stream
If vALastPos <= 0 Then
    'Get data
    BASS_ChannelSetPosition hDA, fPos
    'Init the temporary array
    ReDim arr(bufSize)
    BASS_ChannelGetData hDA, arr(0), bufSize * 2
    'Build the graph
    'avgSize must be half, why???
    avgSize = avgSize / 2
    For m = 0 To UBound(GrfA) - 1
        'This function sweeps the temp array from
        m*avgsize until m*avgsize+avgsize with a step of res
        GrfA(m) = (calcAvg(arr, m * avgSize, avgSize, res)
    Next
    'Set last variables to new data...
    vALastPos = fPos
    vALastArr = arr
    vALastSize = bufSize
Else
    vADelta = fPos - vALastPos
    'If the stream is playing foreward and delta is not
    'larger then the total buffer size
    If (vADelta > 0) And (vADelta < bufSize) Then
        'Get data
        BASS_ChannelSetPosition hDA, vALastPos + bufSize - vADelta
        ReDim arr(vADelta)
        'Get the wave data that was not decoded last time
        BASS_ChannelGetData hDA, arr(0), vADelta * 2
        'reBuild the array
        'Move the wave data by vaDelta to the left
        mOff = bufSize - vADelta
        For m = 0 To mOff - 1
            vALastArr(m) = vALastArr(m + vADelta)
        Next
        'Add the new wave data to the end
        For m = mOff To bufSize
            vALastArr(m) = arr(m - mOff)
        Next
        arr = vALastArr
        'Build the graph
        'Calc what size the new graphic data has
        vADeltaGraf = vADelta / bufSize * UBound(GrfA)
        'Move the graphic by DeltaGraph to the left
        For m = 0 To (UBound(GrfA) - vADeltaGraf - 1)
            'Calc median...
            GrfA(m) = GrfA(m + vADeltaGraf)
        Next
        'Add the new graphic data
        For m = (UBound(GrfA) - vADeltaGraf) To UBound(GrfA) - 1
            'Calc median...
            GrfA(m) = (calcAvg(arr, m * avgSize, avgSize, res)
        Next
        'Update "last" variables
        vALastPos = fPos
        vALastSize = bufSize
    Else
        'if not, order the full graphic decoding next time
        vALastPos = 0
    End If
End If

Irrational86

Multiply by 2 because its 16 bits, means 2 bytes...does this explain it??

kchabot

Well... It does explain that you need to double the specified buffer size, but it does not explain while gathering a larger number of samples the wavedata returned gets shrinked by, for example, 2.

Anyway, no mather, this works...

Irrational86