I've been knocking my head against a wall for more than a year trying to figure out how to correctly mix two streams of audio while using libsndfile for input and libao for output. My main requirement is that I cannot assume anything about the output drivers -- that is, I cannot depend on the output driver (ALSA, OSS, Sun, etc) being able to do the mixing for me. Many of my target platforms lack any sort of mixing services. I need to do this myself. I tried starting a mixer/player thread that would work in a producer/consumer relationship with one or two audio file decoder threads. I can play one sound at a time just fine. When I try to do both, I get distortion followed by a segfault.

So, I'm back to a demo program. What must I do to this program to cause it to start playing one audio file, then play another N seconds later?

David Griffith
d...@661.org

===begin code===
/*
 * gcc -o mixer mixer.c -lao -lsndfile
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ao/ao.h>
#include <sndfile.h>

#define BUFFSIZE 512

int playfile(FILE *);

int main(int argc, char *argv[])
{
        FILE *fp1, *fp2;

        if (argc < 2) {
                printf("usage: %s <filename>.ogg <filename>.aiff\n", argv[0]);
                exit(1);
        }
        fp1 = fopen(argv[1], "rb");
        if (fp1 == NULL)  {
                printf("Cannot open %s.\n", argv[1]);
                exit(2);
        }
        fp2 = fopen(argv[1], "rb");
        if (fp2 == NULL)  {
                printf("Cannot open %s.\n", argv[1]);
                exit(3);
        }

        ao_initialize();
        playfile(fp1);
        playfile(fp2);
        ao_shutdown();

        return 0;
}

int playfile(FILE *fp)
{
        int default_driver;
        ao_device *device;
        ao_sample_format format;
        SNDFILE *sndfile;
        SF_INFO sf_info;
        short *shortbuffer;
        int64_t toread;
        int64_t frames_read;
        int64_t count;

        sndfile = sf_open_fd(fileno(fp), SFM_READ, &sf_info, 1);
        memset(&format, 0, sizeof(ao_sample_format));
        shortbuffer = malloc(BUFFSIZE * sf_info.channels * sizeof(short));
        frames_read = 0;
        toread = sf_info.frames * sf_info.channels;
        count = 0;

        default_driver = ao_default_driver_id();
        memset(&format, 0, sizeof(ao_sample_format));

        format.byte_format = AO_FMT_NATIVE;
        format.bits = 16;
        format.channels = sf_info.channels;
        format.rate = sf_info.samplerate;

        device = ao_open_live(default_driver, &format, NULL);
        if (device == NULL) {
                printf("Error opening sound device.\n");
                exit(4);
        }
        while (count < toread) {
                frames_read = sf_read_short(sndfile, shortbuffer, BUFFSIZE);
                count += frames_read;
                ao_play(device, (char *)shortbuffer, frames_read * 
sizeof(short));
        }
        ao_close(device);
        sf_close(sndfile);
}
===end code===

--
David Griffith
d...@661.org
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev

Reply via email to