Copyright fixes and mpg321 support - Alex
[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
33 #include "tX_endian.h"
34
35 void tX_audiodevice :: init()
36 {
37         samples_per_buffer=0;
38         set_buffersize_near(globals.audiodevice_buffersize);
39 }
40
41
42 void tX_audiodevice :: set_latency_near(int milliseconds)
43 {
44         samples_per_buffer=(int) (((float) milliseconds) * 88.2);
45 }
46
47 int tX_audiodevice :: get_latency()
48 {
49         return ((int) (((float) samples_per_buffer) / 88.2));
50 }
51
52 void tX_audiodevice :: set_buffersize_near(int samples)
53 {
54         samples_per_buffer=samples;
55 }
56
57 int tX_audiodevice :: get_buffersize()
58 {
59         return samples_per_buffer;
60 }
61
62 int tX_audiodevice :: open()
63 {
64         fprintf(stderr, "tX: Error: tX_audiodevice::dev_open()\n");
65         return 1;
66 }
67
68 int tX_audiodevice :: close()
69 {
70         fprintf(stderr, "tX: Error: tX_audiodevice::dev_close()\n");
71         return 1;
72 }
73
74 void tX_audiodevice :: play(int16_t* dummy)
75 {
76         fprintf(stderr, "tX: Error: tX_audiodevice::play()\n");
77 }
78
79 #ifdef USE_OSS
80
81 /* this is required as open() overloads 
82    ansi open() - better solutions anybody? ;)
83 */
84 inline int open_hack(char *name,  int flags, mode_t mode)
85 {
86         return open(name, flags, mode);
87 }
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_hack(globals.audio_device, O_WRONLY, 0);
97         
98         /* setting buffer size */       
99         buff_cfg=(globals.buff_no<<16) | globals.buff_size;
100         
101         p=buff_cfg;
102                 
103         i = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &p);
104
105         ioctl(fd, SNDCTL_DSP_RESET, 0);         
106
107         /* 16 Bits */
108         
109         p =  16;
110
111         i +=  ioctl(fd, SOUND_PCM_WRITE_BITS, &p);
112
113         /* STEREO :) */
114         
115         p =  2;
116         i += ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &p);
117         
118         /* 44.1 khz */
119
120         p =  44100;
121         i += ioctl(fd, SOUND_PCM_WRITE_RATE, &p);
122                 
123         i += ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &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 inline int closewrapper(int fd)
134 {
135         return close(fd);
136 }
137
138 int tX_audiodevice_oss :: close()
139 {
140         void *dummy;
141
142         if (!fd)
143         {       
144                 return(1);              
145         }
146         closewrapper(fd);
147         fd=0;
148         blocksize=0;
149                 
150         return(0);      
151 }
152
153 tX_audiodevice_oss :: tX_audiodevice_oss()
154 {
155         fd=0;
156         blocksize=0;
157         init();
158 }
159
160 void tX_audiodevice_oss :: play(int16_t *buffer)
161 {
162 #ifdef BIG_ENDIAN_MACHINE
163         swapbuffer (buffer, samples);
164 #endif
165         write(fd, buffer, blocksize);   
166 }
167
168 #endif //USE_OSS
169
170 #ifdef USE_ALSA
171
172 int tX_audiodevice_alsa :: open()
173 {
174         return 1;
175 }
176
177 int tX_audiodevice_alsa :: close()
178 {
179         return 1;
180 }
181
182 tX_audiodevice_alsa :: tX_audiodevice_alsa()
183 {
184         init();
185 }
186
187 void tX_audiodevice_alsa :: play(int16_t *buffer)
188 {
189 #ifdef BIG_ENDIAN_MACHINE
190         swapbuffer (buffer, samples);
191 #endif
192         /***/
193 }
194
195 #endif //USE_ALSA