[linux-audio-dev] [newbie] mixing audio streams

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] [newbie] mixing audio streams
From: Alex Marandon (al_AT_alpage.org)
Date: Sat Mar 13 2004 - 18:13:11 EET


Hello,

I'm a trying to make a piece of code to mix 2 WAV files and hear the
output on my headphones. I've spent hours trying differents things with
no success and now I feel I should ask for some light from experienced
people :)

I've found explanations on how to mix audio streams on this page :
http://www.vttoth.com/digimix.htm. But it doesn't really fits my own
situation since samples I get with libsndfile are signed values. My piece of
code works well for some files, but for others, it makes unpleasant
clicks.

I think I use a wrong algorithm, wich one do you use for such a
situation ?

Maybe I also use wrong data types, wich one should I use ?

Is there any framework wich does such a task well ? I had a look at
SndObj which seems to do such things but it's also quite old and not
maintained against today configurations.

Here is the guilty :

#include <stdio.h>
#include <ao/ao.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sndfile.h>

#define BUFFER_SIZE 1024
#define DYNAMIC_RANGE 65535

int main( int argc, char **argv ) {
        /* variables pour libao */
        ao_device * device;
        ao_sample_format format;
        int default_driver;
        /* variables pour libsndfile */
        SNDFILE * wav1;
        SNDFILE * wav2;
        SF_INFO sfinfo;
        SF_INFO sfinfo2;
        /* float volumized */

        static short buffer1 [BUFFER_SIZE];
        static short buffer2 [BUFFER_SIZE];
        static short mixed_buffer [BUFFER_SIZE];

        int max_frames;
        int buffer_cpt;
        int number_of_buffers;
        int i;

        /* faut remplir la stucture sfinfo avec des zéros */
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
        
        /* -- Initialize -- */
        if(!(wav1 = sf_open(argv[1], SFM_READ, &sfinfo))) exit(0);
        if(!(wav2 = sf_open(argv[2], SFM_READ, &sfinfo2))) exit(0);

        ao_initialize();
        
        /* -- Setup for default driver -- */
        default_driver = ao_default_driver_id();

        format.bits = 16;
        format.channels = sfinfo.channels;
        format.rate = sfinfo.samplerate;
        format.byte_format = AO_FMT_LITTLE;
        
        /* -- Open driver -- */
        device = ao_open_live(default_driver, &format, NULL /* no options */);
        if (device == NULL) {
                fprintf(stderr, "Error opening device.\n");
        }

        /* la duree de jeu est en fonction de la longueur
         * du plus long fichier */

        if ( sfinfo.frames > sfinfo2.frames ) {
            max_frames = sfinfo.frames;
        } else {
            max_frames = sfinfo2.frames;
        }

        number_of_buffers = max_frames / BUFFER_SIZE * 2;

        for ( buffer_cpt = 0; buffer_cpt <= number_of_buffers; buffer_cpt++ ) {

            /* -- lecture depuis les fichiers -- */
            sf_read_short (wav1, buffer1, BUFFER_SIZE);
            sf_read_short (wav2, buffer2, BUFFER_SIZE);

            /* -- mixage, cf. http://www.vttoth.com/digimix.htm -- */
            for ( i = 0; i <= BUFFER_SIZE; i++ ) {
                mixed_buffer[i]
                    = buffer1[i] + buffer2[i] - buffer1[i] * buffer2[i] / DYNAMIC_RANGE;
            }

            /* -- envoi dans la carte son -- */
            ao_play(device, (char *) mixed_buffer, sizeof(mixed_buffer));
        }

        ao_close(device);
    
        ao_shutdown();
        exit(0);
}

/* EOF */

Thanks :-)

-- 
Alex


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Sat Mar 13 2004 - 18:13:23 EET