};
#if defined(PLATFORM_UNIX)
-static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
-static char premix_first_buffer[SND_BLOCKSIZE];
+static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
+static short premix_first_buffer[SND_BLOCKSIZE];
#if defined(AUDIO_STREAMING_DSP)
-static char premix_left_buffer[SND_BLOCKSIZE];
-static char premix_right_buffer[SND_BLOCKSIZE];
-static int premix_last_buffer[SND_BLOCKSIZE];
+static short premix_left_buffer[SND_BLOCKSIZE];
+static short premix_right_buffer[SND_BLOCKSIZE];
+static long premix_last_buffer[SND_BLOCKSIZE];
#endif
-static unsigned char playing_buffer[SND_BLOCKSIZE];
+static byte playing_buffer[SND_BLOCKSIZE];
#endif
/* forward declaration of internal functions */
#if defined(AUDIO_STREAMING_DSP)
static void SoundServer_InsertNewSound(struct SoundControl);
+static boolean InitAudioDevice_DSP(int, int);
+#elif defined(PLATFORM_HPUX)
+static boolean InitAudioDevice_HPUX();
#elif defined(PLATFORM_UNIX)
static unsigned char linear_to_ulaw(int);
static int ulaw_to_linear(unsigned char);
-#endif
-
-#if defined(AUDIO_LINUX_IOCTL)
-static boolean InitAudioDevice_Linux();
-#elif defined(PLATFORM_NETBSD)
-static boolean InitAudioDevice_NetBSD();
-#elif defined(PLATFORM_HPUX)
-static boolean InitAudioDevice_HPUX();
#elif defined(PLATFORM_MSDOS)
static void SoundServer_InsertNewSound(struct SoundControl);
-static void SoundServer_StopSound(int);
+static void SoundServer_StopSound(struct SoundControl);
static void SoundServer_StopAllSounds();
#endif
TreeInfo *ti = *ti_ptr;
unsigned long str_size1, str_size2, str_size3;
- printf("B\n");
-
if (leveldir_current == NULL)
leveldir_current = checked_calloc(sizeof(TreeInfo));
- printf("B.1\n");
if (ti == NULL)
ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
- printf("B.2\n");
if (leveldir_current->fullpath != NULL)
free(leveldir_current->fullpath);
- printf("B.3 ['%s']\n", ti->basepath);
-#if 0
if (ti->basepath != NULL)
free(ti->basepath);
-#endif
- printf("B.4\n");
if (ti->fullpath != NULL)
free(ti->fullpath);
- printf("B.5\n");
-
- printf("C\n");
if (read(audio.soundserver_pipe[0], set_name,
snd_ctrl.data_len) != snd_ctrl.data_len ||
sizeof(unsigned long)) != sizeof(unsigned long))
Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
- printf("D\n");
-
leveldir_current->fullpath = checked_calloc(str_size1);
ti->basepath = checked_calloc(str_size2);
ti->fullpath = checked_calloc(str_size3);
str_size3) != str_size3)
Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
- printf("E\n");
-
InitPlaylist();
close(audio.device_fd);
- printf("X\n");
-
if (snd_ctrl.reload_sounds)
{
artwork.sounds_set_current = set_name;
if (playing_sounds || snd_ctrl.active)
{
- struct timeval delay = { 0, 0 };
- byte *sample_ptr;
- long sample_size;
- static long max_sample_size = 0;
- static long fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
- int sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
- static boolean stereo = TRUE;
-
if (playing_sounds ||
(audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
{
+ struct timeval delay = { 0, 0 };
+ static int fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
+ int sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
+ static boolean stereo = TRUE;
+
if (!playing_sounds) /* we just opened the audio device */
- {
-#if defined(AUDIO_LINUX_IOCTL)
- stereo = InitAudioDevice_Linux(fragment_size, sample_rate);
-#elif defined(PLATFORM_NETBSD)
- stereo = InitAudioDevice_NetBSD(fragment_size, sample_rate);
-#endif
- max_sample_size = fragment_size / (stereo ? 2 : 1);
- }
+ stereo = InitAudioDevice_DSP(fragment_size, sample_rate);
if (snd_ctrl.active) /* new sound has arrived */
SoundServer_InsertNewSound(snd_ctrl);
select(audio.soundserver_pipe[0] + 1,
&sound_fdset, NULL, NULL, &delay) < 1)
{
+ short *sample_ptr;
+ int sample_size;
+ int max_sample_size;
+
FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+ max_sample_size = fragment_size / ((stereo ? 2 : 1) * sizeof(short));
+
/* first clear the last premixing buffer */
- memset(premix_last_buffer, 0, fragment_size * sizeof(int));
+ memset(premix_last_buffer, 0,
+ max_sample_size * (stereo ? 2 : 1) * sizeof(long));
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ for(i=0; i<MAX_SOUNDS_PLAYING; i++)
{
int j;
continue;
/* get pointer and size of the actual sound sample */
- sample_ptr = playlist[i].data_ptr + playlist[i].playingpos;
+ sample_ptr = (short *)playlist[i].data_ptr +playlist[i].playingpos;
sample_size = MIN(max_sample_size,
playlist[i].data_len - playlist[i].playingpos);
playlist[i].playingpos += sample_size;
/* fill the first mixing buffer with original sample */
- memcpy(premix_first_buffer, sample_ptr, sample_size);
+ memcpy(premix_first_buffer, sample_ptr,
+ sample_size * sizeof(short));
/* are we about to restart a looping sound? */
if (playlist[i].loop && sample_size < max_sample_size)
{
playlist[i].playingpos = max_sample_size - sample_size;
- memcpy(premix_first_buffer + sample_size,
- playlist[i].data_ptr, max_sample_size - sample_size);
+ memcpy(premix_first_buffer + sample_size * sizeof(short),
+ playlist[i].data_ptr,
+ (max_sample_size - sample_size) * sizeof(short));
sample_size = max_sample_size;
}
if (playlist[i].volume != PSND_MAX_VOLUME)
for(j=0; j<sample_size; j++)
premix_first_buffer[j] =
- (playlist[i].volume * (int)premix_first_buffer[j])
+ (playlist[i].volume * (long)premix_first_buffer[j])
>> PSND_MAX_VOLUME_BITS;
/* fill the last mixing buffer with stereo or mono sound */
if (stereo)
{
- int middle_pos = PSND_MAX_LEFT2RIGHT/2;
- int left_volume = stereo_volume[middle_pos +playlist[i].stereo];
- int right_volume = stereo_volume[middle_pos -playlist[i].stereo];
+ int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
+ int left_volume = stereo_volume[middle_pos + playlist[i].stereo];
+ int right_volume= stereo_volume[middle_pos - playlist[i].stereo];
for(j=0; j<sample_size; j++)
{
premix_left_buffer[j] =
- (left_volume * (int)premix_first_buffer[j])
+ (left_volume * premix_first_buffer[j])
>> PSND_MAX_LEFT2RIGHT_BITS;
premix_right_buffer[j] =
- (right_volume * (int)premix_first_buffer[j])
+ (right_volume * premix_first_buffer[j])
>> PSND_MAX_LEFT2RIGHT_BITS;
- premix_last_buffer[2*j+0] += premix_left_buffer[j];
- premix_last_buffer[2*j+1] += premix_right_buffer[j];
+
+ premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
+ premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
}
}
else
{
- for(j=0;j<sample_size;j++)
- premix_last_buffer[j] += (int)premix_first_buffer[j];
+ for(j=0; j<sample_size; j++)
+ premix_last_buffer[j] += premix_first_buffer[j];
}
/* delete completed sound entries from the playlist */
}
/* put last mixing buffer to final playing buffer */
- for(i=0; i<fragment_size; i++)
+ for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
{
- if (premix_last_buffer[i]<-255)
- playing_buffer[i] = 0;
- else if (premix_last_buffer[i]>255)
- playing_buffer[i] = 255;
- else
- playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
+ /* cut off at 17 bit value */
+ if (premix_last_buffer[i] < -65535)
+ premix_last_buffer[i] = -65535;
+ else if (premix_last_buffer[i] > 65535)
+ premix_last_buffer[i] = 65535;
+
+ /* shift to 16 bit value */
+ premix_last_buffer[i] >>= 1;
+
+ /* fill playing buffer for "signed 16 bit little endian" audio
+ format (independently of endianess of "short" integer type) */
+ playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
+ playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
}
/* finally play the sound fragment */
playing_sounds++;
#if defined(PLATFORM_MSDOS)
- playlist[i].voice = allocate_voice(playlist[i].data_ptr);
+ playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
if (snd_ctrl.loop)
voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
/* ------------------------------------------------------------------------- */
#if defined(AUDIO_LINUX_IOCTL)
-static boolean InitAudioDevice_Linux(long fragment_size, int sample_rate)
+static boolean InitAudioDevice_Linux(int fragment_size, int sample_rate)
{
/* "ioctl()" expects pointer to 'int' value for stereo flag
(boolean is defined as 'char', which will not work here) */
+ unsigned int fragment_spec = 0;
+ unsigned int audio_format = 0;
+ int fragment_size_query;
int stereo = TRUE;
- unsigned long fragment_spec = 0;
/* determine logarithm (log2) of the fragment size */
- for (fragment_spec=0; (1 << fragment_spec) < fragment_size;
- fragment_spec++);
+ for (fragment_spec=0; (1 << fragment_spec) < fragment_size; fragment_spec++);
/* use two fragments (play one fragment, prepare the other);
one fragment would result in interrupted audio output, more
Error(ERR_EXIT_SOUND_SERVER,
"cannot set fragment size of /dev/dsp -- no sounds");
+ audio_format = AFMT_S16_LE;
+ if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) < 0)
+ Error(ERR_EXIT_SOUND_SERVER,
+ "cannot set audio format of /dev/dsp -- no sounds");
+
/* try if we can use stereo sound */
if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
{
"cannot set sample rate of /dev/dsp -- no sounds");
/* get the real fragmentation size; this should return 512 */
- if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size) < 0)
+ if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
Error(ERR_EXIT_SOUND_SERVER,
"cannot get fragment size of /dev/dsp -- no sounds");
+ if (fragment_size_query != fragment_size)
+ Error(ERR_EXIT_SOUND_SERVER,
+ "cannot set fragment size of /dev/dsp -- no sounds");
return (boolean)stereo;
}
#endif /* AUDIO_LINUX_IOCTL */
#if defined(PLATFORM_NETBSD)
-static boolean InitAudioDevice_NetBSD(long fragment_size, int sample_rate)
+static boolean InitAudioDevice_NetBSD(int fragment_size, int sample_rate)
{
audio_info_t a_info;
boolean stereo = TRUE;
}
#endif /* PLATFORM_HPUX */
+#if defined(PLATFORM_UNIX)
+static boolean InitAudioDevice_DSP(int fragment_size, int sample_rate)
+{
+#if defined(AUDIO_LINUX_IOCTL)
+ return InitAudioDevice_Linux(fragment_size, sample_rate);
+#elif defined(PLATFORM_NETBSD)
+ return InitAudioDevice_NetBSD(fragment_size, sample_rate);
+#elif defined(PLATFORM_HPUX)
+ return InitAudioDevice_HPUX();
+#endif
+}
+#endif /* PLATFORM_UNIX */
+
#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
/* these two are stolen from "sox"... :) */
byte sound_header_buffer[WAV_HEADER_SIZE];
char chunk_name[CHUNK_ID_LEN + 1];
int chunk_size;
+ short *data_ptr;
FILE *file;
int i;
#endif
return NULL;
}
+ /* convert unsigned 8 bit sample data to signed 16 bit sample data */
+
+ data_ptr = checked_malloc(snd_info->data_len * sizeof(short));
+
for (i=0; i<snd_info->data_len; i++)
- ((byte *)snd_info->data_ptr)[i] = ((byte *)snd_info->data_ptr)[i] ^ 0x80;
+ data_ptr[i] = ((short)(((byte *)snd_info->data_ptr)[i] ^ 0x80)) << 8;
+
+ free(snd_info->data_ptr);
+ snd_info->data_ptr = data_ptr;
#endif /* PLATFORM_UNIX */
return FALSE;
}
- printf("-> '%s'\n", filename);
-
return Load_WAV(filename);
}
char *filename = getPath2(music_directory, basename);
MusicInfo *mus_info = NULL;
- if (FileIsSound(filename))
+ if (FileIsSound(basename))
mus_info = Load_WAV(filename);
- else if (FileIsMusic(filename))
+ else if (FileIsMusic(basename))
mus_info = Load_MOD(filename);
free(filename);
#if defined(TARGET_SDL)
+ nr = nr % num_music;
+
if (Music[nr]->type == MUS_TYPE_MOD)
{
Mix_PlayMusic(Music[nr]->data_ptr, -1);
static void InitReloadSoundsOrMusic(char *set_name, int type)
{
+#if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
struct SoundControl snd_ctrl = emptySoundControl;
TreeInfo *ti =
(type == SND_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current);
unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
unsigned long str_size2 = strlen(ti->basepath) + 1;
unsigned long str_size3 = strlen(ti->fullpath) + 1;
+#endif
if (!audio.sound_available)
return;
- if (leveldir_current == NULL)
- Error(ERR_EXIT, "leveldir_current == NULL");
-
- snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
- snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
- snd_ctrl.data_len = strlen(set_name) + 1;
-
#if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
if (type == SND_RELOAD_SOUNDS)
- audio.audio.func_reload_sounds();
+ audio.func_reload_sounds();
else
- audio.audio.func_reload_music();
+ audio.func_reload_music();
#elif defined(PLATFORM_UNIX)
if (audio.soundserver_pid == 0) /* we are child process */
return;
+ if (leveldir_current == NULL) /* should never happen */
+ Error(ERR_EXIT, "leveldir_current == NULL");
+
+ snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
+ snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
+ snd_ctrl.data_len = strlen(set_name) + 1;
+
if (write(audio.soundserver_pipe[1], &snd_ctrl,
sizeof(snd_ctrl)) < 0 ||
write(audio.soundserver_pipe[1], set_name,
audio.sound_available = audio.sound_enabled = FALSE;
return;
}
-
- printf("A\n");
-
#endif
}
FreeSound(Sound[i]);
free(Sound);
+
Sound = NULL;
+ num_sounds = 0;
}
void FreeAllMusic()
FreeMusic(Music[i]);
free(Music);
+
Music = NULL;
+ num_music = 0;
}
/* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */