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