コード例 #1
0
ファイル: perfedit.cpp プロジェクト: danielappelt/sequencer64
void
update_perfedit_sequences ()
{
    if (not_nullptr(gs_perfedit_pointer_0))
        gs_perfedit_pointer_0->draw_sequences();

    if (not_nullptr(gs_perfedit_pointer_1))
        gs_perfedit_pointer_1->draw_sequences();
}
コード例 #2
0
ファイル: midibus_portmidi.cpp プロジェクト: EQ4/sequencer64
midibus::~midibus ()
{
    if (not_nullptr(m_pms))
    {
        Pm_Close(m_pms);
        m_pms = nullptr;
    }
}
コード例 #3
0
ファイル: perfedit.cpp プロジェクト: danielappelt/sequencer64
void
perfedit::enqueue_draw (bool forward)
{
    m_perfroll->queue_draw();
    m_perfnames->queue_draw();
    m_perftime->queue_draw();
    if (forward && not_nullptr(m_peer_perfedit))
        m_peer_perfedit->enqueue_draw(false);
}
コード例 #4
0
ファイル: event.cpp プロジェクト: 0rel/sequencer64
void
event::restart_sysex ()
{
    if (not_nullptr(m_sysex))
        delete [] m_sysex;

    m_sysex = nullptr;
    m_sysex_size = 0;
}
コード例 #5
0
void
mastermidibus::set_sequence_input (bool state, sequence * seq)
{
    automutex locker(m_mutex);
    if (m_filter_by_channel)
    {
        if (not_nullptr(seq))
        {
            if (state)
            {
                /*
                 * We might have a sequence in the vector; add the sequence if
                 * not already added.
                 */

                bool have_seq_already = false;
                for (size_t i = 0; i < m_vector_sequence.size(); ++i)
                {
                    if (m_vector_sequence[i] == seq)
                        have_seq_already = true;
                }
                if (! have_seq_already)
                    m_vector_sequence.push_back(seq);
            }
            else
            {
                /*
                 * If we have a sequence that is in the vector, remove the
                 * sequence.
                 */

                for (size_t i = 0; i < m_vector_sequence.size(); ++i)
                {
                    if (m_vector_sequence[i] == seq)
                        m_vector_sequence.erase(m_vector_sequence.begin() + i);
                }
            }
            if (m_vector_sequence.size() != 0)
                m_dumping_input = true;
        }
        else if (! state)
        {
            /*
             * No sequence and false state means we don't want to record, so
             * clear the vector.
             */

            m_vector_sequence.clear();
        }
    }
    else
    {
        m_seq = seq;
        m_dumping_input = state;
    }
}
コード例 #6
0
ファイル: font.cpp プロジェクト: danielappelt/sequencer64
void
font::render_string_on_drawable
(
    Glib::RefPtr<Gdk::GC> gc,
    int x, int y,
    Glib::RefPtr<Gdk::Drawable> a_draw,
    const char * str,
    font::Color col,
    bool invert
) const
{
    int length = 0;
    if (not_nullptr(str))
        length = strlen(str);

    if (m_use_new_font)
        y += 1;                         /* make minor correction */
    else
        y += 2;                         /* make minor correction */

    if (col == font::BLACK)
        m_pixmap = &m_black_pixmap;
    else if (col == font::WHITE)
        m_pixmap = &m_white_pixmap;
    else if (col == font::BLACK_ON_YELLOW)
        m_pixmap = &m_b_on_y_pixmap;
    else if (col == font::YELLOW_ON_BLACK)
        m_pixmap = &m_y_on_b_pixmap;
    else if (col == font::BLACK_ON_CYAN)
        m_pixmap = &m_b_on_c_pixmap;
    else if (col == font::CYAN_ON_BLACK)
        m_pixmap = &m_c_on_b_pixmap;
    else
        m_pixmap = &m_black_pixmap;     /* user lied, provide legal pointer */

    if (gui_palette_gtk2::is_inverse() && invert)
        gc->set_function(Gdk::COPY_INVERT);  /* XOR or INVERT?              */

    for (int k = 0; k < length; ++k)
    {
        int c = int(str[k]);
        int pixbuf_index_x = c % cf_grid_w;
        int pixbuf_index_y = c / cf_grid_h;
        pixbuf_index_x *= m_cell_w;     /* width of grid (letter=6 pixels)  */
        pixbuf_index_x += m_offset;     /* add around 2 for border?         */
        pixbuf_index_y *= m_cell_h;     /* height of grid (letter=10 pixel) */
        pixbuf_index_y += m_offset;     /* add around 2 for border?         */
        a_draw->draw_drawable
        (
            gc, *m_pixmap, pixbuf_index_x, pixbuf_index_y,
            x + (k * m_font_w), y, m_font_w, m_font_h
        );
    }
    if (gui_palette_gtk2::is_inverse() && invert)
        gc->set_function(Gdk::COPY);    /* not NOOP or SET                  */
}
コード例 #7
0
std::string
keyval_name (unsigned int key)
{
    std::string result;
    gchar * kname = gdk_keyval_name(key);
    if (not_nullptr(kname))
        result = std::string((char *) kname);

    return result;
}
コード例 #8
0
mastermidibus::~mastermidibus ()
{
    for (int i = 0; i < m_num_out_buses; ++i)
    {
        if (not_nullptr(m_buses_out[i]))
        {
            delete m_buses_out[i];
            m_buses_out[i] = nullptr;
        }
    }
    for (int i = 0; i < m_num_in_buses; ++i)
    {
        if (not_nullptr(m_buses_in[i]))
        {
            delete m_buses_in[i];
            m_buses_in[i] = nullptr;
        }
    }

#ifdef SEQ64_HAVE_LIBASOUND
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);                          /* kill timer           */
    snd_seq_stop_queue(m_alsa_seq, m_queue, &ev);
    snd_seq_free_queue(m_alsa_seq, m_queue);
    snd_seq_close(m_alsa_seq);                      /* close client         */
    (void) snd_config_update_free_global();         /* additional cleanup   */
