/* * This file is a part of VyQChat. * * Copyright (C) 2002-2004 Pawel Stolowski * * VyQChat is free software; you can redestribute it and/or modify it * under terms of GNU General Public License by Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY. See GPL for more details. */ #include "config.h" #include "sound.h" #include "settings.h" #include #include #include #include #include #include #include #include Sound::SoundType Sound::sndtype; SoundSystem *Sound::sndsys = NULL; static void sigchld_handler(int s) { wait(NULL); } bool Sound::reload_samples(Settings &settings)/*{{{*/ { return sndsys->reload_samples(settings); }/*}}}*/ bool Sound::init(Settings *settings)/*{{{*/ { sndtype = settings->getSoundType(); switch (sndtype) { case NoSound: sndsys = new SoundSystem(); break; case PCSpeaker: sndsys = new SoundPCSpeaker(); break; case Command: sndsys = new SoundCommand(); break; case Arts: sndsys = new SoundArts(); break; case LibAo: sndsys = new SoundLibAo(); break; default: return false; } if (!sndsys) return false; bool status = sndsys->init(); if (!status) { delete sndsys; sndsys = new SoundPCSpeaker(); status = sndsys->init(); } if (status) { sndsys->reload_samples(*settings); signal(SIGCHLD, sigchld_handler); } return status; }/*}}}*/ void Sound::close()/*{{{*/ { if (sndsys) sndsys->close(); }/*}}}*/ void Sound::play(VyEvent evt)/*{{{*/ { if (sndsys) sndsys->play(evt); }/*}}}*/ const QString& Sound::error()/*{{{*/ { return sndsys->errstr; }/*}}}*/ /* * Sound systems base */ SoundSystem::SoundSystem()/*{{{*/ { for (int i=0; i(i)).latin1(), SFM_READ, &sfinf[i]); if (f) { sample[i]->resize(sfinf[i].channels * sfinf[i].frames * sizeof(short)); sf_readf_short(f, reinterpret_cast(sample[i]->data()), sfinf[i].frames); sf_close(f); } else { status = false; } } return status; # else return false; # endif }/*}}}*/ /* * PC Speaker */ bool SoundPCSpeaker::init()/*{{{*/ { return true; }/*}}}*/ void SoundPCSpeaker::play(VyEvent evt)/*{{{*/ { QApplication::beep(); }/*}}}*/ void SoundPCSpeaker::close()/*{{{*/ { }/*}}}*/ /* * LibAo */ bool SoundLibAo::init()/*{{{*/ { # ifdef HAVE_LIBAO ao_initialize(); drv = ao_default_driver_id(); return true; # else errstr = QString("No libao support compiled"); return false; # endif }/*}}}*/ void SoundLibAo::play(VyEvent evt)/*{{{*/ { # ifdef HAVE_LIBAO # ifdef HAVE_SNDFILE if (fork() == 0) { ao_sample_format frmt; frmt.bits = sizeof(short) << 3; frmt.channels = sfinf[evt].channels; frmt.rate = sfinf[evt].samplerate; frmt.byte_format = AO_FMT_NATIVE; ao_device* dev = ao_open_live(drv, &frmt, NULL); ao_play(dev, sample[evt]->data(), sample[evt]->size()); ao_close(dev); ao_shutdown(); _exit(0); } # endif # endif }/*}}}*/ void SoundLibAo::close()/*{{{*/ { # ifdef HAVE_LIBAO ao_shutdown(); # endif }/*}}}*/ /* * ARTS */ bool SoundArts::init()/*{{{*/ { # ifdef HAVE_ARTS /* int err; if ((err = arts_init()) < 0) { errstr = arts_error_text(err); return false; }*/ # else errstr = "no aRtS support compiled"; return false; # endif return true; }/*}}}*/ void SoundArts::play(VyEvent evt)/*{{{*/ { # ifdef HAVE_ARTS # ifdef HAVE_SNDFILE if (fork() == 0) { arts_init(); arts_stream_t str = arts_play_stream(sfinf[evt].samplerate, sizeof(short)<<3, sfinf[evt].channels, "vyqchat");// + QString::number(getpid())); arts_write(str, sample[evt]->data(), sample[evt]->size()); //if (status<0) // qWarning("arts_write error: %s", arts_error_text(status)); arts_close_stream(str); arts_free(); _exit(0); } # endif # endif }/*}}}*/ void SoundArts::close()/*{{{*/ { # ifdef HAVE_ARTS //arts_free(); # endif }/*}}}*/ /* * COMMAND */ bool SoundCommand::reload_samples(Settings &settings)/*{{{*/ { const QStringList cmd = QStringList::split(' ', settings.getPlayCommand()); for (int i=0; i(i))); } return true; }/*}}}*/ bool SoundCommand::init()/*{{{*/ { return true; }/*}}}*/ void SoundCommand::play(VyEvent evt)/*{{{*/ { QProcess *proc = new QProcess(arg[evt], NULL); QObject::connect(proc, SIGNAL(processExited()), proc, SLOT(deleteLater())); if (!proc->start()) qWarning("cannot run play command"); }/*}}}*/