|
|
|
/*
|
|
|
|
|
|
|
|
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 <iostream>
|
|
|
|
#include <math.h>
|
|
|
|
#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;
|
|
|
|
}
|