[beast: 41/49] BSE: move PartNote and related Part methods into bseapi.idl



commit d4a56aaa1615da3fa782914bf6db9d012d44dcdc
Author: Tim Janik <timj gnu org>
Date:   Thu Jun 25 01:28:16 2015 +0200

    BSE: move PartNote and related Part methods into bseapi.idl

 beast-gtk/bstpatterncolumns.cc |   32 +++++----
 beast-gtk/bstpianoroll.cc      |   12 ++--
 beast-gtk/bstpianorollctrl.cc  |  123 ++++++++++++++------------------
 beast-gtk/bstpianorollctrl.hh  |    6 +-
 bse/bseapi.idl                 |   28 ++++++++
 bse/bsebasics.idl              |   16 ----
 bse/bseitem.cc                 |    2 +-
 bse/bsepart.cc                 |   91 +++++++++++++++---------
 bse/bsepart.hh                 |    9 ++-
 bse/bsepart.proc               |  151 ----------------------------------------
 bse/bseutils.cc                |   46 ++++---------
 bse/bseutils.hh                |   13 +---
 12 files changed, 186 insertions(+), 343 deletions(-)
---
diff --git a/beast-gtk/bstpatterncolumns.cc b/beast-gtk/bstpatterncolumns.cc
index 5fb78af..179910b 100644
--- a/beast-gtk/bstpatterncolumns.cc
+++ b/beast-gtk/bstpatterncolumns.cc
@@ -94,18 +94,16 @@ pattern_column_note_width_request (BstPatternColumn       *column,
 }
 
 static char
