/* 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 #include #include #include #include #include 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;ifreq)*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; }