1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (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.
12 
13 See the 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #ifdef DOS
22 #include <mem.h>
23 #endif
24 
25 #include "rt_def.h"
26 #include "rt_util.h"
27 #include "rt_sound.h"
28 #include "rt_net.h"
29 #include "rt_dmand.h"
30 #include "_rt_dman.h"
31 #include "fx_man.h"
32 #include "develop.h"
33 //MED
34 #include "memcheck.h"
35 
36 static boolean Recording=false;
37 static boolean Feeder=false;
38 static byte * RecordingBuffer;
39 static int Playingvoice;
40 static int RecordingPointer;
41 static int FeederPointer;
42 static boolean Playback=false;
43 static boolean Playing=false;
44 static byte * PlaybackBuffer;
45 static int PlaybackPointer;
46 static int PlayingPointer;
47 static boolean RecordingSemaphore=false;
48 
49 //#define FX_StartDemandFeedPlayback MV_StartDemandFeedPlayback
50 //#define FX_StartRecording          MV_StartRecording
51 //#define FX_StopRecord              MV_StopRecord
52 //#include "multivoc.h"
53 
54 //***************************************************************************
55 //
56 // SD_UpdatePlaybackSound - Update playback of a sound in chunks
57 //
58 //***************************************************************************
SD_UpdatePlaybackSound(char ** ptr,unsigned long * length)59 void SD_UpdatePlaybackSound ( char ** ptr, unsigned long * length )
60    {
61    if ( Playing==false )
62       {
63       *ptr = NULL;
64       *length = 0;
65       return;
66       }
67    if (PlayingPointer==PlaybackPointer)
68       {
69       *ptr = NULL;
70       *length = 0;
71       if (Playback==false)
72          {
73          FX_StopSound( Playingvoice );
74          SafeFree ( PlaybackBuffer );
75          Playing=false;
76          }
77       return;
78       }
79 
80    *length=PLAYBACKDELTASIZE;
81 
82    if (PlayingPointer==-1)
83       {
84       *ptr = NULL;
85       *length = 0;
86       return;
87       }
88 
89    *ptr=&PlaybackBuffer[PlayingPointer];
90 
91    PlayingPointer = (PlayingPointer + *length) &
92                       (PLAYBACKBUFFERSIZE - 1);
93    }
94 
95 //***************************************************************************
96 //
97 // SD_StartIncomingSound - Setup to receive an incoming sound in chunks
98 //
99 //***************************************************************************
100 
SD_StartIncomingSound(void)101 void SD_StartIncomingSound ( void )
102 {
103    if (SD_Started==false)
104       return;
105    if ( ( Recording==true ) || ( Playback==true ) )
106       {
107       return;
108       }
109 
110    Playback=true;
111    PlaybackBuffer = SafeMalloc (PLAYBACKBUFFERSIZE);
112    Playing = false;
113    PlayingPointer = -1;
114    PlaybackPointer = 0;
115 
116    Playingvoice = FX_StartDemandFeedPlayback ( SD_UpdatePlaybackSound,
117                   RECORDINGSAMPLERATE,
118                   0, 255, 255, 255, 255, -1);
119    if (Playingvoice==0)
120       {
121       SafeFree(PlaybackBuffer);
122       Playback=false;
123       }
124 }
125 
126 //***************************************************************************
127 //
128 // SD_StopIncomingSound - Stop receiving an incoming sound and playback
129 //
130 //***************************************************************************
131 
SD_StopIncomingSound(void)132 void SD_StopIncomingSound ( void )
133 {
134    if (SD_Started==false)
135       return;
136    Playback=false;
137 }
138 
139 
140 //***************************************************************************
141 //
142 // SD_UpdateIncomingSound - Update an incoming sound
143 //
144 //***************************************************************************
145 
SD_UpdateIncomingSound(byte * ptr,word length)146 void SD_UpdateIncomingSound ( byte * ptr, word length )
147 {
148    int amount;
149 
150    if (SD_Started==false)
151       return;
152 
153    if ( Playback==false )
154       {
155       return;
156       }
157    amount=length;
158    if (PlaybackPointer+length > PLAYBACKBUFFERSIZE)
159       amount=PLAYBACKBUFFERSIZE-PlaybackPointer;
160    memcpy ( &PlaybackBuffer[PlaybackPointer],
161             ptr, amount);
162    PlaybackPointer = (PlaybackPointer + amount) &
163                       (PLAYBACKBUFFERSIZE - 1);
164 
165    ptr+=amount;
166 
167    if (length!=amount)
168       {
169       amount=length-amount;
170       memcpy ( &PlaybackBuffer[PlaybackPointer],
171                ptr, amount);
172       PlaybackPointer = (PlaybackPointer + amount) &
173                          (PLAYBACKBUFFERSIZE - 1);
174       }
175 
176    if (PlayingPointer==-1)
177       {
178       Playing=true;
179       PlayingPointer=0;
180       }
181    if (PlaybackPointer==PlayingPointer)
182       {
183       Playback=false;
184       }
185 }
186 
187 //***************************************************************************
188 //
189 // SD_UpdateRecordingSound - Update recording a sound in chunks
190 //
191 //***************************************************************************
192 extern int whereami;
SD_UpdateRecordingSound(char * ptr,int length)193 void SD_UpdateRecordingSound ( char * ptr, int length )
194    {
195    int amount;
196 
197    whereami = 69;
198    if ( Recording==false )
199       {
200       return;
201       }
202    whereami = 70;
203    amount=length;
204    if (RecordingPointer+length > RECORDINGBUFFERSIZE)
205       amount=RECORDINGBUFFERSIZE-RecordingPointer;
206    memcpy ( &RecordingBuffer[RecordingPointer],
207             ptr, amount);
208    whereami = 71;
209    RecordingPointer = (RecordingPointer + amount) &
210                       (RECORDINGBUFFERSIZE - 1);
211 
212    if (length!=amount)
213       {
214       ptr += amount;
215       amount=length-amount;
216       memcpy ( &RecordingBuffer[RecordingPointer],
217                ptr, amount);
218       RecordingPointer = (RecordingPointer + amount) &
219                          (RECORDINGBUFFERSIZE - 1);
220       }
221    whereami = 72;
222    if (Feeder == false)
223       {
224       Feeder = true;
225       }
226 
227    whereami = 73;
228    if (RecordingPointer==FeederPointer)
229       {
230       Recording=false;
231       }
232    whereami = 74;
233    }
234 
235 //***************************************************************************
236 //
237 // SD_StartRecordingSound - Start recording a sound in chunks
238 //
239 //***************************************************************************
240 
SD_StartRecordingSound(void)241 boolean SD_StartRecordingSound ( void )
242 {
243    int status;
244 
245    if (SD_Started==false)
246       return false;
247    if (remoteridicule == false)
248       return false;
249    if ( ( Recording==true ) || ( Playback==true ) || (Feeder==true))
250       {
251       return false;
252       }
253    Recording=true;
254    RecordingBuffer = SafeMalloc (RECORDINGBUFFERSIZE);
255    Feeder = false;
256    FeederPointer = -1;
257    RecordingPointer = 0;
258 
259    status=FX_StartRecording( RECORDINGSAMPLERATE, SD_UpdateRecordingSound);
260 
261    if (status!=FX_Ok)
262       {
263       Recording=false;
264       SafeFree(RecordingBuffer);
265       return false;
266       }
267 
268    return true;
269 }
270 
271 //***************************************************************************
272 //
273 // SD_StopRecordingSound - Stop recording a sound
274 //
275 //***************************************************************************
276 
SD_StopRecordingSound(void)277 void SD_StopRecordingSound ( void )
278 {
279    if (SD_Started==false)
280       return;
281    if (Recording == true)
282       {
283       FX_StopRecord();
284       Recording=false;
285       }
286 }
287 
288 //***************************************************************************
289 //
290 // SD_SetRecordingActive - Set the recording active flag
291 //
292 //***************************************************************************
293 
SD_SetRecordingActive(void)294 void SD_SetRecordingActive ( void )
295 {
296    RecordingSemaphore=true;
297 }
298 
299 //***************************************************************************
300 //
301 // SD_ClearRecordingActive - Clear the recording active flag
302 //
303 //***************************************************************************
304 
SD_ClearRecordingActive(void)305 void SD_ClearRecordingActive ( void )
306 {
307    RecordingSemaphore=false;
308 }
309 
310 //***************************************************************************
311 //
312 // SD_RecordingActive - Check if recording is active on some system
313 //
314 //***************************************************************************
315 
SD_RecordingActive(void)316 boolean SD_RecordingActive ( void )
317 {
318    return RecordingSemaphore;
319 }
320 
321 //***************************************************************************
322 //
323 // SD_GetSoundData - Returns next piece of sound data, returns:
324 //
325 //                   nodata if no sound data is ready
326 //                   newsound if it is the start of a new sound
327 //                            data is also returned;
328 //                   endsound if the sound is finished
329 //                   data if data is ready
330 //
331 //***************************************************************************
332 
SD_GetSoundData(byte * data,word length)333 recordstate SD_GetSoundData ( byte * data, word length )
334 {
335    recordstate status=rs_data;
336    int amount;
337 
338    if (SD_Started==false)
339       return rs_nodata;
340 
341    if (Feeder==false)
342       return rs_nodata;
343 
344    if (FeederPointer==RecordingPointer)
345       {
346       if (Recording==false)
347          {
348          SafeFree(RecordingBuffer);
349          Feeder=false;
350          return rs_endsound;
351          }
352       else
353          {
354          return rs_nodata;
355          }
356       }
357 
358    if (FeederPointer==-1)
359       {
360       status=rs_newsound;
361       FeederPointer=0;
362       }
363 
364    amount=length;
365 
366    if (FeederPointer+length > RECORDINGBUFFERSIZE)
367       amount=RECORDINGBUFFERSIZE-FeederPointer;
368    memcpy ( data, &RecordingBuffer[FeederPointer], amount);
369 
370    FeederPointer = (FeederPointer + amount) &
371                       (RECORDINGBUFFERSIZE - 1);
372 
373    data += amount;
374 
375    if (length!=amount)
376       {
377       amount=length-amount;
378       memcpy ( data, &RecordingBuffer[FeederPointer], amount);
379       FeederPointer = (FeederPointer + amount) &
380                         (RECORDINGBUFFERSIZE - 1);
381       }
382 
383    return status;
384 }
385 
386 //***************************************************************************
387 //
388 // SD_SoundDataReady - Returns true if data is ready
389 //
390 //***************************************************************************
391 
SD_SoundDataReady(void)392 boolean SD_SoundDataReady ( void )
393 {
394    if (SD_Started==false)
395       return false;
396    return Feeder;
397 }
398 
399 
400 
401