~ubuntu-branches/ubuntu/oneiric/kdelibs/oneiric

« back to all changes in this revision

Viewing changes to .pc/49_hurd_support.diff/libkmid/fmout.cc

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2010-10-15 19:20:42 UTC
  • mfrom: (1.1.19 sid)
  • Revision ID: james.westby@ubuntu.com-20101015192042-jv1fhj33n4f5b398
Tags: 4:3.5.10.dfsg.1-5ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - make sure control and control.in are in sync
  - --with-distribution="Kubuntu (`lsb_release --codename --short`)
    $(DEB_VERSION)"
  - binary-install/kdelibs-data installs aboutkde-kubuntu.png.uu and
    cr*-device-system.png.uu
  - don't build-dep on libgamin-dev, libfam-dev
  - stop kdelibs4-dev depending on gamin/fam
  - don't install .svgz icons, docs or all_languages in kdelibs-data.install
  - rosetta support in rules common-install-prehook-impl:: [and
    common-post-build-arch:: ?] and include debian/kubuntu-desktop-i18n/
  - build-dep on: gettext-kde, kdesdk-scripts, lsb-release, base-files, sudo
  - cdbs build-dep 0.4.41ubuntu2
  - kdelibs4-dev depends on gettext-kde, kdesdk-scripts
  - copy debian/icons over
  - Make kdelibs4c2a depend on launchpad-integration, sudo.  Recommends on
    xdg-user-dirs
  - Remove 19_debianize_useragent.diff (changed to
    kubuntu_19_debianize_useragent.diff) s/Debian/Kubuntu
  - remove kdelibs4c2a depends on menu-xdg
  - include kubuntu_01_kdepot.diff and kde.pot in debian/patches/common
  - use a local copy of kde.mk without the common-install-prehook-impl::
    rule; edit debian-qt-kde.mk to include debian/cdbs/kde.mk
  - build with --with-sudo-kdesu-backend and build-dep on sudo and make
    kdelibs4c2a depend on sudo
  - kdelibs-data.install : Add nzb mimetype
  - Make kdelibs4-dev replace more recent kdelibs4c2a for overlapping files
  - remove /usr/bin/preparetips, arts files and ksvntopng from
    kdelibs4-dev.install
  - Drop the package kdelibs4-doc completely. It contained API documentation
    which is now obsolete, but still available via api.kde.org.
  - make sure control and control.in are in sync
  - in debian/rule remove .pot files outside .po directory
  - 97_automake_cleanup.diff becomes kubuntu_97_automake_cleanup.diff
  - Remove libarts1-dev from build-depends and kdelibs4-dev depends from
    control.in
* Drop kubuntu_98_fix_khc_invocation.diff, replaced by
  68_support_khelpcenter4.diff
* Drop kubuntu_97_automake_cleanup.diff, replaced by 97_automake_cleanup.diff
* Re-add security_05_XMLHttpRequest_vulnerability.diff which has been
  accidentally dropped
* Fix FTBFS, in debian/rules:
  - Add -Wl,--add-needed to LDFLAGS
  - Disable parallel building

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 
 
3
    fmout.cc   - class fmOut which handles the /dev/sequencer device
 
4
                        for fm synths
 
5
    This file is part of LibKMid 0.9.5
 
6
    Copyright (C) 1998,99,2000  Antonio Larrosa Jimenez
 
7
    LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html
 
8
 
 
9
    This library is free software; you can redistribute it and/or
 
10
    modify it under the terms of the GNU Library General Public
 
11
    License as published by the Free Software Foundation; either
 
12
    version 2 of the License, or (at your option) any later version.
 
13
 
 
14
    This library is distributed in the hope that it will be useful,
 
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
    Library General Public License for more details.
 
18
 
 
19
    You should have received a copy of the GNU Library General Public License
 
20
    along with this library; see the file COPYING.LIB.  If not, write to
 
21
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
22
    Boston, MA 02110-1301, USA.
 
23
 
 
24
    Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
 
25
 
 
26
***************************************************************************/
 
27
#include "fmout.h"
 
28
#include <unistd.h>
 
29
#include <fcntl.h>
 
30
#include <stdio.h>
 
31
#include "sndcard.h"
 
32
#include <sys/ioctl.h>
 
33
#include <errno.h>
 
