Removed lots of old code - fixed a record-to-wav error with the
[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 <unistd.h>
30 #include <fcntl.h>
31 #include <sys/soundcard.h>
32 #include <config.h>
33
34 #include "tX_endian.h"
35
36 void tX_audiodevice :: init()
37 {
38         samples_per_buffer=0;
39         set_buffersize_near(globals.audiodevice_buffersize);
40 }
41
42
43 void tX_audiodevice :: set_latency_near(int milliseconds)
44 {
45         samples_per_buffer=(int) (((float) milliseconds) * 88.2);
46 }
47
48 int tX_audiodevice :: get_latency()
49 {
50         return ((int) (((float) samples_per_buffer) / 88.2));
51 }
52
53 void tX_audiodevice :: set_buffersize_near(int samples)
54 {
55         samples_per_buffer=samples;
56 }
57
58 int tX_audiodevice :: get_buffersize()
59 {
60         return samples_per_buffer;
61 }
62
63 int tX_audiodevice :: open()
64 {
65         fprintf(stderr, "tX: Error: tX_audiodevice::dev_open()\n");
66         return 1;
67 }
68
69 int tX_audiodevice :: close()
70 {
71         fprintf(stderr, "tX: Error: tX_audiodevice::dev_close()\n");
72         return 1;
73 }
74
75 void tX_audiodevice :: play(int16_t* dummy)
76 {
77         fprintf(stderr, "tX: Error: tX_audiodevice::play()\n");
78 }
79
80 #ifdef USE_OSS
81
82 /* this is required as open() overloads 
83    ansi open() - better solutions anybody? ;)
84 */
85 inline int open_hack(char *name,  int flags, mode_t mode)
86 {
87         return open(name, flags, mode);
88 }
89
90 int tX_audiodevice_oss :: open()
91 {
92         int i=0;
93         int p;
94         int buff_cfg;
95
96         if (fd) return (1);
97         fd = open_hack(globals.audio_device, O_WRONLY, 0);
98         
99         /* setting buffer size */       
100         buff_cfg=(globals.buff_no<<16) | globals.buff_size;
101
102         tX_debug("tX_adudiodevice_oss::open() - buff_no: %i, buff_size: %i, buff_cfg: %08x", globals.buff_no, globals.buff_size, buff_cfg);
103         
104         p=buff_cfg;
105                 
106         i = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &p);
107
108         ioctl(fd, SNDCTL_DSP_RESET, 0);         
109
110         /* 16 Bits */
111         
112         p =  16;
113
114         i +=  ioctl(fd, SOUND_PCM_WRITE_BITS, &p);
115
116         /* STEREO :) */
117         
118         p =  2;
119         i += ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &p);
120         
121         /* 44.1 khz */
122
123         p =  44100;
124         i += ioctl(fd, SOUND_PCM_WRITE_RATE, &p);
125                 
126         i += ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);
127
128         tX_debug("tX_adudiodevice_oss::open() - blocksize: %i", blocksize);
129
130         samples_per_buffer=blocksize/sizeof(int16_t);
131         globals.true_block_size=samples_per_buffer/2;
132         
133         ioctl(fd, SNDCTL_DSP_SYNC, 0);
134
135         return(i);      
136 }
137
138 inline int closewrapper(int fd)
139 {
140         return close(fd);
141 }
142
143 int tX_audiodevice_oss :: close()
144 {
145         void *dummy;
146
147         if (!fd)
148         {       
149                 return(1);              
150         }
151         closewrapper(fd);
152         fd=0;
153         blocksize=0;
154                 
155         return(0);      
156 }
157
158 tX_audiodevice_oss :: tX_audiodevice_oss()
159 {
160         fd=0;
161         blocksize=0;
162         init();
163 }
164
165 void tX_audiodevice_oss :: play(int16_t *buffer)
166 {
167 #ifdef BIG_ENDIAN_MACHINE
168         swapbuffer (buffer, samples_per_buffer);
169 #endif
170         write(fd, buffer, blocksize);   
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