You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
arts/examples/artscmt.c

144 lines
3.8 KiB

/*
Copyright (C) 2003 Stefan Westerfeld
stefan@space.twc.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
/*
* This is a threaded example using the aRts C API.
*
* Compile programs using the aRts C API with
*
* cc -o artscmt artscmt.c `artsc-config --cflags` `artsc-config --libs`
*
* If you are using a makefile, it could look like this:
*
* CFLAGS=`artsc-config --cflags`
* LDFLAGS=`artsc-config --libs`
*
* artscmt: artscmt.c
*/
#include <artsc.h>
#include <pthread.h>
#include <assert.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
pthread_mutex_t arts_mutex; /* pthread mutex */
struct Writer
{
pthread_t thread;
arts_stream_t stream;
float freq;
};
#define BUFFER_SIZE 1024
static void* writer(void *arg)
{
struct Writer *self = arg;
int pos = 0;
while(pos < 44100*10)
{
char buffer[BUFFER_SIZE], *to = buffer;
int i, written;
for(i=0;i<BUFFER_SIZE/4;i++)
{
/* generate two sin waves */
float fpos = ((float)pos)/44100.0;
long sample = (long)(sin(fpos*6.28*self->freq)*15000.0);
pos++;
/* put the samples in the packet */
*to++ = sample & 0xff;
*to++ = (sample >> 8) & 0xff;
*to++ = sample & 0xff;
*to++ = (sample >> 8) & 0xff;
}
written = 0;
do
{
int space;
/*
* Since there is more than one thread, it is important not to keep the lock
* for a long time. We definitely don't want arts_write to block, while we
* keep the lock, to ensure that other threads can do something as well. So
* we check the available buffer space before writing to avoid blocking.
*/
pthread_mutex_lock(&arts_mutex);
space = arts_stream_get(self->stream, ARTS_P_BUFFER_SPACE);
if (space >= BUFFER_SIZE)
{
written = arts_write(self->stream, buffer, BUFFER_SIZE);
assert(written == BUFFER_SIZE); /* should handle errors here */
}
pthread_mutex_unlock(&arts_mutex);
/*
* If the buffer is full, wait some time to get free space again. The amout of
* time to wait needs to correspond to the buffer size we use for refilling.
*/
if (!written)
usleep(10000); /* 10ms */
} while(!written);
}
return 0;
}
int main()
{
struct Writer writer1, writer2;
int error;
error = arts_init();
if(error < 0)
{
fprintf(stderr, "error initializing aRts driver: %s\n", arts_error_text(error));
return 1;
}
pthread_mutex_init(&arts_mutex, 0);
writer1.stream = arts_play_stream(44100, 16, 2, "artscmt1");
writer1.freq = 440;
pthread_create(&writer1.thread, NULL, writer, &writer1);
writer2.stream = arts_play_stream(44100, 16, 2, "artscmt2");
writer2.freq = 880;
pthread_create(&writer2.thread, NULL, writer, &writer2);
pthread_join(writer1.thread, NULL);
pthread_join(writer2.thread, NULL);
arts_close_stream(writer1.stream);
arts_close_stream(writer2.stream);
pthread_mutex_destroy(&arts_mutex);
arts_free();
return 0;
}