34
#include <string.h>
 
35
#include <sys/param.h>
 
36
#include <stdlib.h>
 
37
#include <limits.h>
 
38
#include "midispec.h"
 
39
#ifdef HAVE_CONFIG_H
 
40
#include <config.h>
 
41
#endif
 
42
 
 
43
SEQ_USE_EXTBUF();
 
44
 
 
45
FMOut::FMOut( int d, int total )
 
46
{
 
47
  seqfd = -1;
 
48
  devicetype = KMID_FM;
 
49
  device = d;
 
50
  _ok = 1;
 
51
  // Put opl=3 for opl/3 (better quality/ 6 voices)
 
52
  //  or opl=2 for fm output (less quality/ 18 voices, which is better imho) :
 
53
  opl = 2;
 
54
  // But be aware that opl=3 is not intended to be fully supported by now
 
55
 
 
56
  nvoices = total;
 
57
  vm = new VoiceManager (nvoices);
 
58
}
 
59
 
 
60
FMOut::~FMOut()
 
61
{
 
62
  closeDev();
 
63
  delete vm;
 
64
  if (deleteFMPatchesDirectory)
 
65
  {
 
66
    free((char *)FMPatchesDirectory);
 
67
    deleteFMPatchesDirectory = 0;
 
68
    FMPatchesDirectory="/etc";
 
69
  }
 
70
}
 
71
 
 
72
void FMOut::openDev (int sqfd)
 
73
{
 
74
#ifdef HAVE_OSS_SUPPORT
 
75
  _ok=1;
 
76
  seqfd = sqfd;
 
77
  //vm->clearLists();
 
78
  if ( seqfd == -1 )
 
79
  {
 
80
    printfdebug("ERROR: Could not open /dev/sequencer\n");
 
81
    return;
 
82
  }
 
83
 
 
84
  loadFMPatches();
 
85
#endif
 
86
 
 
87
}
 
88
 
 
89
void FMOut::closeDev (void)
 
90
{
 
91
  if (!ok()) return;
 
92
  vm->clearLists();
 
93
  //if (seqfd>=0) close(seqfd);
 
94
  seqfd = -1;
 
95
}
 
96
 
 
97
void FMOut::initDev (void)
 
98
{
 
99
#ifdef HAVE_OSS_SUPPORT
 
100
  int chn;
 
101
  if (!ok()) return;
 
102
  uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7};
 
103
  sysex(gm_reset, sizeof(gm_reset));
 
104
  for (chn=0;chn<16;chn++)
 
105
  {
 
106
    chnmute[chn]=0;
 
107
    chnPatchChange(chn,0);
 
108
    chnPressure(chn,127);
 
109
    chnPitchBender(chn, 0x00, 0x40);
 
110
    chnController(chn, CTL_MAIN_VOLUME,127);
 
111
    chnController(chn, CTL_EXT_EFF_DEPTH, 0);
 
112
    chnController(chn, CTL_CHORUS_DEPTH, 0);
 
113
    chnController(chn, 0x4a, 127);
 
114
  }
 
115
 
 
116
  if (opl==3) ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &device);
 
117
  SEQ_VOLUME_MODE(device,VOL_METHOD_LINEAR);
 
118
 
 
119
  for (int i = 0; i < nvoices; i++)
 
120
  {
 
121
    SEQ_CONTROL(device, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
 
122
    SEQ_STOP_NOTE(device, i, vm->note(i), 64);
 
123
  }
 
124
#endif
 
125
}
 
126
 
 
127
void FMOut::loadFMPatches(void)
 
