XML serialization for set files, bug fixes and a new full screen mode
[terminatorX.git] / 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 void tX_audiodevice :: init()
44 {
45         samples_per_buffer=0;
46         set_buffersize_near(globals.audiodevice_buffersize);
47 }
48
49
50 void tX_audiodevice :: set_latency_near(int milliseconds)
51 {
52         samples_per_buffer=(int) (((float) milliseconds) * 88.2);
53 }
54
55 int tX_audiodevice :: get_latency()
56 {
57         return ((int) (((float) samples_per_buffer) / 88.2));
58 }
59
60 void tX_audiodevice :: set_buffersize_near(int samples)
61 {
62         samples_per_buffer=samples;
63 }
64
65 int tX_audiodevice :: get_buffersize()
66 {
67         return samples_per_buffer;
68 }
69
70 int tX_audiodevice :: open()
71 {
72         fprintf(stderr, "tX: Error: tX_audiodevice::dev_open()\n");
73         return 1;
74 }
75
76 int tX_audiodevice :: close()
77 {
78         fprintf(stderr, "tX: Error: tX_audiodevice::dev_close()\n");
79         return 1;
80 }
81
82 void tX_audiodevice :: play(int16_t* dummy)
83 {
84         fprintf(stderr, "tX: Error: tX_audiodevice::play()\n");
85 }
86
87 #ifdef USE_OSS
88
89 int tX_audiodevice_oss :: open()
90 {
91         int i=0;
92         int p;
93         int buff_cfg;
94
95         if (fd) return (1);
96         fd = ::open(globals.audio_device, O_WRONLY, 0);
97         
98         /* setting buffer size */       
99         buff_cfg=(globals.buff_no<<16) | globals.buff_size;
100
101         tX_debug("tX_adudiodevice_oss::open() - buff_no: %i, buff_size: %i, buff_cfg: %08x", globals.buff_no, globals.buff_size, buff_cfg);
102         
103         p=buff_cfg;
104                 
105         i = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &p);
106
107         ioctl(fd, SNDCTL_DSP_RESET, 0);         
108
109         /* 16 Bits */
110         
111         p =  16;
112
113         i +=  ioctl(fd, SOUND_PCM_WRITE_BITS, &p);
114
115         /* STEREO :) */
116         
117         p =  2;
118         i += ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &p);
119         
120         /* 44.1 khz */
121
122         p =  44100;
123         i += ioctl(fd, SOUND_PCM_WRITE_RATE, &p);
124                 
125         i += ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);
126
127         tX_debug("tX_adudiodevice_oss::open() - blocksize: %i", blocksize);
128
129         samples_per_buffer=blocksize/sizeof(int16_t);
130         globals.true_block_size=samples_per_buffer/2;
131         
132         ioctl(fd, SNDCTL_DSP_SYNC, 0);
133
134         return(i);      
135 }
136
137 int tX_audiodevice_oss :: close()
138 {
139         if (!fd)
140         {       
141                 return(1);              
142         }
143         ::close(fd);
144         fd=0;
145         blocksize=0;
146                 
147         return(0);      
148 }
149
150 tX_audiodevice_oss :: tX_audiodevice_oss()
151 {
152         fd=0;
153         blocksize=0;
154         init();
155 }
156
157 void tX_audiodevice_oss :: play(int16_t *buffer)
158 {
159 #ifdef BIG_ENDIAN_MACHINE
160         swapbuffer (buffer, samples_per_buffer);
161 #endif
162         write(fd, buffer, blocksize);   
163 }
164
165 #endif //USE_OSS
166
167 #ifdef USE_ALSA
168
169 int tX_audiodevice_alsa :: open()
170 {
171         return 1;
172 }
173
174 int tX_audiodevice_alsa :: close()
175 {
176         return 1;
177 }
178
179 tX_audiodevice_alsa :: tX_audiodevice_alsa()
180 {
181         init();
182 }
183
184 void tX_audiodevice_alsa :: play(int16_t *buffer)
185 {
186 #ifdef BIG_ENDIAN_MACHINE
187         swapbuffer (buffer, samples_per_buffer);
188 #endif
189         /***/
190 }
191
192 #endif //USE_ALSA