/* Copyright (C) 2000 Stefan Westerfeld stefan@space.twc.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Permission is also granted to link this program with the Qt library, treating Qt like a library that normally accompanies the operating system kernel, whether or not that is in fact the case. */ #include #include #include "audiosubsys.h" #include "convert.h" #include "dispatcher.h" using namespace std; using namespace Arts; class SinTest : public ASProducer { protected: int audiofd; int done; AudioSubSystem *as; bool attached; public: SinTest(); virtual ~SinTest(); void needMore(); void run(long samples); }; SinTest::SinTest() : done(0), as(AudioSubSystem::the()) { // initialize and open audio subsystem (defaults to 44kHz, 16bit, stereo) attached = as->attachProducer(this); if(!attached) { cout << "audio subsystem is already used?" << endl; } else { if(as->open() == false) { cout << "audio subsystem init failed (" << as->error() << ")" << endl; audiofd = -1; } else audiofd = as->selectWriteFD(); } } SinTest::~SinTest() { // deinitialize the audio subsystem if(attached) as->detachProducer(); } void SinTest::run(long samples) { // run this loop until enough samples are produced while(attached && audiofd >= 0 && (done < samples)) { fd_set wfds, efds; FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(audiofd, &wfds); FD_SET(audiofd, &efds); // look if the audio filedescriptor becomes writeable int result = select(audiofd+1,0,&wfds,&efds,0); if(result > 0) { // if yes, tell the audio subsystem to do something about it if(FD_ISSET(audiofd, &wfds)) as->handleIO(AudioSubSystem::ioWrite); if(FD_ISSET(audiofd, &efds)) as->handleIO(AudioSubSystem::ioExcept); } else { cout << "select returned " << result << endl; } } } /* * needMore is a callback by the audio subsystem, which is made as soon as * the internal buffers need a refill */ void SinTest::needMore() { float left[100], right[100]; unsigned char out[400]; // generate two waves, one 440 Hz (left), one 880Hz (right) for(int i=0;i<100;i++) { left[i] = sin((float)i*6.28/100.0); right[i] = sin((float)i*6.28/50.0); } convert_stereo_2float_i16le(100, left, right, out); // write them to the audio subsystem as->write(out,400); done += 100; } /* * This is intended to help testing the audio subsystem with different * hardware without needing to use the whole server. * * Warning: this is *not* an example how to use aRts (there are others), * but a simple test program for debugging purposes. */ int main() { Dispatcher d; // to get startup classes executed // the test, generate 88100 samples (2 seconds) of pure sine wave test data SinTest s; s.run(88100); return 0; }