128
{
 
129
#ifdef HAVE_OSS_SUPPORT
 
130
  char patchesfile[PATH_MAX];
 
131
  char drumsfile[PATH_MAX];
 
132
  int size;
 
133
  struct sbi_instrument instr;
 
134
  char tmp[60];
 
135
  int i,j;
 
136
  for ( i=0; i<256; i++ )
 
137
    patchloaded[i] = 0;
 
138
  int stereoeffect=rand()%3;
 
139
  FILE *fh;
 
140
  int datasize;
 
141
 
 
142
  if (opl==3)
 
143
  {
 
144
    snprintf(patchesfile, PATH_MAX, "%s/std.o3",FMPatchesDirectory);
 
145
    size=60;
 
146
  }
 
147
  else
 
148
  {
 
149
    snprintf(patchesfile, PATH_MAX, "%s/std.sb",FMPatchesDirectory);
 
150
    size=52;
 
151
  }
 
152
  fh=fopen(patchesfile,"rb");
 
153
  if (fh==NULL) return;
 
154
 
 
155
  for (i=0;i<128;i++)
 
156
  {
 
157
    fread(tmp,size,1,fh);
 
158
    patchloaded[i]=1;
 
159
    instr.key = ((strncmp(tmp, "4OP", 3) == 0))? OPL3_PATCH : FM_PATCH;
 
160
    datasize = (strncmp(tmp, "4OP", 3) == 0)? 22 : 11;
 
161
    instr.device=device;
 
162
    instr.channel = i;
 
163
    // Let's get some stereo effect ...
 
164
    tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4);
 
165
    stereoeffect=stereoeffect%3;
 
166
    for (j=0; j<22; j++)
 
167
      instr.operators[j] = tmp[j+36];
 
168
    SEQ_WRPATCH(&instr,sizeof(instr));
 
169
  }
 
170
  fclose(fh);
 
171
 
 
172
  if (opl==3)
 
173
  {
 
174
    snprintf(drumsfile, PATH_MAX, "%s/drums.o3",FMPatchesDirectory);
 
175
  }
 
176
  else
 
177
  {
 
178
    snprintf(drumsfile, PATH_MAX, "%s/drums.sb",FMPatchesDirectory);
 
179
  }
 
180
 
 
181
  fh=fopen(drumsfile,"rb");
 
182
  if (fh==NULL) return;
 
183
 
 
184
  for (i=128;i<175;i++)
 
185
  {
 
186
    fread(tmp,size,1,fh);
 
187
    patchloaded[i]=1;
 
188
    instr.key = (strncmp(tmp, "4OP", 3) == 0)? OPL3_PATCH : FM_PATCH;
 
189
    datasize = (strncmp(tmp, "4OP", 3) == 0)? 22 : 11;
 
190
    instr.device=device;
 
191
    instr.channel = i;
 
192
    // Let's get some stereo effect ...
 
193
    tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4);
 
194
    stereoeffect=stereoeffect%3;
 
195
    for (j=0; j<22; j++)
 
196
      instr.operators[j] = tmp[j+36];
 
197
    SEQ_WRPATCH(&instr,sizeof(instr));
 
198
  }
 
199
  fclose(fh);
 
200
 
 
201
#ifdef FMOUTDEBUG
 
202
  printfdebug("Patches loaded\n");
 
203
#endif
 
204
#endif
 
205
}
 
206
 
 
207
int FMOut::patch(int p)
 
208
{
 
209
  if (patchloaded[p]==1) return p;
 
210
#ifdef FMOUTDEBUG
 
211
  printfdebug("Not loaded %d!\n",p);
 
212
#endif
 
213
  p=0;
 
214
  while ((p<256)&&(patchloaded[p]==0)) p++;
 
215
  return p;
 
216
}
 
217
 
 
218
void FMOut::noteOn  (uchar chn, uchar note, uchar vel)
 
219
{
 
220
  if (vel==0)
 
221
  {
 
222
    noteOff(chn,note,vel);
 
223
  }
 
224
  else
 
225
  {
 
226
    if (chn==PERCUSSION_CHANNEL)
 
227
    {
 
228
      if (patchloaded[note+128]==0) return;
 
229
      else
 
230
        if (patchloaded[chnpatch[chn]]==0) return;
 
231
    }
 
232
    int v=vm->allocateVoice(chn,note);
 
233
    int p;
 
234
    if (chn==PERCUSSION_CHANNEL)
 
235
      SEQ_SET_PATCH(device,v ,p=patch(note+128))
 
236
    else
 
237
      SEQ_SET_PATCH(device,v ,p=map->patch(chn,chnpatch[chn]));
 
238
    SEQ_BENDER(device, v, chnbender[chn]);
 
239
 
 
240
    SEQ_START_NOTE(device, v, note, vel);
 
241
    //    SEQ_CONTROL(device, v, CTL_MAIN_VOLUME, chncontroller[chn][CTL_MAIN_VOLUME]);
 
242
 
 
243
    SEQ_CHN_PRESSURE(device, v , chnpressure[chn]);
 
244
  }
 
245
 
 
246
#ifdef FMOUTDEBUG
 
247
  printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
 
248
#endif
 
249
}
 
