LASH/LADCCA howto


Thanks to Lars Luthman i can present this mini LASH howto which was born in the irc channel #lad on irc.freenode.org:

15:30 < tapas> swh: if an app author wants to integrate lash into his app, what
               does he have to do?
15:30 < swh> tapas, theres a howto somewhere...
15:31 < swh> ... mental note, dont type "lash howto" into google again
15:31 < tapas> hehe
15:31 < swh> maybe linux audio lash howto would be safer!
15:31 < swh> LAD lash howto is not going to be any better!
15:31 < larsl> tapas: Call init_ladcca(), call some other functions to tell
               LADCCA it's JACK name and ALSA ID, then call ladcca_get_events()
               or something like that a few times each second and act on events.

Lars was also kind enough to provide some example code to make it easier for aspiring lash/ladcca users to hack support into their clients (it looks simple enough)..

Here’s the most basic lash/ladcca client ever:

  1. #include <stdio.h>
  2. #include <unistd.h>
  3.  
  4. #include <lash/lash.h>
  5.  
  6.  
  7. lash_client_t* lash_client;
  8.  
  9.  
  10. /* Check for new LADCCA events */
  11. int check_events() {
  12.   int keep_running = 1;
  13.   lash_event_t* event;
  14.   while (event = lash_get_event(lash_client)) {
  15.    
  16.     switch (lash_event_get_type(event)) {
  17.  
  18.     case LASH_Save_File:
  19.       printf(“Asked to save data in %s, but we don’t have any\n,
  20.              lash_event_get_string(event));
  21.       lash_send_event(lash_client, event);
  22.       continue;
  23.    
  24.     case LASH_Restore_File:
  25.       printf(“Asked to restore data from %s, but we don’t have any\n,
  26.              lash_event_get_string(event));
  27.       lash_send_event(lash_client, event);
  28.       continue;
  29.    
  30.     case LASH_Quit:
  31.       printf(“Asked to quit!\n);
  32.       keep_running = 0;
  33.       break;
  34.      
  35.     default:
  36.       printf(“Got unhandled LASH event\n);
  37.     }
  38.    
  39.     lash_event_destroy(event);
  40.   }
  41.  
  42.   return keep_running;
  43. }
  44.  
  45.  
  46. int main(int argc, char** argv) {
  47.   lash_client = lash_init(lash_extract_args(&argc, &argv), “lash-basic”,
  48.                            LASH_Config_File, LASH_PROTOCOL(2, 0));
  49.   if (!lash_client)
  50.     return 1;
  51.   printf(“Successfully connected to the LADLASH daemon!\n);
  52.  
  53.   while (check_events())
  54.     usleep(200000);
  55.  
  56.   return 0;
  57. }

Here’s an example client that shows how to integrate ladcca into a gtkmm app:

  1. #include <iostream>
  2.  
  3. #include <gtkmm.h>
  4. #include <lash/lash.h>
  5.  
  6.  
  7. lash_client_t* lash_client;
  8. Gtk::Label* label;
  9.  
  10.  
  11. /* Check for new LADLASH events */
  12. bool check_events() {
  13.   lash_event_t* event;
  14.   while (event = lash_get_event(lash_client)) {
  15.    
  16.     switch (lash_event_get_type(event)) {
  17.  
  18.     case LASH_Save_File:
  19.       label->set_text(std::string(“Asked to save data in “) +
  20.                       lash_event_get_string(event) + ” but we don’t have any”);
  21.       lash_send_event(lash_client, event);
  22.       continue;
  23.    
  24.     case LASH_Restore_File:
  25.       label->set_text(std::string(“Asked to restore data from “) +
  26.                       lash_event_get_string(event) + ” but we don’t have any”);
  27.       lash_send_event(lash_client, event);
  28.       continue;
  29.    
  30.     case LASH_Quit:
  31.       std::cerr<<“Asked to quit!”<<std::endl;
  32.       Gtk::Main::quit();
  33.       break;
  34.      
  35.     default:
  36.       label->set_text(“Got unhandled LASH event”);
  37.     }
  38.    
  39.     lash_event_destroy(event);
  40.   }
  41.  
  42.   return true;
  43. }
  44.  
  45.  
  46. int main(int argc, char** argv) {
  47.   lash_client = lash_init(lash_extract_args(&argc, &argv), “lash-gtkmm”,
  48.                            LASH_Config_File, LASH_PROTOCOL(2, 0));
  49.   if (!lash_client)
  50.     return 1;
  51.   printf(“Successfully connected to the LADLASH daemon!\n);
  52.  
  53.   /* Initialise gtkmm and create a window */
  54.   Gtk::Main kit(argc, argv);
  55.   Gtk::Window main_win;
  56.   main_win.set_title(“lash-gtkmm”);
  57.   label = new Gtk::Label(“Hello world!”);
  58.   main_win.add(*label);
  59.   main_win.show_all();
  60.  
  61.   /* Make the event callback run five times each second */
  62.   Glib::signal_timeout().connect(&check_events, 200);
  63.  
  64.   kit.run(main_win);
  65.  
  66.   return 0;
  67. }

