[LAD] mixing while using libao and libsndfile

From: David Griffith <dave@email-addr-hidden>
Date: Sun May 15 2016 - 19:34:34 EEST

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
dave@email-addr-hidden

===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
dave@email-addr-hidden
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Sun May 15 20:15:02 2016

This archive was generated by hypermail 2.1.8 : Sun May 15 2016 - 20:15:02 EEST