Making MIDI Mappings persistent - Alex
[terminatorX.git] / terminatorX / src / tX_audiodevice.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2002  Alexander K├Ânig
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  
19     File: tX_aduiodevice.cc
20  
21     Description: Implements Audiodevice handling... 
22 */    
23
24 #include "tX_audiodevice.h"
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/ioctl.h>
29 #include <fcntl.h>
30 #include <sys/soundcard.h>
31 #include <config.h>
32
33 #include "tX_endian.h"
34
35 #ifndef __USE_XOPEN
36 #       define __USE_XOPEN // we need this for swab()
37 #       include <unistd.h>
38 #       undef __USE_XOPEN
39 #else
40 #       include <unistd.h>
41 #endif
42
43 #include <string.h>
44 #include <errno.h>
45 #include <stdlib.h>
46
47 void tX_audiodevice :: init()
48 {
49         samples_per_buffer=0;
50         set_buffersize_near(globals.audiodevice_buffersize);
51 }
52
53
54 void tX_audiodevice :: set_latency_near(int milliseconds)
55 {
56         samples_per_buffer=(int) (((float) milliseconds) * 88.2);
57 }
58
59 int tX_audiodevice :: get_latency()
60 {
61         return ((int) (((float) samples_per_buffer) / 88.2));
62 }
63
64 void tX_audiodevice :: set_buffersize_near(int samples)
65 {
66         samples_per_buffer=samples;
67 }
68
69 int tX_audiodevice :: get_buffersize()
70 {
71         return samples_per_buffer;
72 }
73
74 int tX_audiodevice :: open()
75 {
76         fprintf(stderr, "tX: Error: tX_audiodevice::dev_open()\n");
77         return 1;
78 }
79
80 int tX_audiodevice :: close()
81 {
82         fprintf(stderr, "tX: Error: tX_audiodevice::dev_close()\n");
83         return 1;
84 }
85
86 void tX_audiodevice :: play(int16_t* dummy)
87 {
88         fprintf(stderr, "tX: Error: tX_audiodevice::play()\n");
89 }
90
91 #ifdef USE_OSS
92
93 int tX_audiodevice_oss :: open()
94 {
95         int i=0;
96         int p;
97         int buff_cfg;
98
99         if (fd) return (1);
100         fd = ::open(globals.audio_device, O_WRONLY, 0);
101         
102         /* setting buffer size */       
103         buff_cfg=(globals.buff_no<<16) | globals.buff_size;
104
105         tX_debug("tX_adudiodevice_oss::open() - buff_no: %i, buff_size: %i, buff_cfg: %08x", globals.buff_no, globals.buff_size, buff_cfg);
106         
107         p=buff_cfg;
108                 
109         i = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &p);
110
111         ioctl(fd, SNDCTL_DSP_RESET, 0);         
112
113         /* 16 Bits */
114         
115         p =  16;
116
117         i +=  ioctl(fd, SOUND_PCM_WRITE_BITS, &p);
118
119         /* STEREO :) */
120         
121         p =  2;
122         i += ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &p);
123         
124         /* 44.1 khz */
125
126         p =  44100;
127         i += ioctl(fd, SOUND_PCM_WRITE_RATE, &p);
128                 
129         i += ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);
130
131         tX_debug("tX_adudiodevice_oss::open() - blocksize: %i", blocksize);
132
133         samples_per_buffer=blocksize/sizeof(int16_t);
134         globals.true_block_size=samples_per_buffer/2;
135         
136         ioctl(fd, SNDCTL_DSP_SYNC, 0);
137
138         return(i);      
139 }
140
141 int tX_audiodevice_oss :: close()
142 {
143         if (!fd)
144         {       
145                 return(1);              
146         }
147         ::close(fd);
148         fd=0;
149         blocksize=0;
150                 
151         return(0);      
152 }
153
154 tX_audiodevice_oss :: tX_audiodevice_oss()
155 {
156         fd=0;
157         blocksize=0;
158         init();
159 }
160
161 void tX_audiodevice_oss :: play(int16_t *buffer)
162 {
163 #ifdef BIG_ENDIAN_MACHINE
164         swapbuffer (buffer, samples_per_buffer);
165 #endif
166         int res=write(fd, buffer, blocksize);   
167         if (res==-1) {
168                 tX_error("failed to write to audiodevice: %s", strerror(errno));
169                 exit(-1);
170         }
171 }
172
173 #endif //USE_OSS
174
175 #ifdef USE_ALSA
176
177 int tX_audiodevice_alsa :: open()
178 {
179         return 1;
180 }
181
182 int tX_audiodevice_alsa :: close()
183 {
184         return 1;
185 }
186
187 tX_audiodevice_alsa :: tX_audiodevice_alsa()
188 {
189         init();
190 }
191
192 void tX_audiodevice_alsa :: play(int16_t *buffer)
193 {
194 #ifdef BIG_ENDIAN_MACHINE
195         swapbuffer (buffer, samples_per_buffer);
196 #endif
197         /***/
198 }
199
200 #endif //USE_ALSA