Example Client

Using the example C++ base classes in Ayyi_Beat_Detector, writing a Ayyi client is pretty simple and would look something like the code below:Using the example C++ base classes in Ayyi_Beat_Detector, writing a Ayyi client is pretty simple and would look something like this:

#include "ayyi.h"
 
main (int argc, char **argv)
{
    // establish messaging and shared data:
 
    Ayyi_client* ayyi = new Ayyi_client;
    if (!ayyi->connect()) return 1;
    if (!ayyi->get_shm()) return 1;
 
    // now we can access the model, eg, get a list of regions:
 
    Partlist region_list = ayyi->get_parts_list();
    for (Partlist::iterator i=region_list.begin(); i!=region_list.end(); i++){
        cout << "region name: " << (*i)->name << endl;
    }
 
    // modify the model contents, eg, move the first Part to bar 4:
 
    gpos pos = {16,0,0};
    ayyi->part_move(*region_list.begin(), &pos);
}
 

Example code for a C client is included in the ayyi/examples directory in the AyyiGtk tarball. It is shown below, with a few lines removed for clarity:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <glib.h>
 
#include "model/ayyi_model.h"
 
static void on_shm (); // our callback for when the server connection is complete.
 
 
int main (int argc, char *argv[])
{
    am__init();
 
    // Connect to the default Ayyi service.
    // Once connection is complete, execution continues in on_shm().
    if (!(am__connect_all(ayyi.service, on_shm, NULL))){
        dbg (0, "server connection failed.");
        exit (1);
    }
 
    // Add callbacks for server events.
    // In this example, 'part_new' will notify us when a new
    // Part has been created, either by us, or another client.
    observer.part_new = on_new_part;
 
    g_main_loop_run (g_main_loop_new (NULL, 0));
 
    exit (0);
}
 
static void
do_some_stuff()
{
    // get a list of Parts in the current Song
 
    GList* parts = song->partlist;
    if(!parts) return;
 
    // move the first Part 1 bar later
 
    GPart* part = parts->data;
 
    //define an offset time of 4 beats, 0 sub-beats, and 0 ticks
    GPos delta = {4, 0, 0};
 
    //add the offset to the original Part start
    GPos* position = &part->start;
    pos_add(position, delta);
 
    //request that the part be moved to the new position
    part_move_async (part, position, part->track);
}
 
void
on_new_part(GPart* new_part)
{
   printf("new part created on server: %s\n", new_part->name);
}
 
void
on_shm()
{
    // One or more shm segments have been added.
    // For this example, we only need the Song segment.
    if (ayyi.got_song) {
        //synchronise local data cache.
        ayyi_song__load();
 
        do_some_stuff();
    }
}

Below is an example of the Part proxy object taken from AyyiGtk. Note that many of the methods make asynchronous requests to the server. A dispatcher updates the proxy object in response to incoming signals.

gpart*         part_new              ();
gpart*         part_new_from_index   (int core_idx, MediaType);
void           part_destroy          (gpart*);
 
void           part_move_async       (gpart*, gpos*, int new_track);
void           part_set_track_async  (gpart*, int new_track);
void           part_trim_left_async  (gpart*);
void           part_resize_rhs_async (gpart*);
void           part_split_async      (gpart*, gpos*);
void           part_rename_async     (gpart*, const char* new_name);
void           part_mute_toggle_async(gpart*);
 
void           part_set_length_async (gpart*);
void           part_set_level_async  (gpart*, float level);
void           part_set_fadein_async (gpart*, int fade_time);
void           part_set_fadeout_async(gpart*, int fade_time);
 
double         part_max_length_px    (gpart*);
void           part_max_length       (gpart*, gpos* max);
 
double         part_end_px           (gpart*);
double         part_end_px_nz        (gpart*);
void           part_end_pos          (gpart*, gpos*);
void           part_get_label        (const gpart*, char *label);
unsigned int   part_get_region       (gpart*);
void           part_get_length_bbst  (gpart*, char* bbst);
void           part_nudge_left       (const gpart*, gboolean snap);
void           part_nudge_right      (const gpart*, gboolean snap);
 
void           part_set_colour       (gpart*, unsigned cidx);
void           part_get_fg_colour    (gpart*, char* rgb);
uint32_t       part_get_fg_colour_int(gpart*);
void           part_set_fg_colour    (gpart*, unsigned cidx);
void           part_colour_to_double (gpart*, double* r, double* g, double* b);
 
gboolean       part_is_selected      (gpart*);
gboolean       part_is_muted         (gpart*);
const gpart*   part_is_between       (const gpart* part, const gpart* start, const gpart* end);
 
void           part_print            (gpart*);