1 /***************************************************************************
\r
2 macosx.c - description
\r
4 begin : Wed May 15 2002
\r
5 copyright : (C) 2002 by Pete Bernert
\r
6 email : BlackDove@addcom.de
\r
7 ***************************************************************************/
\r
9 /***************************************************************************
\r
11 * This program is free software; you can redistribute it and/or modify *
\r
12 * it under the terms of the GNU General Public License as published by *
\r
13 * the Free Software Foundation; either version 2 of the License, or *
\r
14 * (at your option) any later version. See also the license.txt file for *
\r
15 * additional informations. *
\r
17 ***************************************************************************/
\r
25 #include <Carbon/Carbon.h>
\r
26 #include "externals.h"
\r
28 #define kMaxSoundBuffers 20
\r
30 //static int macBufferSize = 2, macBufferCount = 36;
\r
31 //static float macSoundPitch = 1.0;
\r
32 static long macSoundVolume = 100;
\r
33 volatile int soundBufferAt = -1, soundPlayAt = -1, soundQueued = 0;
\r
34 char *soundBuffer[kMaxSoundBuffers+1], *emptyBuffer;
\r
35 SndChannelPtr sndChannel;
\r
36 //ExtSoundHeader sndHeader;
\r
37 CmpSoundHeader sndHeader;
\r
38 SndCallBackUPP callBackUPP;
\r
39 static int bufferIndex;
\r
41 ////////////////////////////////////////////////////////////////////////
\r
42 // small linux time helper... only used for watchdog
\r
43 ////////////////////////////////////////////////////////////////////////
\r
45 unsigned long timeGetTime()
\r
48 gettimeofday(&tv, 0); // well, maybe there are better ways
\r
49 return tv.tv_sec * 1000 + tv.tv_usec/1000; // to do that, but at least it works
\r
52 pascal void MacProcessSound(SndChannelPtr chan, SndCommand *cmd)
\r
54 #pragma unused (chan, cmd)
\r
56 if (soundQueued <= 0)
\r
57 sndHeader.samplePtr = emptyBuffer;
\r
60 sndHeader.samplePtr = soundBuffer[soundPlayAt];
\r
62 if (soundPlayAt >= kMaxSoundBuffers/*macBufferCount*/)
\r
67 SndCommand buffer = { bufferCmd, 0, (long) &sndHeader };
\r
68 SndDoImmediate(sndChannel, &buffer);
\r
70 SndCommand callback = { callBackCmd, 0, 0 };
\r
71 SndDoCommand(sndChannel, &callback, true);
\r
74 ////////////////////////////////////////////////////////////////////////
\r
76 ////////////////////////////////////////////////////////////////////////
\r
78 static int buffer_size;
\r
79 void SetupSound(void)
\r
83 callBackUPP = NewSndCallBackUPP(MacProcessSound);
\r
87 SndDisposeChannel(sndChannel, true);
\r
92 while (buffer_size < (44100 / 60))
\r
95 memset(&sndHeader, 0, sizeof(sndHeader));
\r
96 sndHeader.numChannels = (iDisStereo ? 1 : 2);
\r
97 sndHeader.sampleRate = 44100 << 16;
\r
98 sndHeader.encode = cmpSH;
\r
99 sndHeader.baseFrequency = kMiddleC;
\r
100 sndHeader.numFrames = buffer_size;
\r
101 sndHeader.sampleSize = 16;
\r
103 sndHeader.format = k16BitBigEndianFormat;
\r
105 sndHeader.format = k16BitLittleEndianFormat;
\r
107 sndHeader.compressionID = fixedCompression;
\r
109 if (soundBufferAt != -1)
\r
111 free(soundBuffer[0]);
\r
115 soundBuffer[0] = (char *) calloc(buffer_size << 2, kMaxSoundBuffers);
\r
116 for (count = 1; count <= kMaxSoundBuffers; count++)
\r
117 soundBuffer[count] = soundBuffer[count-1] + (buffer_size << 2);
\r
118 emptyBuffer = (char *) calloc(buffer_size << 2, 1);
\r
120 soundBufferAt = soundPlayAt = soundQueued = 0;
\r
123 SndNewChannel(&sndChannel, sampledSynth, initStereo, callBackUPP);
\r
128 volume = (UInt32) (256.0 * (float) macSoundVolume / 100.0);
\r
130 sndcmd.cmd = volumeCmd;
\r
132 sndcmd.param2 = (volume << 16) | volume;
\r
133 SndDoCommand(sndChannel, &sndcmd, true);
\r
135 sndcmd.cmd = callBackCmd;
\r
137 sndcmd.param2 = 0;
\r
138 SndDoCommand(sndChannel, &sndcmd, true);
\r
141 ////////////////////////////////////////////////////////////////////////
\r
143 ////////////////////////////////////////////////////////////////////////
\r
145 void RemoveSound(void)
\r
147 DisposeSndCallBackUPP(callBackUPP);
\r
150 ////////////////////////////////////////////////////////////////////////
\r
151 // GET BYTES BUFFERED
\r
152 ////////////////////////////////////////////////////////////////////////
\r
154 unsigned long SoundGetBytesBuffered(void)
\r
157 int playAt = soundPlayAt;
\r
159 if (soundBufferAt < playAt) {
\r
160 bytes = (soundBuffer[kMaxSoundBuffers]-soundBuffer[playAt])+
\r
161 (soundBuffer[soundBufferAt]-soundBuffer[0]);
\r
163 bytes = soundBuffer[soundBufferAt]-soundBuffer[playAt];
\r
165 //printf("sb=%i\n", bytes);
\r
167 // if (bytes < SOUNDSIZE/2)
\r
173 ////////////////////////////////////////////////////////////////////////
\r
175 ////////////////////////////////////////////////////////////////////////
\r
177 void SoundFeedStreamData(unsigned char* pSound,long lBytes)
\r
181 if (lBytes > (buffer_size<<2)*kMaxSoundBuffers) {
\r
182 printf("sound feed overflow!\n");
\r
186 rem = soundBuffer[kMaxSoundBuffers]-(soundBuffer[soundBufferAt]+bufferIndex);
\r
187 if (lBytes > rem) {
\r
188 memcpy(soundBuffer[soundBufferAt]+bufferIndex, pSound, rem);
\r
189 lBytes -= rem; pSound += rem;
\r
190 soundQueued += kMaxSoundBuffers-soundBufferAt;
\r
191 soundBufferAt = 0; bufferIndex = 0;
\r
193 memcpy(soundBuffer[soundBufferAt]+bufferIndex, pSound, lBytes);
\r
194 soundBufferAt += (lBytes+bufferIndex)/(buffer_size<<2);
\r
195 soundQueued += (lBytes+bufferIndex)/(buffer_size<<2);
\r
196 bufferIndex = (lBytes+bufferIndex)%(buffer_size<<2);
\r
198 if (soundQueued >= kMaxSoundBuffers) {
\r
199 printf("sound buffer overflow!\n");
\r