~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to driver/midiserial.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2005-08-23 17:19:39 UTC
  • mto: (4.1.1 breezy) (1.1.9) (10.1.6 sid)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20050823171939-hd8fgzokb4dbj007
Tags: upstream-0.7.1+0.7.2pre2
ImportĀ upstreamĀ versionĀ 0.7.1+0.7.2pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//=========================================================
2
 
//  MusE
3
 
//  Linux Music Editor
4
 
//    $Id: midiserial.cpp,v 1.1.1.1 2003/10/29 10:06:12 wschweer Exp $
5
 
//  (C) Copyright 1999 Werner Schweer (ws@seh.de)
6
 
//=========================================================
7
 
 
8
 
#include <fcntl.h>
9
 
#include <stdio.h>
10
 
#include <unistd.h>
11
 
#include <errno.h>
12
 
 
13
 
#include <qstring.h>
14
 
#include "globals.h"
15
 
#include "midiserial.h"
16
 
#include "xml.h"
17
 
 
18
 
SerialDeviceList serialDevices;
19
 
 
20
 
//---------------------------------------------------------
21
 
//   writeSerialPorts
22
 
//---------------------------------------------------------
23
 
 
24
 
void writeSerialPorts(int level, Xml& xml)
25
 
      {
26
 
      if (serialDevices.empty())
27
 
            return;
28
 
      for (iSerialDevice i = serialDevices.begin(); i != serialDevices.end(); ++i) {
29
 
            xml.tag(level++, "serialPort");
30
 
            xml.strTag(level, "name", (*i)->name());
31
 
            xml.strTag(level, "path", (*i)->path());
32
 
            xml.intTag(level, "type", (*i)->type());
33
 
            xml.intTag(level, "speed", (*i)->speed());
34
 
            xml.intTag(level, "handshaking", (*i)->handshaking());
35
 
            xml.intTag(level, "ports", (*i)->vports());
36
 
            xml.etag(level--, "serialPort");
37
 
            }
38
 
      }
39
 
 
40
 
//---------------------------------------------------------
41
 
//   deleteSerialDevice
42
 
//    return true on error
43
 
//---------------------------------------------------------
44
 
 
45
 
bool deleteSerialDevice(const QString& path)
46
 
      {
47
 
      for (iSerialDevice i = serialDevices.begin(); i != serialDevices.end(); ++i) {
48
 
            if ((*i)->path() == path) {
49
 
                  if ((*i)->fd() != -1) {
50
 
printf("deleteSerialDevice:busy %s\n", path.latin1());
51
 
                        return true;
52
 
                        }
53
 
                  serialDevices.erase(i);
54
 
                  return false;
55
 
                  }
56
 
            }
57
 
      return false;     // ignore "not found" error
58
 
      }
59
 
 
60
 
//---------------------------------------------------------
61
 
//   readSerialPort
62
 
//---------------------------------------------------------
63
 
 
64
 
void readSerialPort(Xml& xml)
65
 
      {
66
 
      SerialDevice* port = new SerialDevice;
67
 
 
68
 
      for (;;) {
69
 
            Xml::Token token = xml.parse();
70
 
            QString tag = xml.s1();
71
 
            if (token == Xml::Error || token == Xml::End)
72
 
                  break;
73
 
            switch (token) {
74
 
                  case Xml::TagStart:
75
 
                        if (tag == "name")
76
 
                              port->setName(xml.parse1());
77
 
                        else if (tag == "path")
78
 
                              port->setPath(xml.parse1());
79
 
                        else if (tag == "type")
80
 
                              port->setType(SerialType(xml.parseInt()));
81
 
                        else if (tag == "speed")
82
 
                              port->setSpeed(xml.parseInt());
83
 
                        else if (tag == "handshaking")
84
 
                              port->setHandshaking(xml.parseInt());
85
 
                        else if (tag == "ports")
86
 
                              port->setVports(xml.parseInt());
87
 
                        else
88
 
                              xml.unknown("serialPort");
89
 
                        break;
90
 
                  case Xml::TagEnd:
91
 
                        if (tag == "serialPort") {
92
 
                              serialDevices.push_back(port);
93
 
                              for (int i = 0; i < port->vports(); ++i) {
94
 
                                    QString name = port->name();
95
 
                                    if (port->vports() > 1) {
96
 
                                          QString pn;
97
 
                                          pn.setNum(i+1);
98
 
                                          name += "-" + pn;
99
 
                                          }
100
 
                                    MidiSerialDevice* dev = new MidiSerialDevice(port, i, name);
101
 
                                    midiDevices.add(dev);
102
 
                                    }
103
 
                              return;
104
 
                              }
105
 
                  default:
106
 
                        break;
107
 
                  }
108
 
            }
109
 
      }