250
 
 
251
void FMOut::noteOff (uchar chn, uchar note, uchar vel)
 
252
{
 
253
  int i;
 
254
  vm->initSearch();
 
255
  while ((i=vm->search(chn,note))!=-1)
 
256
  {
 
257
    SEQ_STOP_NOTE(device, i, note, vel);
 
258
    vm->deallocateVoice(i);
 
259
  }
 
260
 
 
261
#ifdef FMOUTDEBUG
 
262
  printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
 
263
#endif
 
264
}
 
265
 
 
266
void FMOut::keyPressure (uchar chn, uchar note, uchar vel)
 
267
{
 
268
  int i;
 
269
  vm->initSearch();
 
270
  while ((i=vm->search(chn,note))!=-1)
 
271
    SEQ_KEY_PRESSURE(device, i, note,vel);
 
272
}
 
273
 
 
274
void FMOut::chnPatchChange (uchar chn, uchar patch)
 
275
{
 
276
  if (chn==PERCUSSION_CHANNEL) return;
 
277
  int i;
 
278
  vm->initSearch();
 
279
  while ((i=vm->search(chn))!=-1)
 
280
    SEQ_SET_PATCH(device,i,map->patch(chn,patch));
 
281
 
 
282
  chnpatch[chn]=patch;
 
283
}
 
284
 
 
285
void FMOut::chnPressure (uchar chn, uchar vel)
 
286
{
 
287
  int i;
 
288
  vm->initSearch();
 
289
  while ((i=vm->search(chn))!=-1)
 
290
    SEQ_CHN_PRESSURE(device, i , vel);
 
291
 
 
292
  chnpressure[chn]=vel;
 
293
}
 
294
 
 
295
void FMOut::chnPitchBender(uchar chn,uchar lsb, uchar msb)
 
296
{
 
297
  chnbender[chn]=((int)msb<<7) | (lsb & 0x7F);
 
298
 
 
299
  int i;
 
300
  vm->initSearch();
 
301
  while ((i=vm->search(chn))!=-1)
 
302
    SEQ_BENDER(device, i, chnbender[chn]);
 
303
 
 
304
}
 
305
 
 
306
void FMOut::chnController (uchar chn, uchar ctl, uchar v)
 
307
{
 
308
  if ((ctl==11)||(ctl==7))
 
309
  {
 
310
    v=(v*volumepercentage)/100;
 
311
    if (v>127) v=127;
 
312
  }
 
313
  int i;
 
314
  vm->initSearch();
 
315
  while ((i=vm->search(chn))!=-1)
 
316
    SEQ_CONTROL(device, i, ctl, v);
 
317
 
 
318
  chncontroller[chn][ctl]=v;
 
319
}
 
320
 
 
321
void FMOut::sysex(uchar *, ulong )
 
322
{
 
323
 
 
324
}
 
325
 
 
326
void FMOut::setFMPatchesDirectory(const char *dir)
 
327
{
 
328
  if ((dir==NULL)||(dir[0]==0)) return;
 
329
  if (deleteFMPatchesDirectory)
 
330
        free((char *)FMPatchesDirectory);
 
331
 
 
332
  FMPatchesDirectory = strdup(dir);
 
333
 
 
334
  deleteFMPatchesDirectory=1;
 
335
}
 
336
 
 
337
void FMOut::setVolumePercentage    ( int i )
 
338
{
 
339
#ifdef HAVE_OSS_SUPPORT
 
340
  int fd=open("/dev/mixer0",O_RDWR,0);
 
341
  if (fd==-1) return;
 
342
  int a=i*255/100;
 
343
  if (a>255) a=255;
 
344
  a=(a<<8) | a;
 
345
  if (ioctl(fd,MIXER_WRITE(SOUND_MIXER_SYNTH),&a) == -1)
 
346
    printfdebug("ERROR writing to mixer\n");
 
347
  close(fd);
 
348
#endif
 
349
  volumepercentage=i;
 
350
}
 
351
 
 
352
 
 
353
const char *FMOut::FMPatchesDirectory = "/etc";
 
354
int FMOut::deleteFMPatchesDirectory = 0;