#endif

    /*
     * Still more cleanup, not in seq24.
     */

    if (not_nullptr(m_poll_descriptors))
    {
        delete [] m_poll_descriptors;
        m_poll_descriptors = nullptr;
    }
    if (not_nullptr(m_bus_announce))
    {
        delete m_bus_announce;
        m_bus_announce = nullptr;
    }
}
コード例 #9
0
ファイル: mastermidibus.cpp プロジェクト: EQ4/sequencer24
mastermidibus::mastermidibus ()
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_bpm               (0),
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_seq               (nullptr),
    m_mutex             ()
{
    for (int i = 0; i < c_max_busses; ++i)        // why the global?
    {
        m_buses_in_active[i] = false;
        m_buses_out_active[i] = false;
        m_buses_in_init[i] = false;
        m_buses_out_init[i] = false;
        m_init_clock[i] = e_clock_off;
        m_init_input[i] = false;
    }

#ifdef HAVE_LIBASOUND
    /* open the sequencer client */

    int result  = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result  < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    snd_seq_set_client_name(m_alsa_seq, "seq24");   /* client's name  */
    m_queue = snd_seq_alloc_queue(m_alsa_seq);      /* client's queue */
#endif

#ifdef LASH_SUPPORT
    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(global_lash_driver))
        global_lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));
