+#ifdef WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#elif defined(LINUX)
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+#endif
+
+bool
+WavFile::Play ()
+{
+#ifdef WIN32
+ if (PlaySound ((LPCSTR) m_data, 0, SND_MEMORY | SND_NODEFAULT))
+ return true;
+#elif defined(LINUX)
+ int fd;
+ if ((fd = open ("/dev/dsp",O_WRONLY)) == -1) {
+ error_msg ("Error opening /dev/dsp");
+ return false;
+ }
+
+ int format = AFMT_S16_LE;
+ if (ioctl (fd, SNDCTL_DSP_SETFMT, &format) == -1) {
+ error_msg ("Error setting DSP format");
+ close(fd); return false;
+ }
+ if (format != AFMT_S16_LE) {
+ error_msg ("DSP Format not set");
+ close(fd); return false;
+ }
+
+ int channels = m_nChannels;
+ if (ioctl (fd, SNDCTL_DSP_CHANNELS, &format) == -1) {
+ error_msg ("Error setting number of channels");
+ close(fd); return false;
+ }
+ if (channels != m_nChannels) {
+ error_msg ("Number of channels not set");
+ close(fd); return false;
+ }
+
+ int speed = static_cast<int>(m_rate + 0.5);
+ if (ioctl (fd, SNDCTL_DSP_SPEED, &speed) == -1) {
+ error_msg ("Error setting sample rate");
+ close(fd); return false;
+ }
+ if (speed != m_rate && ! g_quiet) {
+ std::ostringstream os;
+ os << "Warning: Sample rate set to " << speed << ", not " << m_rate;
+ error_msg (os.str().c_str());
+ }
+
+ if (write (fd, reinterpret_cast<char*>(m_data) + m_nHeaderBytes, m_nDataBytes) !=
+ m_nDataBytes) {
+ error_msg ("Error writing audio samples");
+ close(fd); return false;
+ }