110
 
 
111
 
//---------------------------------------------------------
112
 
//   SerialDevice
113
 
//---------------------------------------------------------
114
 
 
115
 
SerialDevice::SerialDevice(const QString& p, SerialType t,
116
 
   int s, int vd)
117
 
      {
118
 
      _type   = t;
119
 
      _path   = p;
120
 
      _fd     = -1;
121
 
      refs    = 0;
122
 
      _speed  = s;
123
 
      _vports = vd;
124
 
      curPort = (_vports == 1) ? 0 : -1;
125
 
      }
126
 
 
127
 
SerialDevice::SerialDevice()
128
 
      {
129
 
      _type = RAW_DEVICE;
130
 
      _fd   = -1;
131
 
      refs  = 0;
132
 
      curPort = -1;
133
 
      }
134
 
 
135
 
SerialDevice::~SerialDevice()
136
 
      {
137
 
      close(0);
138
 
      }
139
 
 
140
 
//---------------------------------------------------------
141
 
//   setVports
142
 
//---------------------------------------------------------
143
 
 
144
 
void SerialDevice::setVports(int v)
145
 
      {
146
 
      _vports = v;
147
 
      if (_vports == 1)
148
 
            curPort = 0;
149
 
      }
150
 
 
151
 
//---------------------------------------------------------
152
 
//   incRef
153
 
//---------------------------------------------------------
154
 
 
155
 
void SerialDevice::incRef(int val)
156
 
      {
157
 
      refs += val;
158
 
      if (refs <= 0) {
159
 
//            printf("incRef %d: close\n", val);
160
 
            close(_fd);
161
 
            refs = 0;
162
 
            }
163
 
      }
164
 
 
165
 
//---------------------------------------------------------
166
 
//   open
167
 
//---------------------------------------------------------
168
 
 
169
 
const QString SerialDevice::open(int)
170
 
      {
171
 
      if (_fd == -1) {
172
 
            _fd = ::open(_path.latin1(), O_RDWR | O_NDELAY);
173
 
            if (_fd == -1)
174
 
                  return QString(strerror(errno));
175
 
            if (_type == SERIAL_PORT) {
176
 
                  struct termios term;
177
 
                  if (tcgetattr(_fd, &term) == -1) {
178
 
                        printf("serialOpen(%s): tcgetattr failed: %s\n",
179
 
                           _path.latin1(), strerror(errno));
180
 
                        int e = errno;
181
 
                        ::close(_fd);
182
 
                        _fd = -1;
183
 
                        return QString(strerror(e));
184
 
                        }
185
 
                  term.c_iflag = IGNBRK;
186
 
                  term.c_oflag &= ~OPOST;
187
 
                  term.c_cflag = CS8 | CREAD | CLOCAL;
188
 
                  term.c_lflag = 0;
189
 
                  term.c_cc[VTIME] = 0;
190
 
                  term.c_cc[VMIN]  = 0;
191
 
                  cfsetispeed(&term, _speed);
192
 
                  cfsetospeed(&term, _speed);
193
 
                  if (tcsetattr(_fd, TCSANOW, &term) == -1) {
194
 
                        printf("serialOpen(%s): tcsetattr failed: %s\n",
195
 
                           _path.latin1(), strerror(errno));
196
 
                        int e = errno;
197
 
                        ::close(_fd);
198
 
                        _fd = -1;
199
 
                        return QString(strerror(e));
200
 
                        }
201
 
                  }
202
 
            }
203
 
      return QString((_fd != -1) ? "OK" : strerror(errno));
204
 
      }
205
 
 
206
 
//---------------------------------------------------------
207
 
//   close
208
 
//---------------------------------------------------------
209
 
 
210
 
void SerialDevice::close(int)
211
 
      {
212
 
      if (_fd != -1) {
213
 
            printf("close <%s>: %d\n", _path.latin1(), _fd);
214
 
            ::close(_fd);
215
 
            }
216
 
      _fd = -1;
217
 
      }
218
 
 
219
 
//---------------------------------------------------------
220
 
//   read
221
 
//---------------------------------------------------------
222
 
 
223
 
int SerialDevice::read(int, unsigned char* buffer, int n)
224
 
      {
225
 
      if (_fd == -1)
226
 
            return 0;
227
 
      return ::read(_fd, buffer, n);
228
 
      }
229
 
 
230
 
//---------------------------------------------------------
231
 
//   write
232
 
//---------------------------------------------------------
233
 
 
234
 