#endif
}
コード例 #10
0
mastermidibus::~mastermidibus ()
{
    for (int i = 0; i < m_num_out_buses; i++)
    {
        if (not_nullptr(m_buses_out[i]))
        {
            delete m_buses_out[i];
            m_buses_out[i] = nullptr;
        }
    }
    for (int i = 0; i < m_num_in_buses; i++)
    {
        if (not_nullptr(m_buses_in[i]))
        {
            delete m_buses_in[i];
            m_buses_in[i] = nullptr;
        }
    }
    Pm_Terminate();
}
コード例 #11
0
ファイル: event.cpp プロジェクト: 0rel/sequencer64
bool
event::append_sysex (midibyte * data, int dsize)
{
    bool result = false;
    if (not_nullptr(data) && (dsize > 0))
    {
        midibyte * buffer = new midibyte[m_sysex_size + dsize];
        if (not_nullptr(buffer))
        {
            if (not_nullptr(m_sysex))
            {
                memcpy(buffer, m_sysex, m_sysex_size);  /* copy original data */
                delete [] m_sysex;
            }
            memcpy(&buffer[m_sysex_size], data, dsize); /* append new data    */
            m_sysex_size += dsize;
            m_sysex = buffer;                           /* save the pointer   */
            result = true;
        }
        else
        {
            errprint("event::append_sysex(): bad allocation");
        }
        for (int i = 0; i < dsize; ++i)
        {
            if (data[i] == EVENT_SYSEX_END)
            {
                result = false;
                break;                                  // done, already false now
            }
        }
    }
    else
    {
        errprint("event::append_sysex(): null parameters");
    }
    return result;
}
コード例 #12
0
ファイル: font.cpp プロジェクト: EQ4/sequencer24
void
font::render_string_on_drawable
(
    Glib::RefPtr<Gdk::GC> a_gc,
    int x, int y,
    Glib::RefPtr<Gdk::Drawable> a_draw,
    const char * str,
    font::Color col
)
{
    int length = 0;
    if (not_nullptr(str))
        length = strlen(str);

    /*
     * The width is identical to c_text_x, but the height is not identical
     * to c_text_y.  Using the latter values causes artifacts on the
     * pattern grid.
     */

    int font_w = 6;                     // c_text_x == 6
    int font_h = 10;                    // c_text_y == 12
    if (col == font::BLACK)
        m_pixmap = &m_black_pixmap;
    else if (col == font::WHITE)
        m_pixmap = &m_white_pixmap;
    else if (col == font::BLACK_ON_YELLOW)
        m_pixmap = &m_b_on_y_pixmap;
    else if (col == font::YELLOW_ON_BLACK)
        m_pixmap = &m_y_on_b_pixmap;
    else
        m_pixmap = &m_black_pixmap; // user lied, provide a legal pointer

    for (int i = 0; i < length; ++i)
    {
        unsigned char c = (unsigned char) str[i];
        int pixbuf_index_x = c % 16;    // number of grids horizontally
        int pixbuf_index_y = c / 16;    // number of grids vertically
        pixbuf_index_x *= 9;            // width of grid (letter is 6 pixels)
        pixbuf_index_x += 2;            // add 2 for border?
        pixbuf_index_y *= 13;           // height of grid (letter is 12 pixels)
        pixbuf_index_y += 2;            // add 2 for border?
        a_draw->draw_drawable
        (
            a_gc, *m_pixmap, pixbuf_index_x, pixbuf_index_y,
            x + (i * font_w), y, font_w, font_h
        );
    }
}
コード例 #13
0
ファイル: mastermidibus.cpp プロジェクト: EQ4/sequencer24
mastermidibus::~mastermidibus ()
{
    for (int i = 0; i < m_num_out_buses; i++)
    {
        if (not_nullptr(m_buses_out[i]))
        {
            delete m_buses_out[i];
            m_buses_out[i] = nullptr;
        }
    }
#ifdef HAVE_LIBASOUND
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);                          /* kill timer */
    snd_seq_stop_queue(m_alsa_seq, m_queue, &ev);
    snd_seq_free_queue(m_alsa_seq, m_queue);
    snd_seq_close(m_alsa_seq);                      /* close client */
