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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations) (download)
Thu Dec 25 00:02:45 2003 UTC (20 years, 5 months ago) by schoenebeck
File size: 5340 byte(s)
* added command line switch --volume to set the global volume level
* added command line switch --inputclient to connect to an Alsa sequencer
  input client on startup (e.g. a MIDI port with a keyboard)
* added command line switch --instrument to select an instrument in case
  the instrument file provides more than one instrument

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     this->pAudioThread = pAudioThread;
27     memset(MIDIControllerTable, 0x00, 128); // set all controller values to zero
28     }
29    
30     MidiIn::~MidiIn() {
31     close_alsa_midi_seq();
32     }
33    
34     int MidiIn::open_alsa_midi_seq(void) {
35     if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
36     fprintf(stderr, "Error opening ALSA sequencer.\n");
37     exit(1);
38     }
39 schoenebeck 20 this->AlsaID = snd_seq_client_id(seq_handle);
40 schoenebeck 9 snd_seq_set_client_name(seq_handle, "LinuxSampler");
41 schoenebeck 20 if ((this->AlsaPort = snd_seq_create_simple_port(seq_handle, "LinuxSampler",
42     SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
43     SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
44 schoenebeck 9 fprintf(stderr, "Error creating sequencer port.\n");
45     exit(1);
46     }
47     return 0;
48     }
49    
50     void MidiIn::close_alsa_midi_seq(void) {
51     }
52    
53 schoenebeck 20 /**
54     * Makes a connection to another Alsa sequencer client, so that all MIDI
55     * events from e.g. a keyboard are always delivered to us.
56     *
57     * @param Client - Alsa sequencer client ID and port string to connect to
58     * (e.g. "64:0")
59     */
60     void MidiIn::SubscribeToClient(const char* Client) {
61     snd_seq_addr_t sender, dest;
62     snd_seq_port_subscribe_t* subs;
63     sscanf(Client, "%d:%d", sender.client, sender.port);
64     dest.client = this->AlsaID;
65     dest.port = this->AlsaPort;
66     snd_seq_port_subscribe_alloca(&subs);
67     snd_seq_port_subscribe_set_sender(subs, &sender);
68     snd_seq_port_subscribe_set_dest(subs, &dest);
69     snd_seq_port_subscribe_set_queue(subs, 1);
70     snd_seq_port_subscribe_set_time_update(subs, 1);
71     snd_seq_port_subscribe_set_time_real(subs, 1);
72     int res = snd_seq_subscribe_port(this->seq_handle, subs);
73     if (!res) {
74     fprintf(stderr, "Unable to subscribe to client \'%s\'\n", Client);
75     }
76     }
77    
78 schoenebeck 9 int MidiIn::Main() {
79     int res = open_alsa_midi_seq();
80     if (res < 0) {
81     fprintf(stderr,"opening of MIDI in device failed, exiting.\n");
82     exit(1);
83     }
84    
85     int npfd;
86     struct pollfd *pfd;
87     snd_seq_event_t *ev;
88    
89     npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
90     pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
91     snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN);
92     while (true) {
93     if (poll(pfd, npfd, 100000) > 0) {
94     do {
95     snd_seq_event_input(seq_handle, &ev);
96     switch (ev->type) {
97     case SND_SEQ_EVENT_CONTROLLER:
98 schoenebeck 18 pAudioThread->SendControlChange(ev->data.control.channel, ev->data.control.param, ev->data.control.value);
99 schoenebeck 9 break;
100    
101     case SND_SEQ_EVENT_PITCHBEND:
102 senoner 10 // fprintf(stderr, "Pitchbender event on Channel %2d: %5d \n",
103     // ev->data.control.channel, ev->data.control.value);
104 schoenebeck 9 break;
105    
106     case SND_SEQ_EVENT_NOTEON:
107     if (ev->data.note.velocity != 0) {
108 schoenebeck 18 pAudioThread->SendNoteOn(ev->data.note.note, ev->data.note.velocity);
109 schoenebeck 9 }
110     else {
111 schoenebeck 18 pAudioThread->SendNoteOff(ev->data.note.note, 0);
112 schoenebeck 9 }
113     break;
114    
115     case SND_SEQ_EVENT_NOTEOFF:
116 schoenebeck 18 pAudioThread->SendNoteOff(ev->data.note.note, ev->data.note.velocity);
117 schoenebeck 9 break;
118     }
119     snd_seq_free_event(ev);
120     } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
121 schoenebeck 18 }
122     }
123 schoenebeck 9 }
124 senoner 10

  ViewVC Help
Powered by ViewVC