int SerialDevice::write(int id, const unsigned char* buffer, int n)
235
 
      {
236
 
      if (n == 0 || _fd == -1)
237
 
            return n;
238
 
      if (curPort != id) {
239
 
            char nbuffer[2];
240
 
            nbuffer[0] = 0xf5;
241
 
            nbuffer[1] = id;
242
 
            for (int i = 0; i < 20; ++i) {
243
 
                  int rv = ::write(_fd, nbuffer, 2);
244
 
                  if (midiOutputTrace)
245
 
                        printf("MidiSerial(%s,%d): write 2: 0x%02x 0x%02x\n",
246
 
                           _path.latin1(), id, nbuffer[0] & 0xff, nbuffer[1] & 0xff);
247
 
                  if (!((rv == -1) && (errno == EAGAIN))) {
248
 
                        if (rv == -1) {
249
 
                              printf("MidiSerial(%s): write(%d,xx,%d) <%s>\n",
250
 
                                 _path.latin1(), _fd, 2, strerror(errno));
251
 
                              exit(-1);
252
 
                              }
253
 
                        break;
254
 
                        }
255
 
                  if (midiOutputTrace)
256
 
                        printf("MidiSerial(%s) write(%d,xx,%d) <%s>\n",
257
 
                           _path.latin1(), _fd, 2, strerror(errno));
258
 
                  usleep(1000);
259
 
                  }
260
 
            curPort = id;
261
 
            }
262
 
      if (midiOutputTrace) {
263
 
            printf("MidiSerial<%s>: write %d: ", _path.latin1(), n);
264
 
            for (int i = 0; i < n; ++i)
265
 
                  printf("%02x ", buffer[i]);
266
 
            printf("\n");
267
 
            }
268
 
      int nn = ::write(_fd, buffer, n);
269
 
      if (n != nn) {
270
 
            printf("MidiSerial<%s>: write %d returns %d\n",
271
 
               _path.latin1(), n, nn);
272
 
            }
273
 
      return nn;
274
 
      }
275
 
 
276
 
//---------------------------------------------------------
277
 
//   MidiSerial
278
 
//---------------------------------------------------------
279
 
 
280
 
MidiSerialDevice::MidiSerialDevice(SerialDevice* d, int vd,
281
 
   const QString& n) : MidiRawDevice(n)
282
 
      {
283
 
// printf("add device %s\n", n.latin1());
284
 
      dev     = d;
285
 
      dev->incRef(1);
286
 
      vdev    = vd;
287
 
      _rwFlags = 0x3;
288
 
      }
289
 
 
290
 
MidiSerialDevice::~MidiSerialDevice()
291
 
      {
292
 
      dev->incRef(-1);
293
 
      }
294
 
 
295
 
//---------------------------------------------------------
296
 
//   initMidiSerial
297
 
//    check for raw midi ports
298
 
//          /dev/midiXX
299
 
//          /dev/sound/midiXX
300
 
//    return true on error
301
 
//---------------------------------------------------------
302
 
 
303
 
bool initMidiSerial()
304
 
      {
305
 
      const char* names[] = {
306
 
            "midi%02d", "midi%d"
307
 
            };
308
 
      int devicesFound = 0;
309
 
      for (unsigned k = 0; k < sizeof(names)/sizeof(*names); ++k) {
310
 
            for (int i = 0; i < 8; ++i) {
311
 
                  char buffer[32];
312
 
                  const char* path;
313
 
                  sprintf(buffer, names[k], i);
314
 
                  path = "/dev";
315
 
                  char pathbuffer[64];
316
 
                  sprintf(pathbuffer, "%s/%s", path, buffer);
317
 
                  int fd = ::open(pathbuffer, O_RDWR | O_NDELAY);
318
 
                  if (fd == -1 && (errno == ENOENT || errno == ENXIO)) {
319
 
                        path = "/dev/sound";
320
 
                        sprintf(pathbuffer, "%s/%s", path, buffer);
321
 
                        fd = ::open(pathbuffer, O_RDWR | O_NDELAY);
322
 
                        }
323
 
                  if (fd != -1) {
324
 
                        SerialDevice* sd = new SerialDevice(QString(pathbuffer), RAW_DEVICE, 0, 1);
325
 
                        MidiSerialDevice* dev = new MidiSerialDevice(sd, 0, QString(buffer));
326
 
                        midiDevices.add(dev);
327
 
                        close(fd);
328
 
                        ++devicesFound;
329
 
                        }
330
 
                  }
331
 
            }
332
 
      return devicesFound == 0;
333
 
      }
334