#endif
}
コード例 #14
0
ファイル: font.hpp プロジェクト: danielappelt/sequencer64
inline font &
font_render ()
{
    static font * sp_font_renderer = nullptr;
    if (is_nullptr(sp_font_renderer))
    {
        sp_font_renderer = new font;
        if (not_nullptr(sp_font_renderer))
        {
            // sp_font_renderer->init(m_window)
        }
        else
        {
            errprint("could not create the application font object, crash!");
        }
    }
    return *sp_font_renderer;
}
コード例 #15
0
ファイル: perfnames.cpp プロジェクト: 0rel/sequencer64
bool
perfnames::on_button_press_event (GdkEventButton * ev)
{
    int y = int(ev->y);
    int seqnum = convert_y(y);
    current_seq(seqnum);
    if (SEQ64_CLICK_LEFT(ev->button))
    {
        if (perf().is_active(seqnum))
        {
            guint modifiers;        /* for filtering out caps/num lock etc. */
            modifiers = gtk_accelerator_get_default_mod_mask();
            if ((ev->state & modifiers) == SEQ64_SHIFT_MASK)
            {
                /*
                 * \new ca 2016-03-15
                 *      If the Shift key is pressed, mute all other sequences.
                 *      Inactive sequences are skipped.
                 */

                for (int s = 0; s < m_sequence_max; ++s)
                {
                    if (s != seqnum)
                    {
                        sequence * seq = perf().get_sequence(s);
                        if (not_nullptr(seq))
                        {
                            bool muted = seq->get_song_mute();
                            seq->set_song_mute(! muted);
                        }
                    }
                }
            }
            else
            {
                sequence * seq = perf().get_sequence(seqnum);
                bool muted = seq->get_song_mute();
                seq->set_song_mute(! muted);
            }
            enqueue_draw();
        }
    }
    return true;
}
コード例 #16
0
ファイル: main.c プロジェクト: EQ4/waonc
int
main (int argc, char * argv [])
{
   wbool_t parse_good = wtrue;
   waon_parameters_t waon_parameters;
   analysis_scratchpad_t analysis_scratchpad;
   wbool_t result = parameters_initialize(&waon_parameters);
   if (result)
      result = parameters_parse(&waon_parameters, argc, argv);

   if (result)
      result = analysis_scratchpad_initialize(&analysis_scratchpad);

   if (result)
   {
       analysis_scratchpad.absolute_cutoff = waon_parameters.abs_flg;
       if (not_nullptr(waon_parameters.file_patch))
          analysis_scratchpad.use_patchfile = wtrue;

       /* NEW as of 12-01 */

       g_midi_pitch_info.mp_adj_pitch = waon_parameters.adj_pitch;
   }
   if (waon_parameters.show_help)
   {
      print_usage();
      parse_good = wfalse;
   }
   else if (waon_parameters.show_version)
   {
      print_version();
      parse_good = wfalse;
   }
   if (result && parse_good)
   {
      parse_good = processing(&waon_parameters, &analysis_scratchpad);
      parameters_free(&waon_parameters);
   }
   return parse_good ? 0 : 1 ;
}
コード例 #17
0
ファイル: perfroll.cpp プロジェクト: EQ4/sequencer64
perfroll::~perfroll ()
{
    if (not_nullptr(m_interaction))
        delete m_interaction;
}
コード例 #18
0
ファイル: sequencer64.cpp プロジェクト: EQ4/sequencer64
int
main (int argc, char * argv [])
{
    Gtk::Main kit(argc, argv);              /* strip GTK+ parameters        */
    int c;
    g_rc_settings.set_defaults();           /* start out with normal values */
    g_user_settings.set_defaults();         /* start out with normal values */

    /*
     * Set up objects that are specific to the Gtk-2 GUI.  Pass them to
     * the perform constructor.  Create a font-render object.
     *
     * ISSUE:  We really need to create the perform object after reading
     * the configuration, but we also need to fill it in from the
     * configuration, I believe.
     */

    seq64::gui_assistant_gtk2 gui;              /* GUI-specific objects     */
    seq64::perform p(gui);                      /* main performance object  */
    seq64::p_font_renderer = new seq64::font(); /* set the font renderer    */

    /*
     *  Instead of the Seq24 names, use the new configuration file-names,
     *  located in ~/.config/sequencer64. However, if they aren't found,
     *  we no longer fall back to the legacy configuration file-names.  If
     *  the --legacy option is in force, use only the legacy configuration
     *  file-name.  The code also ensures the directory exists.  CURRENTLY
     *  LINUX-SPECIFIC.  See the rc_settings class for how this works.
     */

    std::string cfg_dir = g_rc_settings.home_config_directory();
    if (cfg_dir.empty())
        return EXIT_FAILURE;

    std::string rcname = g_rc_settings.user_filespec();
    if (Glib::file_test(rcname, Glib::FILE_TEST_EXISTS))
    {
        printf("[Reading user configuration %s]\n", rcname.c_str());
        seq64::userfile user(rcname);
        if (user.parse(p))
        {
            // Nothing to do, and no exit needed here if it fails
        }
    }

    rcname = g_rc_settings.config_filespec();
    if (Glib::file_test(rcname, Glib::FILE_TEST_EXISTS))
    {
        printf("[Reading rc configuration %s]\n", rcname.c_str());
        seq64::optionsfile options(rcname);
        if (options.parse(p))
        {
            /*
             * Not necessary, and it resets the last-used-directory
             * obtained from the "rc" configuration file.
             *
             * g_rc_settings.last_used_dir(cfg_dir);
             */
        }
        else
            return EXIT_FAILURE;
    }

    for (;;)                                /* parse all command parameters */
    {
        int option_index = 0;               /* getopt_long index storage    */
        c = getopt_long
        (
            argc, argv,
            "ChlLi:jJmM:pPsSU:Vx:",         /* wrong: "C:hi:jJmM:pPsSU:Vx:" */
            long_options, &option_index
        );
        if (c == -1)                        /* detect the end of options    */
            break;

        switch (c)
        {
        case '?':
        case 'h':
            printf(g_help_1a);
            printf(g_help_1b);
            printf(g_help_2);
            return EXIT_SUCCESS;
            break;

        case 'l':
            g_rc_settings.legacy_format(true);
            printf("Setting legacy seq24 file format.\n");
            break;

        case 'L':
            g_rc_settings.lash_support(true);
            printf("Activating LASH support.\n");
            break;

        case 'S':
            g_rc_settings.stats(true);
            break;

        case 's':
            g_rc_settings.show_midi(true);
            break;

        case 'p':
            g_rc_settings.priority(true);
            break;

        case 'P':
            g_rc_settings.pass_sysex(true);
            break;

        case 'k':
            g_rc_settings.print_keys(true);
            break;

        case 'j':
            g_rc_settings.with_jack_transport(true);
            break;

        case 'J':
            g_rc_settings.with_jack_master(true);
            break;

        case 'C':
            g_rc_settings.with_jack_master_cond(true);
            break;

        case 'M':
            if (atoi(optarg) > 0)
            {
                g_rc_settings.jack_start_mode(true);
            }
            else
            {
                g_rc_settings.jack_start_mode(false);
            }
            break;

        case 'm':
            g_rc_settings.manual_alsa_ports(true);
            break;

        case 'i':                           /* ignore ALSA device */
            g_rc_settings.device_ignore(true);
            g_rc_settings.device_ignore_num(atoi(optarg));
            break;

        case 'V':
            printf("%s", versiontext.c_str());
            return EXIT_SUCCESS;
            break;

        case 'U':
            g_rc_settings.jack_session_uuid(std::string(optarg));
            break;

        case 'x':
            g_rc_settings.interaction_method
            (
                interaction_method_t(atoi(optarg))
            );
            break;

        default:
            break;
        }
    }

    std::size_t applen = strlen("seq24");
    std::string appname(argv[0]);               /* "seq24", "./seq24", etc. */
    appname = appname.substr(appname.size()-applen, applen);
    if (appname == "seq24")
    {
        g_rc_settings.legacy_format(true);
        printf("Setting legacy seq24 file format.\n");
    }
    g_rc_settings.set_globals();                /* copy to legacy globals   */
    g_user_settings.set_globals();              /* copy to legacy globals   */

#ifdef USE_THIS_INSTANCE_OF_CODE

    /*
     * Set up objects that are specific to the Gtk-2 GUI.  Pass them to
     * the perform constructor.  Create a font-render object.
     */

    seq64::gui_assistant_gtk2 gui;              /* GUI-specific objects     */
    seq64::perform p(gui);                      /* main performance object  */
    seq64::p_font_renderer = new seq64::font(); /* set the font renderer    */

#endif  // USE_THIS_INSTANCE_OF_CODE

    p.init();
    p.launch_input_thread();
    p.launch_output_thread();
    p.init_jack();

    seq64::mainwnd seq24_window(p);             /* push mainwnd onto stack  */
    if (optind < argc)
    {
        if (Glib::file_test(argv[optind], Glib::FILE_TEST_EXISTS))
            seq24_window.open_file(argv[optind]);
        else
            printf("? file not found: %s\n", argv[optind]);
    }

#ifdef SEQ64_LASH_SUPPORT
    if (global_lash_support)
    {
        /*
         *  Initialize the lash driver (strips lash-specific command line
         *  arguments), then connect to LASH daemon and poll events.
         */

        seq64::global_lash_driver = new seq64::lash(p, argc, argv);
        // seq64::global_lash_driver->init();
        seq64::global_lash_driver->start();
    }
    else
        seq64::global_lash_driver = nullptr;
#endif

    kit.run(seq24_window);
    p.deinit_jack();

    /*
     * Write the configuration file to the new name, unless the
     * --legacy option is in force.
     */

    g_rc_settings.get_globals();             /* copy from legacy globals */
    rcname = g_rc_settings.config_filespec();

    printf("[Writing rc configuration %s]\n", rcname.c_str());
    seq64::optionsfile options(rcname);
    if (options.write(p))
    {
        // Anything to do?
    }

    g_user_settings.dump_summary();
    g_user_settings.get_globals();           /* copy from legacy globals */
    g_user_settings.dump_summary();
    rcname = g_rc_settings.user_filespec();
    printf("[Writing user configuration %s]\n", rcname.c_str());
    seq64::userfile userstuff(rcname);
    if (userstuff.write(p))
    {
        // Anything to do?
    }

#ifdef SEQ64_LASH_SUPPORT
    if (not_nullptr(seq64::global_lash_driver))
        delete seq64::global_lash_driver;
#endif

    return EXIT_SUCCESS;
}
コード例 #19
0
ファイル: perform.hpp プロジェクト: EQ4/sequencer64
 void enregister (performcallback * pfcb)
 {
     if (not_nullptr(pfcb))
         m_notify.push_back(pfcb);
 }
