COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 10-11-2014, 12:50 PM   #1
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 506
Default Displaying a waveform?

I figured I would start a new thread for this since it is a different topic. I'm getting further along with my sampler plugin, and now I'm at the point where I want to try to display a waveform (stored in a vector buffer) with the GUI. I pretty much have no clue where to start with this though. I assume I'll have to inherit from an IControl or something of that sort.

I want to display the waveform, have drag and drop capability, add drag zoom (like Ableton) functionality, and add a slider for where playback in the sample starts. I think eventually I want to layer multi-segment envelopes on top of it too so you can edit volume and filter etc. envelopes with respect to the exact point in the sample.

If anyone at least has some starting tips I would be very grateful!
Alkamist is offline   Reply With Quote
Old 10-13-2014, 12:58 AM   #2
cisdsp
Human being with feelings
 
cisdsp's Avatar
 
Join Date: Mar 2013
Posts: 75
Default

Maybe it helps to get started...
http://stackoverflow.com/questions/2...f-the-wav-file
__________________
Website: CIS DSP Factory
cisdsp is offline   Reply With Quote
Old 03-03-2015, 07:17 AM   #3
stw
Human being with feelings
 
stw's Avatar
 
Join Date: Apr 2012
Posts: 279
Default

Since my goal is the same i simply hijack this thread...
Though the basics are clear to me i can't get my head around a drawing problem.
I want to draw a wave which is available as array. Its address get passed into the IControl by the SetWav function. I can see the wave shortly drawn (only once everytime i start Reaper) and directly jumping back to all zero. Seems as if the mWav pointer is instantly deleted after a first call or something else?

What am i doing wrong? Thanks for helping...


Code:
class DrawWave : public IControl

{
private:
  
  const double *mWav;
  int b,h,mStep;
  IRECT mR;

public:
  
  DrawWave(IPlugBase* pPlug, IRECT pR)
  : IControl(pPlug, pR){
    b = mRECT.R - mRECT.L;
    h = mRECT.B - mRECT.T;
    mR = pR;
    
  }
  void SetWav(const double *wav, int a_size){
    mWav = wav;
    mStep = a_size/b;
  }
  
  bool Draw(IGraphics* pGraphics){
    
    for (int i=0; i<b; i++){
      pGraphics->DrawPoint(&COLOR_RED, i+mRECT.L, mRECT.T + (mWav[i*mStep])* h, 0, false);
    }
    return true;
  }
  
  bool IsDirty() { return true;}
  
};
stw is offline   Reply With Quote
Old 03-03-2015, 09:18 AM   #4
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

My first guess would be that the array isn't available anymore by the time your Draw() method gets called.
Tale is offline   Reply With Quote
Old 03-04-2015, 03:20 AM   #5
stw
Human being with feelings
 
stw's Avatar
 
Join Date: Apr 2012
Posts: 279
Default

Quote:
Originally Posted by Tale View Post
My first guess would be that the array isn't available anymore by the time your Draw() method gets called.
Yes, that's what it seems to be. If i do a memcpy everything draws fine.
Would this be the way to go here? I wanted to avoid memcpy and refeence with pointers to make it faster eventually. Though i even don't know if that would really matter...
stw is offline   Reply With Quote
Old 03-04-2015, 04:08 AM   #6
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

Quote:
Originally Posted by stw View Post
Yes, that's what it seems to be. If i do a memcpy everything draws fine.
Would this be the way to go here? I wanted to avoid memcpy and refeence with pointers to make it faster eventually. Though i even don't know if that would really matter...
I am guessing you call SetWav() from witin ProcessDoubleReplacing()? If so, then remember that ProcessDoubleReplacing() and Draw() are run on different threads, most likely of different priority. ProcessDoubleReplacing() is typically called a couple of hundred times per second, while Draw() is usually called at most 24 times per second. So while your Draw() is still executing there maybe multiple calls to ProcessDoubleReplacing(), so the sample data will no longer be available, and even if it would be it might be inconsistent.

Using memcpy() to copy the data should fix the availability issue, but you might still end up with an inconsistent data set where you draw half the buffer based on an earlier ProcessDoubleReplacing() call, and the other half based on the ongoing ProcessDoubleReplacing(). I guess you could alternate between two buffers to fix this. Also, you might not need to memcpy() in each ProcessDoubleReplacing() call, I guess 24 times per second (or maybe 2x24) should suffice.
Tale is offline   Reply With Quote
Old 03-04-2015, 04:22 AM   #7
stw
Human being with feelings
 
stw's Avatar
 
Join Date: Apr 2012
Posts: 279
Default

Quote:
Originally Posted by Tale View Post
[...]
Using memcpy() to copy the data should fix the availability issue, but you might still end up with an inconsistent data set where you draw half the buffer based on an earlier ProcessDoubleReplacing() call, and the other half based on the ongoing ProcessDoubleReplacing(). I guess you could alternate between two buffers to fix this. Also, you might not need to memcpy() in each ProcessDoubleReplacing() call, I guess 24 times per second (or maybe 2x24) should suffice.
Thanks for helping Tale!
Since i only have to draw from OnParamChange i guess it all will be fine with a memcpy at time.
stw is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 06:03 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.