~ubuntu-branches/ubuntu/oneiric/oss4/oneiric-proposed

« back to all changes in this revision

Viewing changes to tutorials/sndkit/ossmplay/ossmplay.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Rivera
  • Date: 2011-06-16 20:37:48 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110616203748-jbrxik6ql33z54co
Tags: 4.2-build2004-1ubuntu1
* Merge from Debian unstable.
  - Supports our current kernel (LP: #746048)
  Remaining changes:
  - debian/oss4-dkms.dkms.in: s/source/build/ in Kernel headers paths.
* ld-as-needed.patch: Re-order CC arguments to enable building with ld
  --as-needed (LP: #770972)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define DEB(stmt)       /* stmt */      /* For debug printing */
 
2
#define DEB2(stmt)      /* stmt */      /* For debug printing */
 
3
#define DEB3(stmt)      stmt    /* For debug printing */
 
4
#define DEB_ALWAYS(stmt)        stmt    /* Interesting things */
 
5
 
 
6
#define _INCLUDE_POSIX_SOURCE 1
 
7
#include <stdio.h>
 
8
#include <unistd.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include <ctype.h>
 
12
#include <fcntl.h>
 
13
#include <sys/errno.h>
 
14
#include "../../../include/soundcard.h"
 
15
 
 
16
extern int errno;
 
17
 
 
18
#include "mlib.h"
 
19
 
 
20
SEQ_DEFINEBUF (1024);
 
21
 
 
22
int seqfd;
 
23
mlib_track *tracks[1024];
 
24
int ntrks = 0;
 
25
int dev = 0;
 
26
 
 
27
void
 
28
player ()
 
29
{
 
30
  int i, track;
 
31
  int prev_time = 0;
 
32
 
 
33
  int ptrs[1024] = { 0 };
 
34
  unsigned char *ptr;
 
35
  unsigned char *event;
 
36
  int time, n = 0;
 
37
 
 
38
#if 0
 
39
  for (track = 0; track < ntrks; track++)
 
40
    for (i = 0; i < 128; i++)
 
41
      {
 
42
        if (tracks[track]->pgm_map[i] != -1)
 
43
          {
 
44
            n++;
 
45
            SEQ_LOAD_GMINSTR (dev, i);
 
46
          }
 
47
        tracks[track]->pgm_map[i] = i;
 
48
 
 
49
        if (n == 0)             /* No program changes. Assume pgm# 0 */
 
50
          SEQ_LOAD_GMINSTR (dev, 0);
 
51
 
 
52
        if (tracks[track]->drum_map[i] != -1)
 
53
          SEQ_LOAD_GMDRUM (dev, i);
 
54
        tracks[track]->drum_map[i] = i;
 
55
      }
 
56
 
 
57
  if (n == 0)                   /* No program changes detected */
 
58
    SEQ_LOAD_GMINSTR (dev, 0);  /* Acoustic piano */
 
59
 
 
60
#endif
 
61
 
 
62
  SEQ_START_TIMER ();
 
63
  while (1)
 
64
    {
 
65
      int best = -1, best_time = 0x7fffffff;
 
66
 
 
67
      for (i = 0; i < ntrks; i++)
 
68
        if (ptrs[i] < tracks[i]->len)
 
69
          {
 
70
            ptr = &(tracks[i]->events[ptrs[i] * 12]);
 
71
            event = &ptr[4];
 
72
            time = *(int *) ptr;
 
73
 
 
74
            if (time < best_time)
 
75
              {
 
76
                best = i;
 
77
                best_time = time;
 
78
              }
 
79
          }
 
80
 
 
81
      if (best == -1)
 
82
        return;
 
83
 
 
84
      ptr = &(tracks[best]->events[ptrs[best] * 12]);
 
85
      event = &ptr[4];
 
86
      time = *(int *) ptr;
 
87
      ptrs[best]++;
 
88
 
 
89
      if (event[0] < 128)
 
90
        {
 
91
        }
 
92
      else
 
93
        {
 
94
          int j;
 
95
 
 
96
          if (time > prev_time)
 
97
            {
 
98
              SEQ_WAIT_TIME (time);
 
99
              prev_time = time;
 
100
            }
 
101
 
 
102
          if (event[0] == EV_SYSEX)
 
103
            {
 
104
              event[1] = dev;
 
105
            }
 
106
 
 
107
          if ((event[0] & 0xf0) == 0x90)
 
108
            {
 
109
              event[1] = dev;
 
110
 
 
111
              if (event[0] == EV_CHN_COMMON && event[2] == MIDI_PGM_CHANGE)
 
112
                {
 
113
                  event[4] = tracks[best]->pgm_map[event[4]];
 
114
                }
 
115
            }
 
116
 
 
117
          _SEQ_NEEDBUF (8);
 
118
          memcpy (&_seqbuf[_seqbufptr], event, 8);
 
119
          _SEQ_ADVBUF (8);
 
120
 
 
121
        }
 
122
    }
 
123
}
 
124
 
 
125
int
 
126
main (int argc, char *argv[])
 
127
{
 
128
  mlib_desc *mdesc;
 
129
  int was_last;
 
130
  int tmp, argp = 1;
 
131
  oss_longname_t song_name;
 
132
  char *p, *s, *devname="/dev/midi00";;
 
133
  extern void OSS_set_timebase(int tb);
 
134
 
 
135
  if (argc < 2)
 
136
    {
 
137
      fprintf (stderr, "Usage: %s midifile\n", argv[0]);
 
138
      exit (-1);
 
139
    }
 
140
 
 
141
  if (argc==3)
 
142
  {
 
143
     devname=argv[1];
 
144
     argp++;
 
145
  }
 
146
 
 
147
 
 
148
  if ((seqfd = open (devname, O_WRONLY, 0)) == -1)
 
149
    {
 
150
      perror (devname);
 
151
      exit (-1);
 
152
    }
 
153
  dev=0;
 
154
 
 
155
#ifdef OSSLIB
 
156
  OSS_init (seqfd, 1024);
 
157
#endif
 
158
 
 
159
  if ((mdesc = mlib_open (argv[argp])) == NULL)
 
160
    {
 
161
      fprintf (stderr, "Can't open MIDI file %s: %s\n",
 
162
               argv[argp], mlib_errmsg ());
 
163
      exit (-1);
 
164
    }
 
165
  ioctl(seqfd, SNDCTL_SETSONG, argv[argp]);
 
166
 
 
167
/*
 
168
 * Extract the file name part of the argument
 
169
 */
 
170
 
 
171
  p=s=argv[argp];
 
172
  while (*s)
 
173
  {
 
174
        if (*s=='/')
 
175
           p=s+1;
 
176
        s++;
 
177
  }
 
178
  
 
179
  memset(song_name, 0, sizeof(song_name));
 
180
  strcpy(song_name, p);
 
181
 
 
182
#if 1
 
183
  tmp=MIDI_MODE_TIMED;
 
184
  if (ioctl(seqfd, SNDCTL_MIDI_SETMODE, &tmp)==-1)
 
185
  {
 
186
        perror("SNDCTL_MIDI_SETMODE");
 
187
        exit(-1);
 
188
  }
 
189
#endif
 
190
 
 
191
  tmp = mdesc->hdr.division;
 
192
printf("Timebase %d\n", tmp);
 
193
  OSS_set_timebase(tmp);
 
194
  if (ioctl(seqfd, SNDCTL_MIDI_TIMEBASE, &tmp)==-1)
 
195
  {
 
196
        perror("SNDCTL_MIDI_TIMEBASE");
 
197
        exit(-1);
 
198
  }
 
199
 
 
200
  ntrks = 0;
 
201
 
 
202
  while ((tracks[ntrks] = mlib_loadtrack (mdesc, &was_last)) != NULL)
 
203
    {
 
204
      int i;
 
205
 
 
206
      DEB2 (printf ("Loaded track %03d: len = %d events, flags = %08x\n",
 
207
                    mdesc->curr_trk, tracks[ntrks]->len,
 
208
                    tracks[ntrks]->flags));
 
209
      ntrks++;
 
210
    }
 
211
 
 
212
  if (!was_last)
 
213
    {
 
214
      fprintf (stderr, "%s: %s\n", argv[argp], mlib_errmsg ());
 
215
      exit (-1);
 
216
    }
 
217
 
 
218
  tmp = (int) mdesc->timesig;
 
219
  printf("Timesig %08x\n", tmp);
 
220
 
 
221
/*
 
222
 * Set the current song name (OSS 4.0 feature).
 
223
 */
 
224
  ioctl(seqfd, SNDCTL_SETSONG, song_name);
 
225
  player ();
 
226
  SEQ_DELTA_TIME (mdesc->hdr.division * 8);
 
227
  SEQ_PGM_CHANGE(0, 0, 0);
 
228
  SEQ_DUMPBUF ();
 
229
 
 
230
  mlib_close (mdesc);
 
231
  close (seqfd);
 
232
  exit (0);
 
233
}