コード例 #20
0
mastermidibus::mastermidibus (int ppqn, int bpm)
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_max_busses        (c_max_busses),
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_beats_per_minute  (bpm),      // beats per minute
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_vector_sequence   (),
    m_filter_by_channel (false),    // set below based on configuration
    m_seq               (nullptr),
    m_mutex             ()
{
    m_ppqn = choose_ppqn(ppqn);
    for (int i = 0; i < m_max_busses; ++i)
    {
        m_buses_in_active[i] =
            m_buses_out_active[i] =
            m_buses_in_init[i] =
            m_buses_out_init[i] =
            m_init_input[i] = false;

        m_init_clock[i] = e_clock_off;
    }

#ifdef SEQ64_HAVE_LIBASOUND

    /*
     * Open the sequencer client.  This line of code results in a loss of
     * 4 bytes somewhere in snd_seq_open(), as discovered via valgrind.
     */

    int result = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    else
    {
        /*
         * Tried to reduce apparent memory leaks from libasound, but this call
         * changed nothing.
         *
         * (void) snd_config_update_free_global();
         */
    }

    /*
     * Set the client's name for ALSA.  It used to be "seq24".  Then set up our
     * ALSA client's queue.
     */

    snd_seq_set_client_name(m_alsa_seq, "sequencer64");
    m_queue = snd_seq_alloc_queue(m_alsa_seq);

#endif      // SEQ64_HAVE_LIBASOUND

#ifdef SEQ64_LASH_SUPPORT

    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(lash_driver()))
        lash_driver()->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));

