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