It is currently Tue Aug 21, 2018 10:35 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 53 posts ]  Go to page Previous  1, 2, 3, 4
Author Message
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Sun Jul 08, 2018 9:08 pm 
Offline
User
User

Joined: Sun Apr 01, 2018 11:26 am
Posts: 75
Yes, I posted a message on the BASS forum and I got this explanation:

Quote:
Comparing the posted waveforms, it looks your one is slightly ahead of the Cool Edit one. I suspect that is because BASS is removing the encoding delay (and padding) from the decoded data while Cool Edit isn't. Which one is correct is probably a matter of opinion but I would say the former is more correct. For example, if you try generating and encoding a sine wave to MP3 with LAME and then load that into Cool Edit, you will probably see a little gap added at the start and end. Those gaps won't be present if you decode the MP3 with BASS because it removes them.


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Wed Aug 08, 2018 8:22 pm 
Offline
User
User

Joined: Sun Apr 01, 2018 11:26 am
Posts: 75
To genius Wilbert: :mrgreen:

I am using your latest assembly code. It's fast but there's still a small delay when I zoom in or zoom out, because every time I need to call BASS_ChannelGetData(). Like this:

Code:
Length = BASS_ChannelSeconds2Bytes(Channel, AfterPos - BeforePos) 
NumSamples.q = Length >> 2
SamplesPerElement = (NumSamples / WaveformXPixels)
BytesPerPixel = SamplesPerElement << 2
*WaveData = AllocateMemory(Length)
 