#endif
}
コード例 #21
0
void
mastermidibus::port_start (int client, int port)
{
#ifdef SEQ64_HAVE_LIBASOUND
    automutex locker(m_mutex);
    snd_seq_client_info_t * cinfo;                      /* client info        */
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_get_any_client_info(m_alsa_seq, client, cinfo);
    snd_seq_port_info_t * pinfo;                        /* port info          */
    snd_seq_port_info_alloca(&pinfo);
    snd_seq_get_any_port_info(m_alsa_seq, client, port, pinfo);

    int cap = snd_seq_port_info_get_capability(pinfo);  /* get its capability */
    if (ALSA_CLIENT_CHECK(pinfo))
    {
        if (CAP_FULL_WRITE(cap) && ALSA_CLIENT_CHECK(pinfo)) /* outputs */
        {
            bool replacement = false;
            int bus_slot = m_num_out_buses;
            for (int i = 0; i < m_num_out_buses; ++i)
            {
                if
                (
                    m_buses_out[i]->get_client() == client  &&
                    m_buses_out[i]->get_port() == port &&
                    ! m_buses_out_active[i]
                )
                {
                    replacement = true;
                    bus_slot = i;
                }
            }
            if (not_nullptr(m_buses_out[bus_slot]))
            {
                delete m_buses_out[bus_slot];
                errprintf
                (
                    "mastermidibus::port_start(): m_buses_out[%d] not null\n",
                    bus_slot
                );
            }
            m_buses_out[bus_slot] = new midibus
            (
                snd_seq_client_id(m_alsa_seq),
                snd_seq_port_info_get_client(pinfo),
                snd_seq_port_info_get_port(pinfo),
                m_alsa_seq,
                snd_seq_client_info_get_name(cinfo),
                snd_seq_port_info_get_name(pinfo),
                m_num_out_buses,
                m_queue
            );
            m_buses_out[bus_slot]->init_out();
            m_buses_out_active[bus_slot] = true;
            m_buses_out_init[bus_slot] = true;
            if (! replacement)
                ++m_num_out_buses;
        }
        if (CAP_FULL_READ(cap) && ALSA_CLIENT_CHECK(pinfo)) /* inputs */
        {
            bool replacement = false;
            int bus_slot = m_num_in_buses;
            for (int i = 0; i < m_num_in_buses; ++i)
            {
                if
                (
                    m_buses_in[i]->get_client() == client  &&
                    m_buses_in[i]->get_port() == port && ! m_buses_in_active[i]
                )
                {
                    replacement = true;
                    bus_slot = i;
                }
            }
            if (not_nullptr(m_buses_in[bus_slot]))
            {
                delete m_buses_in[bus_slot];
                errprintf
                (
                    "mmbus::port_start(): m_buses_in[%d] not null\n", bus_slot
                );
            }
            m_buses_in[bus_slot] = new midibus
            (
                snd_seq_client_id(m_alsa_seq),
                snd_seq_port_info_get_client(pinfo),
                snd_seq_port_info_get_port(pinfo),
                m_alsa_seq,
                snd_seq_client_info_get_name(cinfo),
                snd_seq_port_info_get_name(pinfo),
                m_num_in_buses,
                m_queue
            );
            m_buses_in_active[bus_slot] = true;
            m_buses_in_init[bus_slot] = true;
            if (! replacement)
                m_num_in_buses++;
        }
    }                                           /* end loop for clients */

    /*
     * Get the number of MIDI input poll file descriptors.
     */

    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);
    m_poll_descriptors = new pollfd[m_num_poll_descriptors]; /* allocate info */
    snd_seq_poll_descriptors                        /* get input descriptors */
    (
        m_alsa_seq, m_poll_descriptors, m_num_poll_descriptors, POLLIN
    );
