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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show 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 /***************************************************************************
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 this->seq_handle = NULL;
27 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 this->AlsaID = snd_seq_client_id(seq_handle);
41 snd_seq_set_client_name(seq_handle, "LinuxSampler");
42 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 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 /**
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 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 snd_seq_addr_t sender, dest;
71 snd_seq_port_subscribe_t* subs;
72 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 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 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 }
88 }
89
90 int MidiIn::Main() {
91 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 }
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 pAudioThread->SendControlChange(ev->data.control.channel, ev->data.control.param, ev->data.control.value);
113 break;
114
115 case SND_SEQ_EVENT_PITCHBEND:
116 // fprintf(stderr, "Pitchbender event on Channel %2d: %5d \n",
117 // ev->data.control.channel, ev->data.control.value);
118 break;
119
120 case SND_SEQ_EVENT_NOTEON:
121 if (ev->data.note.velocity != 0) {
122 pAudioThread->SendNoteOn(ev->data.note.note, ev->data.note.velocity);
123 }
124 else {
125 pAudioThread->SendNoteOff(ev->data.note.note, 0);
126 }
127 break;
128
129 case SND_SEQ_EVENT_NOTEOFF:
130 pAudioThread->SendNoteOff(ev->data.note.note, ev->data.note.velocity);
131 break;
132 }
133 snd_seq_free_event(ev);
134 } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
135 }
136 }
137 }
138

  ViewVC Help
Powered by ViewVC