BASS_ChannelSetPosition(Channel, PosBytes, #BASS_POS_BYTE)   
BASS_ChannelGetData(Channel, *WaveData, Length)

Dim MM.MinMax(NumSamples / SamplesPerElement)
MinMaxScaled(@MM(), SamplesPerElement, *WaveData, NumSamples)
UpdateCanvas(MM())   


There must be a faster way to access the needed waveform-data without calling BASS_ChannelGetData() everytime. Do you have an idea how I can do this?


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Thu Aug 09, 2018 6:37 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3234
Location: Netherlands
Martin Verlaan wrote:
There must be a faster way to access the needed waveform-data without calling BASS_ChannelGetData() everytime. Do you have an idea how I can do this?

The fastest way is to keep the entire song in memory at the maximum zoom-in level and zoom out from there.

It's important in this case to think about what accuracy you need.
Sample accurate means about 10 megabyte of data per minute to store which is quite a lot if you keep the entire song in memory.
If it's enough for you to have an accuracy of about a half or one millisecond per pixel you would have to store much less data and it's faster when zooming.
Once you have that entire song in memory as an array of min/max values, I could write another asm procedure to zoom out from that to the level you want to display (like the entire song).

_________________
MacOS 10.13 High Sierra, PB 5.62 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Thu Aug 09, 2018 8:27 am 
Offline
User
User

Joined: Sun Apr 01, 2018 11:26 am
Posts: 75
wilbert wrote:
Martin Verlaan wrote:
Once you have that entire song in memory as an array of min/max values, I could write another asm procedure to zoom out from that to the level you want to display (like the entire song).


I think the accuracy is only important when zooming in deeply. So I would really appreciate if you could write such procedure (if it's not to much hassle for you)! That would make zooming with the mouse wheel also faster. Thanks in advance!


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Fri Aug 10, 2018 12:54 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3234
Location: Netherlands
Martin Verlaan wrote:
I think the accuracy is only important when zooming in deeply. So I would really appreciate if you could write such procedure (if it's not to much hassle for you)! That would make zooming with the mouse wheel also faster. Thanks in advance!


Can you try if the MMCombine procedure below work for you ?
Code:
Procedure MMCombine(*MMSrc, *MMDst, SrcElements, Combine); SSE
  ; load xor mask into mm2
  !mov eax, 0x807f807f
  !movd mm2, eax
  !punpcklbw mm2, mm2
  ; load *MMSrc and *MMDst pointers
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.p_MMSrc]
    !mov rdx, [p.p_MMDst]
  CompilerElse
    !mov eax, [p.p_MMSrc]
    !mov edx, [p.p_MMDst]
  CompilerEndIf
  !mov ecx, [p.v_Combine]
  ; verify if Combine <= SrcElements
  !.l0:
  !cmp ecx, [p.v_SrcElements]
  !jbe .l1
  ; if not, set Combine to SrcElements
  !mov ecx, [p.v_SrcElements]
  !mov [p.v_Combine], ecx
  !.l1:
  !pxor mm0, mm0
  !test ecx, 1
  !jz .l2
  !add ecx, 1
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !movd mm1, [rax]
    !add rax, 4
  CompilerElse
    !movd mm1, [eax]
    !add eax, 4
  CompilerEndIf
  !pshufw mm1, mm1, 01000100b
  !jmp .l3
  !.l2:
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !movq mm1, [rax]
    !add rax, 8
  CompilerElse
    !movq mm1, [eax]
    !add eax, 8
  CompilerEndIf
  !.l3:
  !pxor mm1, mm2
  !pmaxub mm0, mm1
  !sub ecx, 2
  !jnz .l2
  !pshufw mm1, mm0, 1110b
  !pmaxub mm0, mm1
  !pxor mm0, mm2
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !movd [rdx], mm0
    !add rdx, 4
  CompilerElse
    !movd [edx], mm0
    !add edx, 4
  CompilerEndIf
  !mov ecx, [p.v_Combine]
  !sub [p.v_SrcElements], ecx
  !jnz .l0
  !emms
EndProcedure



; >> Test <<

Structure MinMax
  min.b[2]
  max.b[2]
EndStructure

Dim MM.MinMax(4)
Dim MM_Zoomed.MinMax(2)

MM(0)\min[0] = -5
MM(0)\min[1] = -9
MM(0)\max[0] = 25
MM(0)\max[1] = 75

MM(1)\min[0] = -15
MM(1)\min[1] = -19
MM(1)\max[0] = 45
MM(1)\max[1] = 95

MM(2)\min[0] = -1
MM(2)\min[1] = -89
MM(2)\max[0] = 77
MM(2)\max[1] = 1

MM(3)\min[0] = 0
MM(3)\min[1] = 1
MM(3)\max[0] = 0
MM(3)\max[1] = 3

; Combine 2 MinMax values into 1
MMCombine(@MM(), @MM_Zoomed(), 4, 2)
 
Debug MM_Zoomed(0)\min[0]
Debug MM_Zoomed(0)\min[1]
Debug MM_Zoomed(0)\max[0]
Debug MM_Zoomed(0)\max[1]

Debug MM_Zoomed(1)\min[0]
Debug MM_Zoomed(1)\min[1]
Debug MM_Zoomed(1)\max[0]
Debug MM_Zoomed(1)\max[1]

  • The first procedure argument (*MMSrc) needs to be the address of the source array.
    This would be the array of MinMax values of the entire song in it's most expanded state.
  • The second argument is the address of the destination array.
  • The third argument is the number of elements the source array contains.
  • The last argument is how many source elements to combine into one destination element.

The example in the code above combines two elements into one.

_________________
MacOS 10.13 High Sierra, PB 5.62 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Sat Aug 11, 2018 10:38 am 
Offline
User
User

Joined: Sun Apr 01, 2018 11:26 am
Posts: 75
First of all: Thank you!

Sorry, I find it difficult to understand your explanation.
The way I zoom without your new procedure was like this:

Code:
  PosBytes.q = BASS_ChannelSeconds2Bytes(Channel, BeforePos)
  Length.q = BASS_ChannelSeconds2Bytes(Channel, AfterPos - BeforePos)
  NumSamples.q = Length >> 2
  SamplesPerElement = (NumSamples / WaveformXPixels)
  *WaveData = AllocateMemory(Length)
 
  BASS_ChannelSetPosition(Channel, PosBytes, #BASS_POS_BYTE)   
  BASS_ChannelGetData(Channel, *WaveData, Length)
  Dim MM.MinMax(NumSamples / SamplesPerElement)
  MinMaxScaled(@MM(), SamplesPerElement, *WaveData, NumSamples)
  UpdateCanvas(MM()) 


How can I make above code work with your procedure?


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Sat Aug 11, 2018 11:42 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3234
Location: Netherlands
Martin Verlaan wrote:
How can I make above code work with your procedure?

Unfortunately it's not one simple change.

The main problem is with BASS_ChannelGetData because it has to decode every time. That's why I suggested to store the entire decoded mp3 in memory.
The fastest way is to do that when it comes to working with the data afterwards, is as an array of min/max values but it would also be possible to do it as decoded samples if there's enough memory.
But you probably would have to change your code in other places as well for this to load an entire song and work from that data instead of using BASS_ChannelGetData all the time.
If you don't want to do that, there's still a little room to improve the speed but not much as the most time consuming thing is probably the mp3 decode.

_________________
MacOS 10.13 High Sierra, PB 5.62 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Draw a waveform with Purebasic and BASS library
PostPosted: Sat Aug 11, 2018 2:26 pm 
Offline
User
User

Joined: Sun Apr 01, 2018 11:26 am
Posts: 75
No problem, I'm going to play with it and try to implement it. I don't give up :)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 53 posts ]  Go to page Previous  1, 2, 3, 4

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye