1 /* 2 TiMidity++ -- MIDI to WAVE converter and player 3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp> 4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 testnull11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20 bsd20_a.c 21 Written by Yamate Keiichiro <keiich-y@is.aist-nara.ac.jp> 22 */ 23 24 /* 25 * BSD/OS 2.0 audio 26 */ 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif /* HAVE_CONFIG_H */ 30 #include <stdio.h> 31 #include <unistd.h> 32 #include <fcntl.h> 33 #include <i386/isa/sblast.h> 34 35 #include "timidity.h" 36 #include "output.h" 37 #include "controls.h" 38 #include "timer.h" 39 #include "instrum.h" 40 #include "playmidi.h" 41 #include "miditrace.h" 42 43 static int open_output(void); /* 0=success, 1=warning, -1=fatal error */ 44 static void close_output(void); 45 static int output_data(char *buf, int32 nbytes); 46 static int acntl(int request, void *arg); 47 48 /* export the playback mode */ 49 50 #define dpm bsdi_play_mode 51 52 PlayMode dpm = { 53 DEFAULT_RATE, PE_SIGNED|PE_MONO, PF_PCM_STREAM|PF_CAN_TRACE, 54 -1, 55 {0}, /* default: get all the buffer fragments you can */ 56 "BSD/OS sblast dsp", 'd', 57 "/dev/sb_dsp", 58 open_output, 59 close_output, 60 output_data, 61 acntl 62 }; 63 64 static int open_output(void) 65 { 66 int fd, tmp, warnings=0; 67 68 if ((fd=open(dpm.name, O_RDWR | O_NDELAY, 0)) < 0) 69 { 70 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 71 dpm.name, strerror(errno)); 72 return -1; 73 } 74 75 /* They can't mean these */ 76 dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP); 77 78 79 /* Set sample width to whichever the user wants. If it fails, try 80 the other one. */ 81 82 if (dpm.encoding & PE_16BIT) 83 { 84 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: sblast only 8bit", 85 dpm.name); 86 close(fd); 87 return -1; 88 } 89 90 tmp = ((~dpm.encoding) & PE_16BIT) ? PCM_8 : 0; 91 ioctl(fd, DSP_IOCTL_COMPRESS, &tmp); 92 dpm.encoding &= ~PE_SIGNED; 93 94 /* Try stereo or mono, whichever the user wants. If it fails, try 95 the other. */ 96 97 tmp=(dpm.encoding & PE_MONO) ? 0 : 1; 98 ioctl(fd, DSP_IOCTL_STEREO, &tmp); 99 100 /* Set the sample rate */ 101 102 tmp=dpm.rate * ((dpm.encoding & PE_MONO) ? 1 : 2); 103 ioctl(fd, DSP_IOCTL_SPEED, &tmp); 104 if (tmp != dpm.rate) 105 { 106 dpm.rate=tmp / ((dpm.encoding & PE_MONO) ? 1 : 2);; 107 ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 108 "Output rate adjusted to %d Hz", dpm.rate); 109 warnings=1; 110 } 111 112 /* Older VoxWare drivers don't have buffer fragment capabilities */ 113 114 if (dpm.extra_param[0]) 115 { 116 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 117 "%s doesn't support buffer fragments", dpm.name); 118 warnings=1; 119 } 120 121 tmp = 16384; 122 ioctl(fd, DSP_IOCTL_BUFSIZE, &tmp); 123 124 dpm.fd = fd; 125 return warnings; 126 } 127 128 static int output_data(char *buf, int32 nbytes) 129 { 130 while ((-1==write(dpm.fd, buf, nbytes)) && errno==EINTR) 131 ; 132 } 133 134 static void close_output(void) 135 { 136 if(dpm.fd != -1) 137 { 138 close(dpm.fd); 139 dpm.fd = -1; 140 } 141 } 142 143 static int acntl(int request, void *arg) 144 { 145 switch(request) 146 { 147 case PM_REQ_DISCARD: 148 return ioctl(dpm.fd, DSP_IOCTL_RESET); 149 150 case PM_REQ_PLAY_START: /* Called just before playing */ 151 case PM_REQ_PLAY_END: /* Called just after playing */ 152 return 0; 153 } 154 return -1; 155 } 156