Hi Florian,

On Mon, 27 Jan 2014 01:05:55 +0100
Florian Jung <[email protected]> wrote:

> i have an idea, stolen from ardour.
> 
> there are three threads:
> GUI
> audio
> prefetch
> 
> there is 'the model', containing every information about our song. This
> is shared among GUI and prefetch thread. audio never touches it.
> 
> GUI and prefetch do mutex locking when operationg on the model.
> 
> All data, (also MIDI data), is read from the prefetch thread and written
> into ringbuffers, to be read and played by the audio thread. the audio
> thread does effects etc.

That sounds like a very reasonable approach. Though I'd try to avoid
mutex locks between GUI and prefetch thread, if possible. For me the
prefetch thread is not as time critical as "audio" but it has hard
deadlines, too in order to avoid buffer underruns.

So here is a slightly modified idea in pseudo-code as it's too late for
me to describe it in words. :-) I hope you get the idea despite the
only vaguely C++ like syntax.

  public class Model {
    public:
      boolean changes_allowed() { return this._changes_allowed };
      void start_editing() { this._changes_allowed = False; }
      void finish_editing() { this._changes_allowed = True; }
    private:
      boolean _changes_allowed = True;
  }

  Model* model_active = new Model();  // Used by prefetch thread
  Model* model_edited = new Model();  // Used by GUI thread
  Mutex* model_swap = new Mutex();

Basically there are two copies of the Model. The prefetch thread uses
the object pointed to by "model_active". Changes can only be made by
the GUI but it works on another copy pointed to by "model_edited", akin
to this:

  if (!model_edited.changes_allowed()) {
    return;
  }

  Model* _model = model_edited;
  _model.start_editing();

  // Make changes

  model_swap.acquire_or_wait();
  model_edited = model_active;
  model_active = _model;
  model_swap.release();

  // Send signal to prefetch thread that the pointer changed.
  // The prefetch thread might need to invalidate its current operation
  // and start over again. Buffer underrun may also occur but hopefully
  // less likely because the Model object is not locked while it's
  // being edited.

  // Wait until the prefetch thread has picked up the new pointer

  delete model_edited;
  model_edited = new Model(model_active);
  model_edited.finish_editing();

Dennis

------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today. 
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Lmuse-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmuse-developer

Reply via email to