And finally one that also has some rudimentary jack functionality:

  1. #include <iostream>
  2.  
  3. #include <gtkmm.h>
  4. #include <lash/lash.h>
  5. #include <jack/jack.h>
  6.  
  7.  
  8. jack_client_t* jack_client;
  9. lash_client_t* lash_client;
  10. Gtk::Label* label;
  11.  
  12.  
  13. /* Check for new LADLASH events */
  14. bool check_events() {
  15.   lash_event_t* event;
  16.   while (event = lash_get_event(lash_client)) {
  17.    
  18.     switch (lash_event_get_type(event)) {
  19.  
  20.     case LASH_Save_File:
  21.       label->set_text(std::string(“Asked to save data in “) +
  22.                       lash_event_get_string(event) + ” but we don’t have any”);
  23.       lash_send_event(lash_client, event);
  24.       continue;
  25.    
  26.     case LASH_Restore_File:
  27.       label->set_text(std::string(“Asked to restore data from “) +
  28.                       lash_event_get_string(event) + ” but we don’t have any”);
  29.       lash_send_event(lash_client, event);
  30.       continue;
  31.    
  32.     case LASH_Quit:
  33.       std::cerr<<“Asked to quit!”<<std::endl;
  34.       Gtk::Main::quit();
  35.       break;
  36.      
  37.     default:
  38.       label->set_text(“Got unhandled LASH event”);
  39.     }
  40.    
  41.     lash_event_destroy(event);
  42.   }
  43.  
  44.   return true;
  45. }
  46.  
  47.  
  48. int main(int argc, char** argv) {
  49.  
  50.   lash_client = lash_init(lash_extract_args(&argc, &argv), “lash-gtkmm-jack”,
  51.                            LASH_Config_File, LASH_PROTOCOL(2, 0));
  52.   if (!lash_client)
  53.     return 1;
  54.   printf(“Successfully connected to the LADLASH daemon!\n);
  55.  
  56.   /* Initialise JACK */
  57.   jack_client = jack_client_new(“lash-gtkmm-jack”);
  58.   if (!jack_client)
  59.     return 1;
  60.   printf(“Successfully connected to the JACK daemon!\n);
  61.   jack_port_register(jack_client, “Audio output”, JACK_DEFAULT_AUDIO_TYPE,
  62.                      JackPortIsOutput, 0);
  63.   jack_activate(jack_client);
  64.  
  65.   /* Tell LADLASH out JACK client name */
  66.   lash_jack_client_name(lash_client, “lash-gtkmm-jack”);
  67.  
  68.   /* Initialise gtkmm and create a window */
  69.   Gtk::Main kit(argc, argv);
  70.   Gtk::Window main_win;
  71.   main_win.set_title(“lash-gtkmm”);
  72.   label = new Gtk::Label(“Hello world!”);
  73.   main_win.add(*label);
  74.   main_win.show_all();
  75.  
  76.   /* Make the event callback run five times each second */
  77.   Glib::signal_timeout().connect(&check_events, 200);
  78.  
  79.   kit.run(main_win);
  80.  
  81.   return 0;
  82. }

6 Comments

  1. thrope says:

    You’ll be pleased to know that typing “lash howto” into google now returns this page as first result…

  2. tapas says:

    Hehe, thanks for the pointer.

  3. jaakko says:

    Hi!

    I think the howto is outdated since all function and variable name prefixes have changed from:

    cca_xxx -> lash_xxx
    CCA_xxx -> LASH_xxx

    At least in the ubuntu feisty liblash-dev package.

  4. tapas says:

    You are completely right. I will fix it [was just too lazy until now].. But when people actually complain, it’s a different story :)

    Thanks for the feedback.

  5. Nedko Arnaudov says:

    lash clients are supposed to send save/restore events back, not just destroy them

Leave a Reply