+#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_NO_DEFAULT))
+ return true;
+#elif defined(LINUX)
+ int fd;
+ if ((fd = open ("/dev/dsp",O_WRONLY)) < 0) {
+ 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; }
+ double set_speed = speed;
+ if (fabs (set_speed - m_rate) / m_rate > 0.1) {
+ error_msg ("Sample rate not set");
+ close(fd); return false; }
+
+ if (write (fd, reinterpret_cast<char*>(m_data) + m_nHeaderBytes, m_nDataBytes) !=
+ m_nDataBytes) {
+ error_msg ("Error writing audio samples");
+ close(fd); return false; }