-pattern_column_note_char (BstPatternColumnNote *self,
-                          BsePartNoteSeq       *pseq,
-                          gint                  pos)
+pattern_column_note_char (BstPatternColumnNote *self, const Bse::PartNoteSeq &pseq, int pos)
 {
   BseNoteDescription *ndesc;
-  if (!pseq || !pseq->n_pnotes)
+  if (pseq.size() == 0)
     return '-';
-  else if (pseq->n_pnotes > 1)
+  else if (pseq.size() > 1)
     return '*';
-  /* pseq->n_pnotes == 1 */
-  ndesc = bse_note_describe (BSE_MUSICAL_TUNING_12_TET, /* tuning is irrelevant if we ignore ->freq */
-                             pseq->pnotes[0]->note, pseq->pnotes[0]->fine_tune);
+  // pseq.size() == 1
+  ndesc = bse_note_describe (BSE_MUSICAL_TUNING_12_TET, // tuning is irrelevant if we ignore ->freq
+                             pseq[0].note, pseq[0].fine_tune);
   switch (pos)
     {
     case 0:     return ndesc->upshift ? '#' : ' ';
@@ -133,7 +131,9 @@ pattern_column_note_draw_cell (BstPatternColumn       *column,
   GdkGC *text_gc = gcs[BST_PATTERN_COLUMN_GC_TEXT1];
   GdkGC *draw_gc;
   Bse::PartH part = pview->part;
-  BsePartNoteSeq *pseq = part ? bse_part_list_notes_within (part.proxy_id(), column->num, tick, duration) : 
NULL;
+  Bse::PartNoteSeq pseq;
+  if (part)
+    pseq = part.list_notes_within (column->num, tick, duration);
   gchar ch;
   gint accu, yline;
 
@@ -181,24 +181,26 @@ pattern_column_note_key_event (BstPatternColumn       *column,
 {
   // BstPatternColumnNote *self = (BstPatternColumnNote*) column;
   Bse::PartH part = pview->part;
-  BsePartNoteSeq *pseq = part ? bse_part_list_notes_within (part.proxy_id(), column->num, tick, duration) : 
NULL;
+  Bse::PartNoteSeq pseq;
+  if (part)
+    pseq = part.list_notes_within (column->num, tick, duration);
   guint i, iparam = 0.5 + param;
   switch (action)
     {
     case BST_PATTERN_REMOVE_EVENTS:
       bse_item_group_undo (part.proxy_id(), "Remove Events");
-      for (i = 0; i < pseq->n_pnotes; i++)
-        part.delete_event (pseq->pnotes[i]->id);
+      for (i = 0; i < pseq.size(); i++)
+        part.delete_event (pseq[i].id);
       bse_item_ungroup_undo (part.proxy_id());
       return TRUE;
     case BST_PATTERN_SET_NOTE:
       bse_item_group_undo (part.proxy_id(), "Set Note");
-      if (pseq->n_pnotes == 1)
+      if (pseq.size() == 1)
         {
-          BsePartNote *pnote = pseq->pnotes[0];
+          const Bse::PartNote *pnote = &pseq[0];
           part.change_note (pnote->id, pnote->tick, pnote->duration, SFI_NOTE_CLAMP (iparam), 
pnote->fine_tune, pnote->velocity);
         }
-      else if (pseq->n_pnotes <= 1)
+      else if (pseq.size() <= 1)
         part.insert_note (column->num, tick, duration, SFI_NOTE_CLAMP (iparam), 0, +1);
       else
         bst_gui_error_bell (pview);
diff --git a/beast-gtk/bstpianoroll.cc b/beast-gtk/bstpianoroll.cc
index 9455230..81b2572 100644
--- a/beast-gtk/bstpianoroll.cc
+++ b/beast-gtk/bstpianoroll.cc
@@ -692,7 +692,6 @@ bst_piano_roll_draw_canvas (GxkScrollCanvas *scc,
   BstPianoRoll *self = BST_PIANO_ROLL (scc);
   GdkGC *dark_gc = STYLE (self)->dark_gc[GTK_STATE_NORMAL];
   gint pass, dlen, width, height, line_width = 0; /* line widths != 0 interfere with dash-settings on some X 
servers */
-  BsePartNoteSeq *pseq;
   GXK_SCROLL_CANVAS_CLASS (bst_piano_roll_parent_class)->draw_canvas (scc, drawable, area);
   gdk_window_get_size (drawable, &width, &height);
 
@@ -788,12 +787,13 @@ bst_piano_roll_draw_canvas (GxkScrollCanvas *scc,
 
   /* draw notes */
   dark_gc = STYLE (self)->dark_gc[GTK_STATE_NORMAL];
-  pseq = self->part ? bse_part_list_notes_crossing (self->part.proxy_id(),
-                                                    coord_to_tick (self, area->x, FALSE),
-                                                    coord_to_tick (self, area->x + area->width, FALSE)) : 
NULL;
-  for (uint i = 0; pseq && i < pseq->n_pnotes; i++)
+  Bse::PartNoteSeq pseq;
+  if (self->part)
+    pseq = self->part.list_notes_crossing (coord_to_tick (self, area->x, false),
+                                           coord_to_tick (self, area->x + area->width, false));
+  for (size_t i = 0; i < pseq.size(); i++)
     {
-      BsePartNote *pnote = pseq->pnotes[i];
+      const Bse::PartNote *pnote = &pseq[i];
       gint semitone = SFI_NOTE_SEMITONE (pnote->note);
       guint start = pnote->tick, end = start + pnote->duration;
       GdkGC *xdark_gc, *xlight_gc, *xnote_gc;
diff --git a/beast-gtk/bstpianorollctrl.cc b/beast-gtk/bstpianorollctrl.cc
index 5a82b70..db283eb 100644
--- a/beast-gtk/bstpianorollctrl.cc
+++ b/beast-gtk/bstpianorollctrl.cc
@@ -23,7 +23,7 @@ static void   controller_update_canvas_cursor         (BstPianoRollController *sel
 
 
 /* --- variables --- */
-static BsePartNoteSeq *clipboard_pseq = NULL;
+static Bse::PartNoteSeq *clipboard_pseq = NULL;
 
 /* --- actions --- */
 enum {
@@ -134,16 +134,16 @@ bst_piano_roll_controller_quant_actions (BstPianoRollController *self)
 }
 
 void
-bst_piano_roll_controller_set_clipboard (BsePartNoteSeq *pseq)
+bst_piano_roll_controller_set_clipboard (const Bse::PartNoteSeq *pseq)
 {
   if (clipboard_pseq)
-    bse_part_note_seq_free (clipboard_pseq);
-  clipboard_pseq = pseq && pseq->n_pnotes ? bse_part_note_seq_copy_shallow (pseq) : NULL;
+    delete clipboard_pseq;
+  clipboard_pseq = pseq->size() > 0 ? new Bse::PartNoteSeq (*pseq) : NULL;
   if (clipboard_pseq)
     bst_event_roll_controller_set_clipboard (Bse::PartControlSeq());
 }
 
-BsePartNoteSeq*
+Bse::PartNoteSeq*
 bst_piano_roll_controller_get_clipboard (void)
 {
   return clipboard_pseq;
@@ -242,10 +242,9 @@ bst_piano_roll_controller_exec_action (BstPianoRollController *self,
                                        gulong                  action_id)
 {
   Bse::PartH part = self->proll->part;
+  Bse::PartNoteSeq pseq;
   switch (action_id)
     {
-      BsePartNoteSeq *pseq;
-      guint i;
     case ACTION_SELECT_ALL:
       part.select_notes (0, self->proll->max_ticks, self->proll->min_note, self->proll->max_note);
       break;
@@ -253,11 +252,11 @@ bst_piano_roll_controller_exec_action (BstPianoRollController *self,
       part.deselect_notes (0, self->proll->max_ticks, self->proll->min_note, self->proll->max_note);
       break;
     case ACTION_SELECT_INVERT:
-      pseq = bse_part_list_selected_notes (part.proxy_id());
+      pseq = part.list_selected_notes();
       part.select_notes (0, self->proll->max_ticks, self->proll->min_note, self->proll->max_note);
-      for (i = 0; i < pseq->n_pnotes; i++)
+      for (size_t i = 0; i < pseq.size(); i++)
         {
-          BsePartNote *pnote = pseq->pnotes[i];
+          const Bse::PartNote *pnote = &pseq[i];
           part.deselect_event (pnote->id);
         }
       break;
@@ -343,15 +342,13 @@ piano_canvas_button_tool (BstPianoRollController *self,
 void
 bst_piano_roll_controller_clear (BstPianoRollController *self)
 {
-  BsePartNoteSeq *pseq;
-
   g_return_if_fail (self != NULL);
   Bse::PartH part = self->proll->part;
-  pseq = bse_part_list_selected_notes (part.proxy_id());
+  Bse::PartNoteSeq pseq = part.list_selected_notes();
   bse_item_group_undo (part.proxy_id(), "Clear Selection");
-  for (size_t i = 0; i < pseq->n_pnotes; i++)
+  for (size_t i = 0; i < pseq.size(); i++)
     {
-      BsePartNote *pnote = pseq->pnotes[i];
+      const Bse::PartNote *pnote = &pseq[i];
       part.delete_event (pnote->id);
     }
   bse_item_ungroup_undo (part.proxy_id());
@@ -363,14 +360,14 @@ bst_piano_roll_controller_cut (BstPianoRollController *self)
   g_return_if_fail (self != NULL);
 
   Bse::PartH part = self->proll->part;
-  BsePartNoteSeq *pseq = bse_part_list_selected_notes (part.proxy_id());
+  Bse::PartNoteSeq pseq = part.list_selected_notes();
   bse_item_group_undo (part.proxy_id(), "Cut Selection");
-  for (size_t i = 0; i < pseq->n_pnotes; i++)
+  for (size_t i = 0; i < pseq.size(); i++)
     {
-      BsePartNote *pnote = pseq->pnotes[i];
+      const Bse::PartNote *pnote = &pseq[i];
       part.delete_event (pnote->id);
     }
-  bst_piano_roll_controller_set_clipboard (pseq);
+  bst_piano_roll_controller_set_clipboard (&pseq);
   bse_item_ungroup_undo (part.proxy_id());
 }
 
@@ -380,9 +377,9 @@ bst_piano_roll_controller_copy (BstPianoRollController *self)
   g_return_val_if_fail (self != NULL, FALSE);
 
   Bse::PartH part = self->proll->part;
-  BsePartNoteSeq *pseq = bse_part_list_selected_notes (part.proxy_id());
-  bst_piano_roll_controller_set_clipboard (pseq);
-  return pseq && pseq->n_pnotes;
+  Bse::PartNoteSeq pseq = part.list_selected_notes();
+  bst_piano_roll_controller_set_clipboard (&pseq);
+  return pseq.size() > 0;
 }
 
 void
@@ -391,7 +388,7 @@ bst_piano_roll_controller_paste (BstPianoRollController *self)
   g_return_if_fail (self != NULL);
 
   Bse::PartH part = self->proll->part;
-  BsePartNoteSeq *pseq = bst_piano_roll_controller_get_clipboard ();
+  Bse::PartNoteSeq *pseq = bst_piano_roll_controller_get_clipboard ();
   if (pseq)
     {
       guint i, paste_tick, ctick = self->proll->max_ticks;
@@ -401,16 +398,16 @@ bst_piano_roll_controller_paste (BstPianoRollController *self)
       part.deselect_notes (0, self->proll->max_ticks, self->proll->min_note, self->proll->max_note);
       bst_piano_roll_get_paste_pos (self->proll, &paste_tick, &paste_note);
       paste_tick = bst_piano_roll_controller_quantize (self, paste_tick);
-      for (i = 0; i < pseq->n_pnotes; i++)
+      for (i = 0; i < pseq->size(); i++)
        {
-         BsePartNote *pnote = pseq->pnotes[i];
+          const Bse::PartNote *pnote = &(*pseq)[i];
          ctick = MIN (ctick, uint (pnote->tick));
          cnote = MAX (cnote, pnote->note);
        }
       cnote = paste_note - cnote;
-      for (i = 0; i < pseq->n_pnotes; i++)
+      for (i = 0; i < pseq->size(); i++)
        {
-         BsePartNote *pnote = pseq->pnotes[i];
+          const Bse::PartNote *pnote = &(*pseq)[i];
          guint id;
          gint note;
          note = pnote->note + cnote;
@@ -427,8 +424,8 @@ bst_piano_roll_controller_paste (BstPianoRollController *self)
 gboolean
 bst_piano_roll_controller_clipboard_full (BstPianoRollController *self)
 {
-  BsePartNoteSeq *pseq = bst_piano_roll_controller_get_clipboard ();
-  return pseq && pseq->n_pnotes;
+  Bse::PartNoteSeq *pseq = bst_piano_roll_controller_get_clipboard ();
+  return pseq && pseq->size() > 0;
 }
 
 gboolean
@@ -441,8 +438,8 @@ bst_piano_roll_controller_has_selection (BstPianoRollController *self,
       if (part)
         {
           self->cached_stamp = action_stamp;
-          BsePartNoteSeq *pseq = bse_part_list_selected_notes (part.proxy_id());
-          self->cached_n_notes = pseq->n_pnotes;
+          Bse::PartNoteSeq pseq = part.list_selected_notes();
+          self->cached_n_notes = pseq.size();
         }
       else
         self->cached_n_notes = 0;
@@ -506,28 +503,22 @@ controller_update_canvas_cursor (BstPianoRollController *self,
 }
 
 static gboolean
-check_hoverlap (SfiProxy part,
-               guint    tick,
-               guint    duration,
-               gint     note,
-               guint    except_tick,
-               guint    except_duration)
+check_hoverlap (Bse::PartH part, uint tick, uint duration, int note, uint except_tick, uint except_duration)
 {
   if (duration)
     {
-      BsePartNoteSeq *pseq = bse_part_check_overlap (part, tick, duration, note);
-      BsePartNote *pnote;
-
-      if (pseq->n_pnotes == 0)
-       return FALSE;     /* no overlap */
-      if (pseq->n_pnotes > 1)
-       return TRUE;      /* definite overlap */
-      pnote = pseq->pnotes[0];
+      Bse::PartNoteSeq pseq = part.check_overlap (tick, duration, note);
+
+      if (pseq.size() == 0)
+       return false;   // no overlap
+      if (pseq.size() > 1)
+       return true;    // definitly overlaps
+      const Bse::PartNote *pnote = &pseq[0];
       if (uint (pnote->tick) == except_tick &&
          uint (pnote->duration) == except_duration)
-       return FALSE;     /* overlaps with exception */
+       return false;   // overlaps with exception
     }
-  return TRUE;
+  return true;
 }
 
 static void
@@ -542,7 +533,7 @@ move_start (BstPianoRollController *self,
       gxk_status_set (GXK_STATUS_WAIT, _("Move Note"), NULL);
       drag->state = GXK_DRAG_CONTINUE;
       if (part.is_event_selected (self->obj_id))
-       self->sel_pseq = bse_part_note_seq_copy_shallow (bse_part_list_selected_notes (part.proxy_id()));
+        self->sel_pseq = part.list_selected_notes();
     }
   else
     {
@@ -566,9 +557,9 @@ move_group_motion (BstPianoRollController *self, BstPianoRollDrag *drag)
   delta_tick -= new_tick;
   delta_note -= new_note;
   bse_item_group_undo (part.proxy_id(), "Move Selection");
-  for (uint i = 0; i < self->sel_pseq->n_pnotes; i++)
+  for (size_t i = 0; i < self->sel_pseq.size(); i++)
     {
-      BsePartNote *pnote = self->sel_pseq->pnotes[i];
+      const Bse::PartNote *pnote = &self->sel_pseq[i];
       gint tick = pnote->tick;
       gint note = pnote->note;
       note -= delta_note;
@@ -576,10 +567,7 @@ move_group_motion (BstPianoRollController *self, BstPianoRollDrag *drag)
                         SFI_NOTE_CLAMP (note), pnote->fine_tune, pnote->velocity);
     }
   if (drag->type == GXK_DRAG_DONE)
-    {
-      bse_part_note_seq_free (self->sel_pseq);
-      self->sel_pseq = NULL;
-    }
+    self->sel_pseq.clear();
   bse_item_ungroup_undo (part.proxy_id());
 }
 
@@ -590,7 +578,7 @@ move_motion (BstPianoRollController *self,
   Bse::PartH part = self->proll->part;
   bool note_changed;
 
-  if (self->sel_pseq)
+  if (self->sel_pseq.size() > 0)
     {
       move_group_motion (self, drag);
       return;
@@ -600,7 +588,7 @@ move_motion (BstPianoRollController *self,
   new_tick = bst_piano_roll_controller_quantize (self, new_tick);
   note_changed = self->obj_note != drag->current_note;
   if ((uint (new_tick) != self->obj_tick || note_changed) &&
-      !check_hoverlap (part.proxy_id(), new_tick, self->obj_duration, drag->current_note,
+      !check_hoverlap (part, new_tick, self->obj_duration, drag->current_note,
                       self->obj_tick, note_changed ? 0 : self->obj_duration))
     {
       bse_item_group_undo (part.proxy_id(), "Move Note");
@@ -623,11 +611,7 @@ static void
 move_abort (BstPianoRollController *self,
            BstPianoRollDrag       *drag)
 {
-  if (self->sel_pseq)
-    {
-      bse_part_note_seq_free (self->sel_pseq);
-      self->sel_pseq = NULL;
-    }
+  self->sel_pseq.clear();
   gxk_status_set (GXK_STATUS_ERROR, _("Move Note"), _("Lost Note"));
 }
 
@@ -671,7 +655,7 @@ resize_motion (BstPianoRollController *self,
 
   /* apply new note size */
   if ((self->obj_tick != new_tick || new_duration != self->obj_duration) &&
-      !check_hoverlap (part.proxy_id(), new_tick, new_duration, self->obj_note,
+      !check_hoverlap (part, new_tick, new_duration, self->obj_note,
                       self->obj_tick, self->obj_duration))
     {
       bse_item_group_undo (part.proxy_id(), "Resize Note");
@@ -727,7 +711,7 @@ insert_start (BstPianoRollController *self,
     {
       guint qtick = bst_piano_roll_controller_quantize (self, drag->start_tick);
       guint duration = drag->proll->ppqn * 4 / NOTE_LENGTH (self);
-      if (check_hoverlap (part.proxy_id(), qtick, duration, drag->start_note, 0, 0))
+      if (check_hoverlap (part, qtick, duration, drag->start_note, 0, 0))
        error = Bse::ERROR_INVALID_OVERLAP;
       else
        {
@@ -844,14 +828,13 @@ controller_canvas_drag (BstPianoRollController *self,
   if (drag->type == GXK_DRAG_START)
     {
       BstCommonRollTool tool = BST_COMMON_ROLL_TOOL_NONE;
-      BsePartNoteSeq *pseq;
 
       /* setup drag data */
       Bse::PartH part = drag->proll->part;
-      pseq = bse_part_get_notes (part.proxy_id(), drag->start_tick, drag->start_note);
-      if (pseq->n_pnotes)
+      Bse::PartNoteSeq pseq = part.get_notes (drag->start_tick, drag->start_note);
+      if (pseq.size() > 0)
        {
-         BsePartNote *pnote = pseq->pnotes[0];
+         const Bse::PartNote *pnote = &pseq[0];
          self->obj_id = pnote->id;
          self->obj_tick = pnote->tick;
          self->obj_duration = pnote->duration;
@@ -868,9 +851,9 @@ controller_canvas_drag (BstPianoRollController *self,
          self->obj_fine_tune = 0;
          self->obj_velocity = 0;
        }
-      if (self->sel_pseq)
-       g_warning ("leaking old drag selection (%p)", self->sel_pseq);
-      self->sel_pseq = NULL;
+      if (self->sel_pseq.size())
+       g_warning ("leaking old drag selection (%zu)", self->sel_pseq.size());
+      self->sel_pseq.clear();
       self->xoffset = 0;
       self->tick_bound = 0;
 
diff --git a/beast-gtk/bstpianorollctrl.hh b/beast-gtk/bstpianorollctrl.hh
index 6391e9f..35b122d 100644
--- a/beast-gtk/bstpianorollctrl.hh
+++ b/beast-gtk/bstpianorollctrl.hh
@@ -16,7 +16,7 @@ typedef struct {
   gfloat           obj_velocity;
   guint                   xoffset;
   guint                   tick_bound;
-  BsePartNoteSeq  *sel_pseq;
+  Bse::PartNoteSeq sel_pseq;
   /* tool data */
   guint                   tool_index;
   /* tool selections */
@@ -35,8 +35,8 @@ BstPianoRollController*       bst_piano_roll_controller_ref            
(BstPianoRollController
 void                   bst_piano_roll_controller_unref          (BstPianoRollController *self);
 guint                   bst_piano_roll_controller_quantize       (BstPianoRollController *self,
                                                                  guint                    fine_tick);
-void                   bst_piano_roll_controller_set_clipboard  (BsePartNoteSeq         *pseq);
-BsePartNoteSeq*                bst_piano_roll_controller_get_clipboard  (void);
+void                   bst_piano_roll_controller_set_clipboard  (const Bse::PartNoteSeq *pseq);
+Bse::PartNoteSeq*      bst_piano_roll_controller_get_clipboard  (void);
 GxkActionList*          bst_piano_roll_controller_select_actions (BstPianoRollController *self);
 GxkActionList*          bst_piano_roll_controller_canvas_actions (BstPianoRollController *self);
 GxkActionList*          bst_piano_roll_controller_note_actions   (BstPianoRollController *self);
diff --git a/bse/bseapi.idl b/bse/bseapi.idl
index d7b85c6..734eeac 100644
--- a/bse/bseapi.idl
+++ b/bse/bseapi.idl
@@ -322,6 +322,23 @@ interface Item : Object {
   Item common_ancestor (Item other);    ///< Find a common container (parent or grand-parent) of two items 
if any.
 };
 
+/// Part specific note event representation.
+record PartNote
+{
+  int32   id        = Num ("ID", "", 0, ":readwrite");
+  int32   channel   = Range ("Channel", "", ":readwrite", 0, MAXINT31, 1);
+  int32   tick      = Range ("Tick", "", ":readwrite", 0, MAXINT31, 1);
+  int32   duration  = Range ("Duration", "Duration in number of ticks", ":readwrite", 0, MAXINT31, 1);
+  int32   note      = Range ("Note", "", NOTEHINTS, MIN_NOTE, MAX_NOTE, 12, KAMMER_NOTE);
+  int32   fine_tune = Range ("Fine Tune", "", FINETUNEHINTS, MIN_FINE_TUNE, MAX_FINE_TUNE, 1);
+  float64 velocity  = Range ("Velocity", "", VELOCITYHINTS, 0, 1.0, 0.1, 1);
+  bool    selected  = Bool ("Selected", "", ":readwrite", false);
+};
+/// A list of part note events.
+sequence PartNoteSeq {
+  PartNote part_notes;
+};
+
 /// Part specific control event representation.
 record PartControl {
   int32          id           = Num ("ID", "", ":readwrite");
@@ -361,6 +378,17 @@ interface Part : Item {
   void           deselect_notes            (int32 tick, int32 duration, int32 min_note, int32 max_note); 
///< Deselect all notes within rectangle.
   void           deselect_event            (int32 id); ///< Deselect an existing event.
   void           deselect_controls         (int32 tick, int32 duration, MidiSignalType control_type); ///< 
Deselect all controls within given range.
+  PartNoteSeq list_notes_crossing (int32 tick, int32 duration); ///< List all notes within or crossing a 
tick range.
+  PartNoteSeq list_notes_within   (int32 channel, int32 tick, int32 duration); ///< List all notes within a 
tick range.
+  PartNoteSeq list_selected_notes (); ///< List all currently selected notes.
+  PartNoteSeq check_overlap       (int32 tick, int32 duration, int32 note); ///< Check whether a note would 
overlap with neighbours.
+  PartNoteSeq get_notes           (int32 tick, int32 note); ///< Retrieve all notes at a specific frequency 
or crossing a tick.
+
+  // SongTiming     get_timing                (int32 tick); ///< Retrieve song timing information at a 
specific tick.
+  // signal void    range_changed             (int32 a, int32 b, int32 c, int32 d);
+  // signal void    links_changed             ();
+  // property int32 n_channels;
+  // property int32 last_tick;
 };
 
 /// Base type for synthesis objects with input or output streams.
diff --git a/bse/bsebasics.idl b/bse/bsebasics.idl
index 69fbae0..d0658b2 100644
--- a/bse/bsebasics.idl
+++ b/bse/bsebasics.idl
@@ -336,22 +336,6 @@ record PropertyCandidates {
   ItemSeq items;
   TypeSeq partitions = SfiSeq ("Type Partitions", "List of types which may logically partition the list of 
items by type discrimination", STANDARD);
 };
-record PartNote
-{
-  Info     blurb        = "Part specific note representation";
-  Int      id           = SfiUInt ("ID", "", 0, ":readwrite");
-  Int      channel      = SfiInt ("Channel", "", 0, 0, MAXINT, 1, ":readwrite");
-  Int      tick         = SfiInt ("Tick", "", 0, 0, MAXINT, 1, ":readwrite");
-  Int      duration     = SfiInt ("Duration", "Duration in number of ticks", 0, 0, MAXINT, 1, ":readwrite");
-  Int      note         = Note ("Note", "", KAMMER_NOTE, ":readwrite");
-  Int      fine_tune    = SfiInt ("Fine Tune", "", 0, MIN_FINE_TUNE, MAX_FINE_TUNE, 1, ":readwrite");
-  Real     velocity     = SfiReal ("Velocity", "", 1, 0, 1.0, 0.1, ":readwrite");
-  Bool     selected     = SfiBool ("Selected", "", FALSE, ":readwrite");
-};
-sequence PartNoteSeq {
-  Info     blurb = "A list of part notes";
-  PartNote pnotes;
-};
 record NoteDescription
 {
   MusicalTuningType musical_tuning;
diff --git a/bse/bseitem.cc b/bse/bseitem.cc
index 9a44225..1957725 100644
--- a/bse/bseitem.cc
+++ b/bse/bseitem.cc
@@ -1284,7 +1284,7 @@ void
 ItemImpl::push_undo (const String &blurb, const UndoErrorLambda &lambda)
 {
   UndoVoidLambda void_lambda = [blurb, lambda] (ItemImpl &item) {
-    Bse::ErrorType error = lambda (item);
+    const Bse::ErrorType error = lambda (item);
     if (error) // undo errors shouldn't happen
       g_warning ("error during undo '%s' of item %s: %s", blurb.c_str(),
                  item.debug_name().c_str(), bse_error_blurb (error));
diff --git a/bse/bsepart.cc b/bse/bsepart.cc
index 8a6fdb9..cf1d1df 100644
--- a/bse/bsepart.cc
+++ b/bse/bsepart.cc
@@ -1039,8 +1039,7 @@ bse_part_change_control (BsePart           *self,
 }
 
 static inline gfloat
-note_get_control_value (BsePartEventNote *note,
-                        Bse::MidiSignalType ctype)
+note_get_control_value (const BsePartEventNote *note, Bse::MidiSignalType ctype)
 {
   switch (ctype)
     {
@@ -1123,29 +1122,21 @@ bse_part_query_event (BsePart           *self,
 }
 
 static void
-part_note_seq_append (BsePartNoteSeq   *pseq,
-                      guint             channel,
-                      BsePartEventNote *note)
+part_note_seq_append (Bse::PartNoteSeq &pseq, uint channel, const BsePartEventNote *note)
 {
-  BsePartNote *pnote = bse_part_note (note->id,
-                                      channel,
-                                      note->tick,
-                                      note->duration,
-                                      note->note,
-                                      note->fine_tune,
-                                      note->velocity,
-                                      note->selected);
-  bse_part_note_seq_take_append (pseq, pnote);
+  const Bse::PartNote pnote = bse_part_note (note->id, channel, note->tick, note->duration, note->note,
+                                             note->fine_tune, note->velocity, note->selected);
+  pseq.push_back (pnote);
 }
 
 static void
-part_control_seq_append_note (Bse::PartControlSeq &cseq, BsePartEventNote *note, Bse::MidiSignalType ctype)
+part_control_seq_append_note (Bse::PartControlSeq &cseq, const BsePartEventNote *note, Bse::MidiSignalType 
ctype)
 {
   Bse::PartControl pctrl = bse_part_control (note->id, note->tick, ctype, note_get_control_value (note, 
ctype), note->selected);
   cseq.push_back (pctrl);
 }
 
-BsePartNoteSeq*
+Bse::PartNoteSeq
 bse_part_list_notes (BsePart *self,
                      guint    match_channel,
                      guint    tick,
@@ -1154,17 +1145,14 @@ bse_part_list_notes (BsePart *self,
                      gint     max_note,
                      gboolean include_crossings)
 {
-  BsePartEventNote *bound, *note;
-  BsePartNoteSeq *pseq;
-  guint n, j, channel;
-  gulong *ids;
+  Bse::PartNoteSeq pseq;
 
-  g_return_val_if_fail (BSE_IS_PART (self), NULL);
-  g_return_val_if_fail (tick < BSE_PART_MAX_TICK, NULL);
-  g_return_val_if_fail (duration > 0 && duration <= BSE_PART_MAX_TICK, NULL);
+  g_return_val_if_fail (BSE_IS_PART (self), pseq);
+  g_return_val_if_fail (tick < BSE_PART_MAX_TICK, pseq);
+  g_return_val_if_fail (duration > 0 && duration <= BSE_PART_MAX_TICK, pseq);
 
-  pseq = bse_part_note_seq_new ();
-  for (channel = 0; channel < self->n_channels; channel++)
+  BsePartEventNote *bound, *note;
+  for (size_t channel = 0; channel < self->n_channels; channel++)
     {
       SfiUPool *tickpool;
       if (channel != match_channel && match_channel != ~uint (0))
@@ -1173,7 +1161,7 @@ bse_part_list_notes (BsePart *self,
       /* gather notes spanning across tick */
       note = include_crossings ? bse_part_note_channel_lookup_lt (&self->channels[channel], tick) : NULL;
       if (note)
-        for (j = 0; j < BSE_PART_NOTE_N_CROSSINGS (note); j++)
+        for (size_t j = 0; j < BSE_PART_NOTE_N_CROSSINGS (note); j++)
           {
             BsePartEventNote *xnote = bse_part_note_channel_lookup (&self->channels[channel],
                                                                     BSE_PART_NOTE_CROSSING (note, j));
@@ -1194,9 +1182,10 @@ bse_part_list_notes (BsePart *self,
           note++;
         }
       /* add notes to sequence */
-      ids = sfi_upool_list (tickpool, &n);
+      guint n = 0;
+      gulong *ids = sfi_upool_list (tickpool, &n);
       sfi_upool_destroy (tickpool);
-      for (j = 0; j < n; j++)
+      for (size_t j = 0; j < n; j++)
         {
           note = bse_part_note_channel_lookup (&self->channels[channel], ids[j]);
           part_note_seq_append (pseq, channel, note);
@@ -1294,16 +1283,13 @@ bse_part_queue_notes_within (BsePart *self,
   queue_update (self, tick, end_tick - tick, max_note);
 }
 
-BsePartNoteSeq*
+Bse::PartNoteSeq
 bse_part_list_selected_notes (BsePart *self)
 {
-  BsePartNoteSeq *pseq;
-  guint channel;
-
-  g_return_val_if_fail (BSE_IS_PART (self), NULL);
+  Bse::PartNoteSeq pseq;
+  g_return_val_if_fail (BSE_IS_PART (self), pseq);
 
-  pseq = bse_part_note_seq_new ();
-  for (channel = 0; channel < self->n_channels; channel++)
+  for (size_t channel = 0; channel < self->n_channels; channel++)
     {
       BsePartEventNote *note = bse_part_note_channel_lookup_ge (&self->channels[channel], 0);
       BsePartEventNote *bound = note ? bse_part_note_channel_get_bound (&self->channels[channel]) : NULL;
@@ -2097,6 +2083,41 @@ PartImpl::PartImpl (BseObject *bobj) :
 PartImpl::~PartImpl ()
 {}
 
+PartNoteSeq
+PartImpl::list_notes_crossing (int tick, int duration)
+{
+  BsePart *self = as<BsePart*>();
+  return bse_part_list_notes (self, ~uint (0), tick, duration, BSE_MIN_NOTE, BSE_MAX_NOTE, true);
+}
+
+PartNoteSeq
+PartImpl::list_notes_within (int channel, int tick, int duration)
+{
+  BsePart *self = as<BsePart*>();
+  return bse_part_list_notes (self, channel, tick, duration, BSE_MIN_NOTE, BSE_MAX_NOTE, false);
+}
+
+PartNoteSeq
+PartImpl::list_selected_notes ()
+{
+  BsePart *self = as<BsePart*>();
+  return bse_part_list_selected_notes (self);
+}
+
+PartNoteSeq
+PartImpl::check_overlap (int tick, int duration, int note)
+{
+  BsePart *self = as<BsePart*>();
+  return bse_part_list_notes (self, ~uint (0), tick, duration, note, note, true);
+}
+
+PartNoteSeq
+PartImpl::get_notes (int tick, int note)
+{
+  BsePart *self = as<BsePart*>();
+  return bse_part_list_notes (self, ~uint (0), tick, 1, note, note, true);
+}
+
 PartControlSeq
 PartImpl::list_controls (int tick, int duration, MidiSignalType control_type)
 {
diff --git a/bse/bsepart.hh b/bse/bsepart.hh
index 2f5ade7..737dac0 100644
--- a/bse/bsepart.hh
+++ b/bse/bsepart.hh
@@ -92,7 +92,7 @@ gboolean           bse_part_change_control            (BsePart           *self,
                                                        guint              tick,
                                                        Bse::MidiSignalType  ctype,
                                                        gfloat             value);
-BsePartNoteSeq*    bse_part_list_notes                (BsePart           *self,
+Bse::PartNoteSeq   bse_part_list_notes                (BsePart           *self,
                                                        guint              channel,
                                                        guint              tick,
                                                        guint              duration,
@@ -110,7 +110,7 @@ void               bse_part_queue_notes_within        (BsePart           *self,
                                                        gint               min_note,
                                                        gint               max_note);
 #define            bse_part_queue_controls(p,t,d)          bse_part_queue_notes_within (p, t, d, 
BSE_MIN_NOTE, BSE_MAX_NOTE)
-BsePartNoteSeq*    bse_part_list_selected_notes       (BsePart           *self);
+Bse::PartNoteSeq    bse_part_list_selected_notes      (BsePart           *self);
 Bse::PartControlSeq bse_part_list_selected_controls  (BsePart *self, Bse::MidiSignalType ctype);
 void               bse_part_select_notes              (BsePart           *self,
                                                        guint              channel,
@@ -273,6 +273,11 @@ protected:
   virtual               ~PartImpl               ();
 public:
   explicit               PartImpl               (BseObject*);
+  virtual PartNoteSeq    list_notes_crossing    (int tick, int duration) override;
+  virtual PartNoteSeq    list_notes_within      (int channel, int tick, int duration) override;
+  virtual PartNoteSeq    list_selected_notes    () override;
+  virtual PartNoteSeq    check_overlap          (int tick, int duration, int note) override;
+  virtual PartNoteSeq    get_notes              (int tick, int note) override;
   virtual PartControlSeq list_selected_controls (MidiSignalType control_type) override;
   virtual PartControlSeq list_controls          (int tick, int duration, MidiSignalType control_type) 
override;
   virtual PartControlSeq get_channel_controls   (int channel, int tick, int duration, MidiSignalType 
control_type) override;
diff --git a/bse/bsepart.proc b/bse/bsepart.proc
index b4e77e9..bd8155b 100644
--- a/bse/bsepart.proc
+++ b/bse/bsepart.proc
@@ -10,157 +10,6 @@ AUTHORS     = "Tim Janik <timj gtk org>";
 LICENSE = "GNU Lesser General Public License";
 
 
-METHOD (BsePart, list-notes-crossing) {
-  HELP = "List all notes within or crossing a tick range.";
-  IN   = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("tick", "Start Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("duration", "Tick Duration", NULL,
-                        1, 1, BSE_PART_MAX_TICK, 384, SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("note_list", "Note List", NULL,
-                               BSE_TYPE_PART_NOTE_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BsePart *self = (BsePart*) bse_value_get_object (in_values++);
-  guint    tick            = sfi_value_get_int (in_values++);
-  guint    duration = sfi_value_get_int (in_values++);
-
-  /* check parameters */
-  if (!BSE_IS_PART (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  bse_value_take_boxed (out_values++, bse_part_list_notes (self, ~0, tick, duration, BSE_MIN_NOTE, 
BSE_MAX_NOTE, TRUE));
-
-  return Bse::ERROR_NONE;
-}
-
-METHOD (BsePart, list-notes-within) {
-  HELP = "List all notes within a tick range.";
-  IN   = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("channel", "Channel", NULL,
-                        0, 0, BSE_PART_MAX_CHANNELS, 4, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("tick", "Start Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("duration", "Tick Duration", NULL,
-                        1, 1, BSE_PART_MAX_TICK, 384, SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("note_list", "Note List", NULL,
-                               BSE_TYPE_PART_NOTE_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BsePart *self = (BsePart*) bse_value_get_object (in_values++);
-  guint    channel  = sfi_value_get_int (in_values++);
-  guint    tick            = sfi_value_get_int (in_values++);
-  guint    duration = sfi_value_get_int (in_values++);
-
-  /* check parameters */
-  if (!BSE_IS_PART (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  bse_value_take_boxed (out_values++, bse_part_list_notes (self, channel, tick, duration, BSE_MIN_NOTE, 
BSE_MAX_NOTE, FALSE));
-
-  return Bse::ERROR_NONE;
-}
-
-
-METHOD (BsePart, list-selected-notes) {
-  HELP = "List all currently selected notes.";
-  IN   = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("note_list", "Note List", NULL,
-                               BSE_TYPE_PART_NOTE_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BsePart *self = (BsePart*) bse_value_get_object (in_values++);
-
-  /* check parameters */
-  if (!BSE_IS_PART (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  bse_value_take_boxed (out_values++, bse_part_list_selected_notes (self));
-
-  return Bse::ERROR_NONE;
-}
-
-
-METHOD (BsePart, check-overlap) {
-  HELP = "Check whether a note would overlap with neighbours.";
-  IN   = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("tick", "Start Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("duration", "Tick Duration", NULL,
-                        1, 0, BSE_PART_MAX_TICK, 384, SFI_PARAM_STANDARD);
-  IN   = bse_pspec_note_simple ("note", "Note", NULL, SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("note_list", "Note List", NULL,
-                               BSE_TYPE_PART_NOTE_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BsePart *self = (BsePart*) bse_value_get_object (in_values++);
-  guint    tick            = sfi_value_get_int (in_values++);
-  guint    duration = sfi_value_get_int (in_values++);
-  gint     note     = sfi_value_get_note (in_values++);
-
-  /* check parameters */
-  if (!BSE_IS_PART (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  bse_value_take_boxed (out_values++, bse_part_list_notes (self, ~0, tick, duration, note, note, TRUE));
-
-  return Bse::ERROR_NONE;
-}
-
-METHOD (BsePart, get-notes) {
-  HELP = "Retrieve all notes of specific frequency at or crossing a specific tick.";
-  IN   = bse_param_spec_object ("part", "Part", NULL,
-                                BSE_TYPE_PART, SFI_PARAM_STANDARD);
-  IN   = sfi_pspec_int ("tick", "Tick", NULL,
-                        0, 0, BSE_PART_MAX_TICK - 1, 384, SFI_PARAM_STANDARD);
-  IN   = bse_pspec_note_simple ("note", "Note", NULL,
-                                SFI_PARAM_STANDARD);
-  OUT   = bse_param_spec_boxed ("note_list", "Note List", NULL,
-                               BSE_TYPE_PART_NOTE_SEQ, SFI_PARAM_STANDARD);
-}
-BODY (BseProcedureClass *proc,
-      const GValue      *in_values,
-      GValue            *out_values)
-{
-  /* extract parameter values */
-  BsePart *self = (BsePart*) bse_value_get_object (in_values++);
-  guint    tick            = sfi_value_get_int (in_values++);
-  gint     note     = sfi_value_get_note (in_values++);
-
-  /* check parameters */
-  if (!BSE_IS_PART (self))
-    return Bse::ERROR_PROC_PARAM_INVAL;
-
-  /* action */
-  bse_value_take_boxed (out_values++, bse_part_list_notes (self, ~0, tick, 1, note, note, TRUE));
-
-  return Bse::ERROR_NONE;
-}
-
 METHOD (BsePart, get-timing) {
   HELP  = "Retrieve song timing information at a specific tick.";
   IN    = bse_param_spec_object ("part", "Part", NULL, BSE_TYPE_PART, SFI_PARAM_STANDARD);
diff --git a/bse/bseutils.cc b/bse/bseutils.cc
index c980e82..ad6b862 100644
--- a/bse/bseutils.cc
+++ b/bse/bseutils.cc
@@ -50,48 +50,28 @@ bse_note_description (BseMusicalTuningType   musical_tuning,
   return info;
 }
 
-BsePartNote*
-bse_part_note (guint    id,
-              guint    channel,
-              guint    tick,
-              guint    duration,
-              gint     note,
-              gint     fine_tune,
-              gfloat   velocity,
-              gboolean selected)
-{
-  BsePartNote *pnote = bse_part_note_new ();
-
-  pnote->id = id;
-  pnote->channel = channel;
-  pnote->tick = tick;
-  pnote->duration = duration;
-  pnote->note = note;
-  pnote->fine_tune = fine_tune;
-  pnote->velocity = velocity;
-  pnote->selected = selected != FALSE;
-
+Bse::PartNote
+bse_part_note (uint id, uint channel, uint tick, uint duration, int note, int fine_tune, double velocity, 
bool selected)
+{
+  Bse::PartNote pnote;
+  pnote.id = id;
+  pnote.channel = channel;
+  pnote.tick = tick;
+  pnote.duration = duration;
+  pnote.note = note;
+  pnote.fine_tune = fine_tune;
+  pnote.velocity = velocity;
+  pnote.selected = selected != false;
   return pnote;
 }
 
-void
-bse_part_note_seq_take_append (BsePartNoteSeq *seq,
-                              BsePartNote    *element)
-{
-  g_return_if_fail (seq != NULL);
-  g_return_if_fail (element != NULL);
-
-  bse_part_note_seq_append (seq, element);
-  bse_part_note_free (element);
-}
-
 Bse::PartControl
-bse_part_control (uint id, uint tick, Bse::MidiSignalType ctype, double value, bool selected)
+bse_part_control (uint id, uint tick, Bse::MidiSignalType control_type, double value, bool selected)
 {
   Bse::PartControl pctrl;
   pctrl.id = id;
   pctrl.tick = tick;
-  pctrl.control_type = ctype;
+  pctrl.control_type = control_type;
   pctrl.value = value;
   pctrl.selected = selected != false;
   return pctrl;
diff --git a/bse/bseutils.hh b/bse/bseutils.hh
index 4118248..1b1f0f2 100644
--- a/bse/bseutils.hh
+++ b/bse/bseutils.hh
@@ -16,17 +16,8 @@ void    bse_cxx_init      (void);
 BseNoteDescription* bse_note_description             (BseMusicalTuningType   musical_tuning,
                                                       int                    note,
                                                       int                    fine_tune);
-BsePartNote*        bse_part_note                    (guint                  id,
-                                                      guint                  channel,
-                                                      guint                  tick,
-                                                      guint                  duration,
-                                                      gint                   note,
-                                                      gint                   fine_tune,
-                                                      gfloat                 velocity,
-                                                      gboolean               selected);
-void                bse_part_note_seq_take_append    (BsePartNoteSeq        *seq,
-                                                      BsePartNote           *element);
-Bse::PartControl    bse_part_control                 (uint id, uint tick, Bse::MidiSignalType ctype, double 
value, bool selected);
+Bse::PartNote    bse_part_note    (uint id, uint channel, uint tick, uint duration, int note, int fine_tune, 
double velocity, bool selected);
+Bse::PartControl bse_part_control (uint id, uint tick, Bse::MidiSignalType control_type, double value, bool 
selected);
 void                bse_note_sequence_resize         (BseNoteSequence       *rec,
                                                       guint                  length);
 guint               bse_note_sequence_length         (BseNoteSequence       *rec);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]