/[svn]/linuxsampler/trunk/src/midiin.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/midiin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (hide annotations) (download)
Thu Dec 25 18:03:43 2003 UTC (20 years, 4 months ago) by schoenebeck
File size: 5887 byte(s)
src/midiin.cpp: fixed SubscribeToClient() method which is mandatory for the
command line switch --inputclient added with the recent commit batch

1 schoenebeck 9 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck *
6     * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "midiin.h"
24    
25     MidiIn::MidiIn(AudioThread* pAudioThread) : Thread(true, 1, -1) {
26 schoenebeck 23 this->seq_handle = NULL;
27 schoenebeck 9 this->pAudioThread = pAudioThread;
28     memset(MIDIControllerTable, 0x00, 128); // set all controller values to zero
29     }
30    
31     MidiIn::~MidiIn() {
32     close_alsa_midi_seq();
33     }
34    
35     int MidiIn::open_alsa_midi_seq(void) {
36     if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
37     fprintf(stderr, "Error opening ALSA sequencer.\n");
38     exit(1);
39     }
40 schoenebeck 20 this->AlsaID = snd_seq_client_id(seq_handle);
41 schoenebeck 9 snd_seq_set_client_name(seq_handle, "LinuxSampler");
42 schoenebeck 20 if ((this->AlsaPort = snd_seq_create_simple_port(seq_handle, "LinuxSampler",
43     SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
44     SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
45 schoenebeck 9 fprintf(stderr, "Error creating sequencer port.\n");
46     exit(1);
47     }
48     return 0;
49     }
50    
51     void MidiIn::close_alsa_midi_seq(void) {
52     }
53    
54 schoenebeck 20 /**
55     * Makes a connection to another Alsa sequencer client, so that all MIDI
56     * events from e.g. a keyboard are always delivered to us.
57     *
58     * @param Client - Alsa sequencer client ID and port string to connect to
59     * (e.g. "64:0")
60     */
61     void MidiIn::SubscribeToClient(const char* Client) {
62 schoenebeck 23 if (!this->seq_handle) { // if we haven't registered our seq client yet
63     int res = open_alsa_midi_seq();
64     if (res < 0) {
65     fprintf(stderr,"Opening of MIDI in device failed, exiting.\n");
66     exit(EXIT_FAILURE);
67     }
68     }
69    
70 schoenebeck 20 snd_seq_addr_t sender, dest;
71     snd_seq_port_subscribe_t* subs;
72 schoenebeck 23 int extClientID, extPortID;
73    
74     sscanf(Client, "%d:%d", &extClientID, &extPortID);
75     sender.client = (char) extClientID;
76     sender.port = (char) extPortID;
77     dest.client = (char) this->AlsaID;
78     dest.port = (char) this->AlsaPort;
79 schoenebeck 20 snd_seq_port_subscribe_alloca(&subs);
80     snd_seq_port_subscribe_set_sender(subs, &sender);
81     snd_seq_port_subscribe_set_dest(subs, &dest);
82     snd_seq_port_subscribe_set_queue(subs, 1);
83     snd_seq_port_subscribe_set_time_update(subs, 1);
84     snd_seq_port_subscribe_set_time_real(subs, 1);
85 schoenebeck 23 if (snd_seq_subscribe_port(this->seq_handle, subs) < 0) {
86     fprintf(stderr, "Unable to subscribe to client \'%s\' (%s)\n", Client, snd_strerror(errno));
87 schoenebeck 20 }
88     }
89    
90 schoenebeck 9 int MidiIn::Main() {
91 schoenebeck 23 if (!this->seq_handle) { // if we haven't registered our seq client yet
92     int res = open_alsa_midi_seq();
93     if (res < 0) {
94     fprintf(stderr,"Opening of MIDI in device failed, exiting.\n");
95     exit(EXIT_FAILURE);
96     }
97 schoenebeck 9 }
98    
99     int npfd;
100     struct pollfd *pfd;
101     snd_seq_event_t *ev;
102    
103     npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
104     pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
105     snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN);
106     while (true) {
107     if (poll(pfd, npfd, 100000) > 0) {
108     do {
109     snd_seq_event_input(seq_handle, &ev);
110     switch (ev->type) {
111     case SND_SEQ_EVENT_CONTROLLER:
112 schoenebeck 18 pAudioThread->SendControlChange(ev->data.control.channel, ev->data.control.param, ev->data.control.value);
113 schoenebeck 9 break;
114    
115     case SND_SEQ_EVENT_PITCHBEND:
116 senoner 10 // fprintf(stderr, "Pitchbender event on Channel %2d: %5d \n",
117     // ev->data.control.channel, ev->data.control.value);
118 schoenebeck 9 break;
119    
120     case SND_SEQ_EVENT_NOTEON:
121     if (ev->data.note.velocity != 0) {
122 schoenebeck 18 pAudioThread->SendNoteOn(ev->data.note.note, ev->data.note.velocity);
123 schoenebeck 9 }
124     else {
125 schoenebeck 18 pAudioThread->SendNoteOff(ev->data.note.note, 0);
126 schoenebeck 9 }
127     break;
128    
129     case SND_SEQ_EVENT_NOTEOFF:
130 schoenebeck 18 pAudioThread->SendNoteOff(ev->data.note.note, ev->data.note.velocity);
131 schoenebeck 9 break;
132     }
133     snd_seq_free_event(ev);
134     } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
135 schoenebeck 18 }
136     }
137 schoenebeck 9 }
138 senoner 10

  ViewVC Help
Powered by ViewVC