diff options
Diffstat (limited to 'tools/ioemu/iodev/soundlnx.cc')
-rw-r--r-- | tools/ioemu/iodev/soundlnx.cc | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/tools/ioemu/iodev/soundlnx.cc b/tools/ioemu/iodev/soundlnx.cc new file mode 100644 index 0000000000..773addc311 --- /dev/null +++ b/tools/ioemu/iodev/soundlnx.cc @@ -0,0 +1,227 @@ +///////////////////////////////////////////////////////////////////////// +// $Id: soundlnx.cc,v 1.6 2002/12/24 10:12:26 vruppert Exp $ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001 MandrakeSoft S.A. +// +// MandrakeSoft S.A. +// 43, rue d'Aboukir +// 75002 Paris - France +// http://www.linux-mandrake.com/ +// http://www.mandrakesoft.com/ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +// This file (SOUNDLNX.CC) written and donated by Josef Drexler + + +#include "bochs.h" +#if (defined(linux) || defined(__FreeBSD__)) && BX_SUPPORT_SB16 +#define LOG_THIS bx_sb16. + +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/soundcard.h> + +bx_sound_linux_c::bx_sound_linux_c(bx_sb16_c *sb16) + :bx_sound_output_c(sb16) +{ + this->sb16 = sb16; + midi = NULL; + wavedevice = NULL; + wave = -1; +} + +bx_sound_linux_c::~bx_sound_linux_c() +{ + // nothing for now +} + + +int bx_sound_linux_c::waveready() +{ + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::midiready() +{ + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::openmidioutput(char *device) +{ + if ( (device == NULL) || (strlen(device) < 1) ) + return BX_SOUND_OUTPUT_ERR; + + midi = fopen(device,"w"); + + if (midi == NULL) + { + WRITELOG( MIDILOG(2), "Couldn't open midi output device %s: %s.", + device, strerror(errno)); + return BX_SOUND_OUTPUT_ERR; + } + + return BX_SOUND_OUTPUT_OK; +} + + +int bx_sound_linux_c::sendmidicommand(int delta, int command, int length, Bit8u data[]) +{ + UNUSED(delta); + // BX_PANIC(("Sendmidicommand!!"); + + fputc(command, midi); + fwrite(data, 1, length, midi); + fflush(midi); // to start playing immediately + + return BX_SOUND_OUTPUT_OK; +} + + +int bx_sound_linux_c::closemidioutput() +{ + fclose(midi); + + return BX_SOUND_OUTPUT_OK; +} + + +int bx_sound_linux_c::openwaveoutput(char *device) +{ + int length = strlen(device) + 1; + + if (wavedevice != NULL) + delete(wavedevice); + + wavedevice = new char[length]; + + if (wavedevice == NULL) + return BX_SOUND_OUTPUT_ERR; + + strncpy(wavedevice, device, length); + + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::startwaveplayback(int frequency, int bits, int stereo, int format) +{ + int fmt, ret; + int signeddata = format & 1; + + if ( (wavedevice == NULL) || (strlen(wavedevice) < 1) ) + return BX_SOUND_OUTPUT_ERR; + + if (wave == -1) + wave = open(wavedevice, O_WRONLY); + else + if ( (frequency == oldfreq) && + (bits == oldbits) && + (stereo == oldstereo) && + (format == oldformat) ) + return BX_SOUND_OUTPUT_OK; // nothing to do + + oldfreq = frequency; + oldbits = bits; + oldstereo = stereo; + oldformat = format; + + if (wave == -1) + return BX_SOUND_OUTPUT_ERR; + + if (bits == 16) + if (signeddata == 1) + fmt = AFMT_S16_LE; + else + fmt = AFMT_U16_LE; + else if (bits == 8) + if (signeddata == 1) + fmt = AFMT_S8; + else + fmt = AFMT_U8; + else + return BX_SOUND_OUTPUT_ERR; + + // set frequency etc. + ret = ioctl(wave, SNDCTL_DSP_RESET); + if (ret != 0) + WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_RESET): %s", strerror(errno)); + + /* + ret = ioctl(wave, SNDCTL_DSP_SETFRAGMENT, &fragment); + if (ret != 0) + WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SETFRAGMENT, %d): %s", + fragment, strerror(errno)); + */ + + ret = ioctl(wave, SNDCTL_DSP_SETFMT, &fmt); + if (ret != 0) // abort if the format is unknown, to avoid playing noise + { + WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SETFMT, %d): %s", + fmt, strerror(errno)); + return BX_SOUND_OUTPUT_ERR; + } + + ret = ioctl(wave, SNDCTL_DSP_STEREO, &stereo); + if (ret != 0) + WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_STEREO, %d): %s", + stereo, strerror(errno)); + + ret = ioctl(wave, SNDCTL_DSP_SPEED, &frequency); + if (ret != 0) + WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SPEED, %d): %s", + frequency, strerror(errno)); + + // ioctl(wave, SNDCTL_DSP_GETBLKSIZE, &fragment); + // WRITELOG( WAVELOG(4), "current output block size is %d", fragment); + + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::sendwavepacket(int length, Bit8u data[]) +{ + int ret; + + ret = write(wave, data, length); + + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::stopwaveplayback() +{ + // ioctl(wave, SNDCTL_DSP_SYNC); + // close(wave); + // wave = -1; + + return BX_SOUND_OUTPUT_OK; +} + +int bx_sound_linux_c::closewaveoutput() +{ + if (wavedevice != NULL) + delete(wavedevice); + + if (wave != -1) + { + close(wave); + wave = -1; + } + + wavedevice = NULL; + + return BX_SOUND_OUTPUT_OK; +} + +#endif // defined(linux) |