--- ./configure.ac +++ ./configure.ac @@ -21,9 +21,11 @@ dnl Checks what version of Unix we have and soundcard support AC_CHECK_HEADERS(sys/ioctl.h linux/soundcard.h machine/soundcard.h \ -soundcard.h sys/audio.h sun/audioio.h sun/dbriio.h sys/audioio.h \ +sys/soundcard.h soundcard.h sys/audio.h sun/audioio.h sun/dbriio.h sys/audioio.h \ audio.h dmedia/audio.h) +AC_ARG_WITH(alsa,[ --with-alsa Use ALSA library for sound],[WANT_ALSA=$withval],[WANT_ALSA=no]) + AH_TOP( [/* Define supported audio driver */ #undef HAVE_HARDSID @@ -60,9 +62,17 @@ AC_MSG_RESULT(irix) AC_CHECK_LIB(audio, main, [AUDIO_LDADD=-laudio AC_SUBST(AUDIO_LDADD)]) ;; - *linux*) AC_DEFINE(HAVE_OSS) - audiodrv_libadd="./audio/oss/liboss.a" - AC_MSG_RESULT(oss) + *linux*) + if test "$WANT_ALSA" = "yes" ; then + AC_DEFINE(HAVE_ALSA) + audiodrv_libadd="./audio/alsa/libalsa.a" + AC_MSG_RESULT(alsa) + AC_CHECK_LIB(asound, main, [AUDIO_LDFLAGS=-lasound AC_SUBST(AUDIO_LDFLAGS)]) + else + AC_DEFINE(HAVE_OSS) + audiodrv_libadd="./audio/oss/liboss.a" + AC_MSG_RESULT(oss) + fi ;; *netbsd*) AC_DEFINE(HAVE_OSS) audiodrv_libadd="./audio/oss/liboss.a" --- sidplay-2.0.9.orig/src/args.cpp +++ sidplay-2.0.9/src/args.cpp @@ -93,7 +93,7 @@ // Convert time from integer -bool ConsolePlayer::parseTime (const char *str, uint_least32_t &time) +bool ConsolePlayer::parseTime (char *str, uint_least32_t &time) { char *sep; uint_least32_t _time; @@ -126,7 +126,7 @@ } // Parse command line arguments -int ConsolePlayer::args (int argc, const char *argv[]) +int ConsolePlayer::args (int argc, char *argv[]) { int infile = 0; int i = 0; --- sidplay-2.0.9.orig/src/audio/alsa/audiodrv.cpp +++ sidplay-2.0.9/src/audio/alsa/audiodrv.cpp @@ -3,6 +3,9 @@ // -------------------------------------------------------------------------- /*************************************************************************** * $Log: audiodrv.cpp,v $ + * Revision 1.8 2008/07/19 13:58:04 wnd + * Almost complete rewrite to support new ALSA API. + * * Revision 1.7 2002/03/04 19:07:48 s_a_white * Fix C++ use of nothrow. * @@ -29,171 +32,277 @@ ***************************************************************************/ #include "audiodrv.h" -#ifdef HAVE_ALSA +#ifdef HAVE_ALSA #include #ifdef HAVE_EXCEPTIONS -# include +#include #endif +#include +#include + +#define ALSA_DEFAULT "default" + Audio_ALSA::Audio_ALSA() { - // Reset everything. - outOfOrder(); + // Reset everything. + outOfOrder(); +} + +Audio_ALSA::~Audio_ALSA() +{ + close (); } -Audio_ALSA::~Audio_ALSA () +void +Audio_ALSA::outOfOrder() { - close (); + // Reset everything. + _swapEndian = false; + _bufShift = 0; + _errorString = "None"; + _audioHandle = NULL; } -void Audio_ALSA::outOfOrder () -{ - // Reset everything. - _errorString = "None"; - _audioHandle = NULL; -} - -void *Audio_ALSA::open (AudioConfig &cfg, const char *) -{ - AudioConfig tmpCfg; - int mask, wantedFormat, format; - int rtn; - int card = -1, dev = 0; - - if (_audioHandle != NULL) - { - _errorString = "ERROR: Device already in use"; - return NULL; - } - - if ((rtn = snd_pcm_open_preferred (&_audioHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK))) - { - _errorString = "ERROR: Could not open audio device."; - goto open_error; - } - - // Transfer input parameters to this object. - // May later be replaced with driver defaults. - tmpCfg = cfg; - - snd_pcm_channel_params_t pp; - snd_pcm_channel_setup_t setup; - - snd_pcm_channel_info_t pi; - - memset (&pi, 0, sizeof (pi)); - pi.channel = SND_PCM_CHANNEL_PLAYBACK; - if ((rtn = snd_pcm_plugin_info (_audioHandle, &pi))) - { - _errorString = "ALSA: snd_pcm_plugin_info failed."; - goto open_error; - } - - memset(&pp, 0, sizeof (pp)); +bool +Audio_ALSA::fmt(AudioConfig &cfg, snd_pcm_hw_params_t *hw) +{ + struct precinfo { + snd_pcm_format_t format; + int encoding; + int precision; + int swap; + }; + struct precinfo info[] = { +#if defined(WORDS_BIGENDIAN) + { SND_PCM_FORMAT_S16_BE, AUDIO_SIGNED_PCM, 16, false }, + { SND_PCM_FORMAT_U16_BE, AUDIO_UNSIGNED_PCM, 16, false }, + { SND_PCM_FORMAT_S16_LE, AUDIO_SIGNED_PCM, 16, true }, + { SND_PCM_FORMAT_U16_LE, AUDIO_UNSIGNED_PCM, 16, true }, +#else + { SND_PCM_FORMAT_S16_LE, AUDIO_SIGNED_PCM, 16, false }, + { SND_PCM_FORMAT_U16_LE, AUDIO_UNSIGNED_PCM, 16, false }, + { SND_PCM_FORMAT_S16_BE, AUDIO_SIGNED_PCM, 16, true }, + { SND_PCM_FORMAT_U16_BE, AUDIO_UNSIGNED_PCM, 16, true }, +#endif + { SND_PCM_FORMAT_S8, AUDIO_SIGNED_PCM, 8, false }, + { SND_PCM_FORMAT_U8, AUDIO_UNSIGNED_PCM, 8, false } + }; + + switch (cfg.precision) { + case 8: + for (int i = 0; i < 2; i++) { + struct precinfo t; + memcpy(&t, &info[i], sizeof(t)); + memcpy(&info[i + 4], &info[i], sizeof(t)); + memcpy(&info[i], &t, sizeof(t)); + } + break; + case 16: + break; + default: + fprintf(stderr, "Unsupported precision: %d bits\n", + cfg.precision); + return false; + } + + int err; + for (int i = 0; i < 6; i++) { + err = snd_pcm_hw_params_set_format(_audioHandle, hw, + info[i].format); + if (err < 0) { + continue; + } + + cfg.precision = info[i].precision; + cfg.encoding = info[i].encoding; + _swapEndian = info[i].swap; + _bufShift = info[i].precision == 8 ? 0 : 1; + return true; + } - pp.mode = SND_PCM_MODE_BLOCK; - pp.channel = SND_PCM_CHANNEL_PLAYBACK; - pp.start_mode = SND_PCM_START_FULL; - pp.stop_mode = SND_PCM_STOP_STOP; - - pp.buf.block.frag_size = pi.max_fragment_size; - - pp.buf.block.frags_max = 1; - pp.buf.block.frags_min = 1; - - pp.format.interleave = 1; - pp.format.rate = tmpCfg.frequency; - pp.format.voices = tmpCfg.channels; - - // Set sample precision and type of encoding. - if ( tmpCfg.precision == 8 ) - { - tmpCfg.encoding = AUDIO_UNSIGNED_PCM; - pp.format.format = SND_PCM_SFMT_U8; - } - if ( tmpCfg.precision == 16 ) - { - tmpCfg.encoding = AUDIO_SIGNED_PCM; - pp.format.format = SND_PCM_SFMT_S16_LE; - } - - if ((rtn = snd_pcm_plugin_params (_audioHandle, &pp)) < 0) - { - _errorString = "ALSA: snd_pcm_plugin_params failed."; - goto open_error; - } - - if ((rtn = snd_pcm_plugin_prepare (_audioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0) - { - _errorString = "ALSA: snd_pcm_plugin_prepare failed."; - goto open_error; - } - - memset (&setup, 0, sizeof (setup)); - setup.channel = SND_PCM_CHANNEL_PLAYBACK; - if ((rtn = snd_pcm_plugin_setup (_audioHandle, &setup)) < 0) - { - _errorString = "ALSA: snd_pcm_plugin_setup failed."; - goto open_error; - } + fprintf(stderr, "Cannot set sample format: %s\n", snd_strerror(err)); + return false; +} + + + +bool +Audio_ALSA::init(AudioConfig &cfg, snd_pcm_hw_params_t *hw) +{ + int err; + + err = snd_pcm_hw_params_any(_audioHandle, hw); + if (err < 0) { + fprintf(stderr, "Cannot initialize hardware " + "parameter structure: %s\n", + snd_strerror(err)); + return false; + } + + err = snd_pcm_hw_params_set_access(_audioHandle, hw, + SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) { + fprintf(stderr, "Cannot set access type: %s\n", + snd_strerror(err)); + return false; + } + + /* try to find supported format/precision */ + if (! fmt(cfg, hw)) { + return false; + } + + /* use closest frequency */ + unsigned int realFreq = (unsigned int) cfg.frequency; + err = snd_pcm_hw_params_set_rate_near(_audioHandle, hw, &realFreq, 0); + if (err < 0) { + fprintf(stderr, "Cannot set sample rate: %s\n", + snd_strerror(err)); + return false; + } + cfg.frequency = realFreq; + + switch (cfg.channels) { + case 2: + _bufShift++; + break; + case 1: + break; + default: + fprintf(stderr, "Unsupported channel count: %d\n", + cfg.channels); + return false; + } + err = snd_pcm_hw_params_set_channels(_audioHandle, hw, + cfg.channels); + if (err < 0) { + fprintf(stderr, "Cannot set channel count: %s\n", + snd_strerror(err)); + return false; + } + + err = snd_pcm_hw_params(_audioHandle, hw); + if (err < 0) { + fprintf(stdout, "Cannot set parameters: %s\n", + snd_strerror(err)); + return false; + } - tmpCfg.bufSize = setup.buf.block.frag_size; + return true; +} + + + +void * +Audio_ALSA::open(AudioConfig &cfg, const char *name) +{ + AudioConfig tmpCfg = cfg; + snd_pcm_hw_params_t *hw; + int err; + + if (_audioHandle != NULL) { + _errorString = "ERROR: Device already in use"; + return NULL; + } + + err = snd_pcm_open(&_audioHandle, ALSA_DEFAULT, + SND_PCM_STREAM_PLAYBACK, 0); + if (err < 0) { + _errorString = "ERROR: Could not open audio device."; + fprintf(stderr, "Cannot open audio device: %s\n", + snd_strerror(err)); + return NULL; + } + + err = snd_pcm_hw_params_malloc(&hw); + if (err < 0) { + _errorString = "ERROR: Cannot initialise ALSA"; + fprintf(stderr, "Cannot allocate hardware " + "parameter structure: %s\n", + snd_strerror(err)); + return NULL; + } + + bool init_ok = init(tmpCfg, hw); + snd_pcm_hw_params_free(hw); + if (! init_ok) { + _errorString = "ERROR: Cannot initialise ALSA"; + return NULL; + } + + err = snd_pcm_prepare(_audioHandle); + if (err < 0) { + _errorString = "Cannot initialise ALSA"; + fprintf(stderr, "cannot prepare audio interface for use: %s\n", + snd_strerror(err)); + return NULL; + } + + tmpCfg.bufSize = 4096; #ifdef HAVE_EXCEPTIONS - _sampleBuffer = new(std::nothrow) int_least8_t[tmpCfg.bufSize]; + _sampleBuffer = new(std::nothrow) int_least8_t[tmpCfg.bufSize]; #else - _sampleBuffer = new int_least8_t[tmpCfg.bufSize]; + _sampleBuffer = new int_least8_t[tmpCfg.bufSize]; #endif - if (!_sampleBuffer) - { - _errorString = "AUDIO: Unable to allocate memory for sample buffers."; - goto open_error; - } - - // Setup internal Config - _settings = tmpCfg; - // Update the users settings - getConfig (cfg); - return _sampleBuffer; - -open_error: - if (_audioHandle != NULL) - { - close (); - } - - perror ("ALSA"); -return NULL; + if (!_sampleBuffer) { + _errorString = "Unable to allocate memory for sample buffers"; + return NULL; + } + + // Setup internal Config + _settings = tmpCfg; + // Update the users settings + getConfig (cfg); + return _sampleBuffer; } + + // Close an opened audio device, free any allocated buffers and // reset any variables that reflect the current state. -void Audio_ALSA::close () +void +Audio_ALSA::close() { - if (_audioHandle != NULL ) - { - snd_pcm_close(_audioHandle); - delete [] _sampleBuffer; - outOfOrder (); - } + if (_audioHandle != NULL) { + snd_pcm_close(_audioHandle); + delete [] _sampleBuffer; + outOfOrder (); + } } -void *Audio_ALSA::reset () + + +void * +Audio_ALSA::reset () { - return (void *) _sampleBuffer; + return (void *) _sampleBuffer; } -void *Audio_ALSA::write () -{ - if (_audioHandle == NULL) - { - _errorString = "ERROR: Device not open."; - return NULL; - } - snd_pcm_plugin_write (_audioHandle, _sampleBuffer, _settings.bufSize); - return (void *) _sampleBuffer; + +void * +Audio_ALSA::write() +{ + if (_audioHandle == NULL) + { + _errorString = "ERROR: Device not open."; + return NULL; + } + + if (_swapEndian) { + for (int n = 0; n < _settings.bufSize; n += 2) { + char t = ((char *) _sampleBuffer)[n]; + ((char *) _sampleBuffer)[n] = + ((char *) _sampleBuffer)[n + 1]; + ((char *) _sampleBuffer)[n + 1] = t; + } + } + snd_pcm_writei(_audioHandle, _sampleBuffer, + _settings.bufSize >> _bufShift); + return (void *) _sampleBuffer; } #endif // HAVE_ALSA --- sidplay-2.0.9.orig/src/audio/alsa/audiodrv.h +++ sidplay-2.0.9/src/audio/alsa/audiodrv.h @@ -3,6 +3,9 @@ // -------------------------------------------------------------------------- /*************************************************************************** * $Log: audiodrv.h,v $ + * Revision 1.6 2008/07/19 13:58:04 wnd + * Update to new ALSA API. + * * Revision 1.5 2002/01/10 19:04:00 s_a_white * Interface changes for audio drivers. * @@ -36,7 +39,7 @@ #include #include #include -#include +#include #include "../AudioBase.h" @@ -44,6 +47,8 @@ { private: // ------------------------------------------------------- private snd_pcm_t * _audioHandle; + bool _swapEndian; + int _bufShift; void outOfOrder (); @@ -51,6 +56,8 @@ Audio_ALSA(); ~Audio_ALSA(); + bool fmt (AudioConfig &cfg, snd_pcm_hw_params_t *hw); + bool init (AudioConfig &cfg, snd_pcm_hw_params_t *hw); void *open (AudioConfig &cfg, const char *name); void close (); // Rev 1.2 (saw) - Changed, see AudioBase.h --- sidplay-2.0.9.orig/src/audio/oss/audiodrv.h +++ sidplay-2.0.9/src/audio/oss/audiodrv.h @@ -57,7 +57,9 @@ #include #include -#if defined(HAVE_LINUX_SOUNDCARD_H) +#if defined(HAVE_SYS_SOUNDCARD_H) +# include +#elif defined(HAVE_LINUX_SOUNDCARD_H) # include #elif defined(HAVE_MACHINE_SOUNDCARD_H) # include --- sidplay-2.0.9.orig/src/keyboard.cpp +++ sidplay-2.0.9/src/keyboard.cpp @@ -56,7 +56,7 @@ # include # include # include -char _getch (void); +int _getch (void); #endif #define MAX_CMDLEN 10 @@ -200,7 +200,8 @@ int keyboard_decode () { - char cmd[MAX_CMDLEN+1], c; + char cmd[MAX_CMDLEN+1]; + int c; int nch = 0; int action = A_NONE; @@ -208,14 +209,14 @@ * Collect characters in a buffer. * Start with the one we have, and get more if we need them. */ - c = (char) _getch(); + c = _getch(); if (c == '\0') c = '\340'; // 224 else if (c == ESC) { cmd[nch++] = c; if (_kbhit ()) - c = (char) _getch (); + c = _getch (); } while (c >= 0) @@ -228,7 +229,7 @@ break; if (!_kbhit ()) break; - c = (char) _getch (); + c = _getch (); } return action; } @@ -256,7 +257,7 @@ return 0; } -char _getch (void) +int _getch (void) { char ch = -1; if (infd >= 0) --- sidplay-2.0.9.orig/src/main.cpp +++ sidplay-2.0.9/src/main.cpp @@ -137,7 +137,7 @@ g_player = &player; {// Decode the command line args - int ret = player.args (argc - 1, const_cast(argv + 1)); + int ret = player.args (argc - 1, const_cast(argv + 1)); if (ret < 0) goto main_error; else if (!ret) --- sidplay-2.0.9.orig/src/player.h +++ sidplay-2.0.9/src/player.h @@ -194,7 +194,7 @@ void consoleRestore (void); // Command line args - bool parseTime (const char *str, uint_least32_t &time); + bool parseTime (char *str, uint_least32_t &time); void displayArgs (const char *arg = NULL); void displayDebugArgs (); @@ -211,7 +211,7 @@ ConsolePlayer (const char * const name); virtual ~ConsolePlayer() {;} - int args (int argc, const char *argv[]); + int args (int argc, char *argv[]); bool open (void); void close (void); bool play (void); --- sidplay-2.0.9.orig/unix/config.h.in +++ sidplay-2.0.9/unix/config.h.in @@ -18,6 +18,9 @@ #undef HAVE_HARDSID_BUILDER +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + /* Define to 1 if you have the header file. */ #undef HAVE_AUDIO_H @@ -78,6 +81,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOUNDCARD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H @@ -102,6 +108,9 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME +/* Define to the home page for this package. */ +#undef PACKAGE_URL + /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -111,6 +120,14 @@ /* Version number of package */ #undef VERSION -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -#undef WORDS_BIGENDIAN +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif --- sidplay-2.0.9.orig/unix/my_macros.m4 +++ sidplay-2.0.9/unix/my_macros.m4 @@ -80,7 +80,8 @@ AC_CACHE_VAL(test_cv_have_ios_binary, [ AC_TRY_COMPILE( - [#include ], + [#include + using namespace std;], [ifstream myTest(ios::in|ios::binary);], [test_cv_have_ios_binary=yes], [test_cv_have_ios_binary=no] @@ -105,8 +106,9 @@ AC_CACHE_VAL(test_cv_have_ios_openmode, [ AC_TRY_COMPILE( - [#include - #include ], + [#include + #include + using namespace std;], [ios::openmode myTest = ios::in;], [test_cv_have_ios_openmode=yes], [test_cv_have_ios_openmode=no]