#endif  // SEQ64_HAVE_LIBASOUND
}
コード例 #22
0
void
mastermidibus::init (int ppqn)
{
#ifdef SEQ64_HAVE_LIBASOUND
    snd_seq_client_info_t * cinfo;          /* client info */
    snd_seq_port_info_t * pinfo;            /* port info   */
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_client_info_set_client(cinfo, -1);
    if (rc().manual_alsa_ports())
    {
        /*
         * Output busses
         */

        int num_buses = SEQ64_ALSA_OUTPUT_BUSS_MAX;
        for (int i = 0; i < num_buses; ++i)
        {
            if (not_nullptr(m_buses_out[i]))
            {
                delete m_buses_out[i];
                errprintf("mmbus::init() manual: m_buses_out[%d] not null\n", i);
            }
            m_buses_out[i] = new midibus
            (
                snd_seq_client_id(m_alsa_seq), m_alsa_seq, i+1, m_queue
            );
            m_buses_out[i]->init_out_sub();
            m_buses_out_active[i] = m_buses_out_init[i] = true;
        }
        m_num_out_buses = num_buses;
        if (not_nullptr(m_buses_in[0]))
        {
            delete m_buses_in[0];
            errprint("mmbus::init() manual: m_buses_[0] not null");
        }

        /*
         * Input buss.  Only the first element is set up.  The rest are used
         * only for non-manual ALSA ports in the else-class below.
         */

        m_num_in_buses = 1;
        m_buses_in[0] = new midibus
        (
            snd_seq_client_id(m_alsa_seq), m_alsa_seq, m_num_in_buses, m_queue
        );
        m_buses_in[0]->init_in_sub();
        m_buses_in_active[0] = m_buses_in_init[0] = true;
    }
    else
    {
        /*
         * While the next client for the sequencer is available, get the client
         * from cinfo.  Fill pinfo.
         */

        while (snd_seq_query_next_client(m_alsa_seq, cinfo) >= 0)
        {
            int client = snd_seq_client_info_get_client(cinfo);
            snd_seq_port_info_alloca(&pinfo);           /* will fill pinfo */
            snd_seq_port_info_set_client(pinfo, client);
            snd_seq_port_info_set_port(pinfo, -1);
            while (snd_seq_query_next_port(m_alsa_seq, pinfo) >= 0)
            {
                /*
                 * While the next port is available, get its capability.
                 */

                int cap = snd_seq_port_info_get_capability(pinfo);
                if
                (
                    ALSA_CLIENT_CHECK(pinfo) &&
                    snd_seq_port_info_get_client(pinfo) != SND_SEQ_CLIENT_SYSTEM
                )
                {
                    /*
                     * Output busses:
                     *
                     * Why are we doing the ALSA client check again here?
                     * Because it could be altered in the if-clause above.
                     */

                    if (CAP_WRITE(cap) && ALSA_CLIENT_CHECK(pinfo))
                    {
                        if (not_nullptr(m_buses_out[m_num_out_buses]))
                        {
                            delete m_buses_out[m_num_out_buses];
                            errprintf
                            (
                                "mmbus::init(): m_buses_out[%d] not null\n",
                                m_num_out_buses
                            );
                        }
                        m_buses_out[m_num_out_buses] = new midibus
                        (
                            snd_seq_client_id(m_alsa_seq),
                            snd_seq_port_info_get_client(pinfo),
                            snd_seq_port_info_get_port(pinfo), m_alsa_seq,
                            snd_seq_client_info_get_name(cinfo),
                            snd_seq_port_info_get_name(pinfo),
                            m_num_out_buses, m_queue
                        );
                        if (m_buses_out[m_num_out_buses]->init_out())
                        {
                            m_buses_out_active[m_num_out_buses] = true;
                            m_buses_out_init[m_num_out_buses] = true;
                        }
                        else
                            m_buses_out_init[m_num_out_buses] = true;

                        ++m_num_out_buses;
                    }

                    /*
                     * Input busses
                     */

                    if (CAP_READ(cap) && ALSA_CLIENT_CHECK(pinfo)) /* inputs */
                    {
                        if (not_nullptr(m_buses_in[m_num_in_buses]))
                        {
                            delete m_buses_in[m_num_in_buses];
                            errprintf
                            (
                                "mmbus::init(): m_buses_in[%d] not null\n",
                                m_num_in_buses
                            );
                        }
                        m_buses_in[m_num_in_buses] = new midibus
                        (
                            snd_seq_client_id(m_alsa_seq),
                            snd_seq_port_info_get_client(pinfo),
                            snd_seq_port_info_get_port(pinfo), m_alsa_seq,
                            snd_seq_client_info_get_name(cinfo),
                            snd_seq_port_info_get_name(pinfo),
                            m_num_in_buses, m_queue
                        );
                        m_buses_in_active[m_num_in_buses] =
                            m_buses_in_init[m_num_in_buses] = true;

                        ++m_num_in_buses;
                    }
                }
            }
        }                                       /* end loop for clients */
    }
    set_beats_per_minute(m_beats_per_minute);
    set_ppqn(ppqn);

    /*
     * Get the number of MIDI input poll file descriptors.  Allocate the
     * poll-descriptors array.  Then get the input poll-descriptors into the
     * array
     */

    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);
    m_poll_descriptors = new pollfd[m_num_poll_descriptors];
    snd_seq_poll_descriptors
    (
        m_alsa_seq, m_poll_descriptors, m_num_poll_descriptors, POLLIN
    );
    set_sequence_input(false, nullptr);

    /* Set the input and output buffer sizes */

    snd_seq_set_output_buffer_size(m_alsa_seq, c_midibus_output_size);
    snd_seq_set_input_buffer_size(m_alsa_seq, c_midibus_input_size);
    m_bus_announce = new midibus
    (
        snd_seq_client_id(m_alsa_seq),
        SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE,
        m_alsa_seq, "system", "announce",   // was "annouce" ca 2016-04-03
        0, m_queue
    );
    m_bus_announce->set_input(true);
    for (int i = 0; i < m_num_out_buses; ++i)
        set_clock(i, m_init_clock[i]);

    for (int i = 0; i < m_num_in_buses; ++i)
        set_input(i, m_init_input[i]);

#endif  // SEQ64_HAVE_LIBASOUND
}