1 /* SpiralSynth
2 * Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "Output.h"
20
Output()21 Output::Output() :
22 m_Amp(0.5)
23 {
24 Init();
25 m_Buffer = new short[SpiralInfo::BUFSIZE];
26 for (int n=0; n<SpiralInfo::BUFSIZE; n++)
27 {
28 m_Buffer[n]=0;
29 }
30 }
31
Send(short * data)32 void Output::Send(short *data)
33 {
34 for (int n=0; n<SpiralInfo::BUFSIZE; n++)
35 {
36 data[n]=static_cast<short>(data[n]*m_Amp);
37
38 // clip
39 if (data[n]<-SpiralInfo::MAXSAMPLE/2) data[n]=static_cast<short>(-SpiralInfo::MAXSAMPLE/2);
40 if (data[n]>SpiralInfo::MAXSAMPLE/2) data[n]=static_cast<short>(SpiralInfo::MAXSAMPLE/2);
41
42 m_Buffer[n]+=(short)(data[n]);
43 }
44 }
45
Play()46 void Output::Play()
47 {
48 #if __BYTE_ORDER == BIG_ENDIAN
49 static short *buf16 = new short[SpiralInfo::BUFSIZE];
50 for (int n=0; n<SpiralInfo::BUFSIZE; n++)
51 {
52 buf16[n]=(short)((m_Buffer[n]<<8)&0xff00) | ((m_Buffer[n]>>8)&0xff);
53 }
54 if (SpiralInfo::REALTIMEOUT)
55 {
56 write(m_Dspfd,buf16,sizeof(short)*SpiralInfo::BUFSIZE);
57 }
58
59 if(m_Wav.Recording())
60 {
61 m_Wav.Save(SpiralInfo::BUFSIZE,buf16);
62 }
63 #else
64 if (SpiralInfo::REALTIMEOUT)
65 {
66 write(m_Dspfd,m_Buffer,sizeof(short)*SpiralInfo::BUFSIZE);
67 }
68
69 if(m_Wav.Recording())
70 {
71 m_Wav.Save(SpiralInfo::BUFSIZE,m_Buffer);
72 }
73 #endif
74 }
75
ClearBuffer()76 void Output::ClearBuffer()
77 {
78 for (int n=0; n<SpiralInfo::BUFSIZE; n++)
79 {
80 m_Buffer[n]=0;
81 }
82 }
83
Init()84 void Output::Init()
85 {
86 if (!SpiralInfo::REALTIMEOUT)
87 {
88 return;
89 }
90
91 int r,val;
92
93 m_Dspfd = open(SpiralInfo::OUTPUTFILE.c_str(),O_WRONLY);
94 if(m_Dspfd<0)
95 {
96 fprintf(stderr,"Can't open audio driver.\n");
97 exit(999);
98 }
99
100 r = ioctl(m_Dspfd,SNDCTL_DSP_RESET,NULL);
101
102 if (r>=0)
103 {
104 val=262152;
105 r=ioctl(m_Dspfd, SNDCTL_DSP_SETFRAGMENT, &val);
106 }
107 if(r>=0)
108 {
109 val = 1;
110 r = ioctl(m_Dspfd, SOUND_PCM_WRITE_CHANNELS, &val);
111 }
112 if(r>=0)
113 {
114 val = AFMT_S16_LE;
115 r = ioctl(m_Dspfd,SNDCTL_DSP_SETFMT,&val);
116 }
117 if(r>=0)
118 {
119 val = 0;
120 r = ioctl(m_Dspfd,SNDCTL_DSP_STEREO,&val);
121 }
122 if(r>=0)
123 {
124 val = SpiralInfo::SAMPLERATE;
125 r = ioctl(m_Dspfd,SNDCTL_DSP_SPEED,&val);
126 }
127 if(r<0)
128 {
129 fprintf(stderr,"Sound device did not accept settings.\n");
130 exit(999);
131 }
132 }
133
134