Hi,

I have installed a delta 1010 on my 3.06 ghz machine
(with 2GB ram), running redhat 9 (kernel 2.4.20-24.9).

I find
a) that trying to grab audio from 8 channels at 96Khz
   (a supported sampling rate for DL1010) eats up
   50% of my CPU, and after a few seconds begins
   giving me error -5 (Input/Output Error).
   I was getting the same error earlier at a sampling
   rate of 16Khz (8 channels) on a 2 Ghz processor,
   which prompted me to upgrade my CPU. Now I can
   get 16Khz, but not 32 or 48 Khz (which is what
   I need).

   Since these are supported sampling rates, Im
   surprised that it must consume so much CPU.

   Strangely, if I include a printf in my code
   to print out energies in the recorded channels,
   I get more errors at higher sampling rates.

b) I am completely unable to duplex. I can either
   record audio, or play it back. If I try to do
   both (i.e. record and then play back) I get
   the error
"write to audio interface failed (Broken pipe)"

 I have opened two different hanldes to default,
 so I do not see why this doesnt work..

Ive attached the code I use.  If I
comment out the recording the play works,
and if I comment out the play the recording
works, but not both together.

Any advice at all would be greatly appreciated.

Many thanks,
Bhiksha

Bhiksha Raj
Research Scientist
Mitsubishi Electric Research Labs
Cambridge, MA 02139

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>


struct{
    short buf;
    snd_pcm_t *playback_handle;
}sound_out;    


int sound_out_open( int samprate, int numchannel, int bufsize, char *dev)
{
    int err;
    snd_pcm_hw_params_t *hw_params;

    // Open the PCM device
    err = snd_pcm_open (&sound_out.playback_handle, dev, 
                        SND_PCM_STREAM_PLAYBACK, 0);
    if (err < 0) {
        fprintf (stderr, "cannot open audio device \"%s\" (%s)\n", 
                         dev, snd_strerror (err));
        exit (1);
    }

    // Allocate hardware parameter structure
    err = snd_pcm_hw_params_malloc (&hw_params);
    if (err < 0) {
        fprintf (stderr, "cannot alloc hardware parameter structure (%s)\n",
                         snd_strerror (err)); exit (1);
    }

    // Initialize the hardware parameter structure
    err = snd_pcm_hw_params_any (sound_out.playback_handle, hw_params);
    if (err < 0) {
        fprintf (stderr, 
                 "cannot initialize hardware parameter structure (%s)\n", 
                 snd_strerror (err));
        exit (1);
    }

    // Set the access type to interleaved
    err = snd_pcm_hw_params_set_access (sound_out.playback_handle, 
                                  hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        fprintf (stderr, "cannot set access type (%s)\n",snd_strerror(err));
        exit (1);
    }

    // Set sample format to 16 bit little endian
    err = snd_pcm_hw_params_set_format(sound_out.playback_handle, hw_params,
                                       SND_PCM_FORMAT_S16_LE);
    if (err< 0){
        fprintf (stderr, "cannot set sample format (%s)\n", 
                          snd_strerror (err));
        exit (1);
    }

    // Set Sampling rate
    err = snd_pcm_hw_params_set_rate (sound_out.playback_handle, hw_params,
                                      samprate, 0);
    if (err < 0) {
        fprintf (stderr,"cannot set sample rate (%s)\n", snd_strerror(err));
        exit (1);
    }

    // Set number of channels
    err = snd_pcm_hw_params_set_channels (sound_out.playback_handle, 
                                          hw_params, numchannel);
    if (err < 0) {
        fprintf (stderr, "cannot set channel count (%s)\n", 
                          snd_strerror (err));
        exit (1);
    }

    // Set the PCM hardware parameters, using the hw_params structure
    err = snd_pcm_hw_params (sound_out.playback_handle, hw_params);
    if (err < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror(err));
        exit (1);
    }

    // Free the hw_params structure
    snd_pcm_hw_params_free (hw_params);

    // Set the buffer
    sound_out.buf = bufsize;


    // Set the auiod interface hanlde
    err = snd_pcm_prepare (sound_out.playback_handle);
    if (err < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n", 
                         snd_strerror (err));
        exit (1);
    }

    return 0;
}

int sound_out_queue( short *buf)
{
    int err = snd_pcm_writei(sound_out.playback_handle, buf, sound_out.buf);
    if (err  != sound_out.buf) {
        fprintf (stderr, "write to audio interface failed (%s)\n", 
                         snd_strerror (err));
        exit (1);
    }
}

void sound_out_close()
{
    snd_pcm_close (sound_out.playback_handle);
}


/*
 *      Sound input section
 */
 
struct{
    short buf;
    snd_pcm_t *capture_handle;
}sound_in;


int sound_in_open( int samprate, int numchannel, int bufsize, char *dev)
{
    int err;
    snd_pcm_hw_params_t *hw_params;

    // Open the PCM device
    err = snd_pcm_open (&sound_in.capture_handle, dev, 
                        SND_PCM_STREAM_CAPTURE, 0);
    if (err < 0) {
        fprintf (stderr, "cannot open audio device \"%s\" (%s)\n", 
                         dev, snd_strerror (err));
        exit (1);
    }

    // Allocate hardware parameter structure
    err = snd_pcm_hw_params_malloc (&hw_params);
    if (err < 0) {
        fprintf (stderr, "cannot alloc hardware parameter structure (%s)\n",
                         snd_strerror (err)); exit (1);
    }

    // Initialize the hardware parameter structure
    err = snd_pcm_hw_params_any (sound_in.capture_handle, hw_params);
    if (err < 0) {
        fprintf (stderr, 
                 "cannot initialize hardware parameter structure (%s)\n", 
                 snd_strerror (err));
        exit (1);
    }

    // Set the access type to interleaved
    err = snd_pcm_hw_params_set_access (sound_in.capture_handle, hw_params,
                                        SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        fprintf (stderr, "cannot set access type (%s)\n",snd_strerror(err));
        exit (1);
    }

    // Set sample format to 16 bit little endian
    err = snd_pcm_hw_params_set_format(sound_in.capture_handle, hw_params,
                                       SND_PCM_FORMAT_S16_LE);
    if (err< 0){
        fprintf (stderr, "cannot set sample format (%s)\n", 
                          snd_strerror (err));
        exit (1);
    }

    // Set Sampling rate
    err = snd_pcm_hw_params_set_rate (sound_in.capture_handle, hw_params,
                                      samprate, 0);
    if (err < 0) {
        fprintf (stderr,"cannot set sample rate (%s)\n", snd_strerror(err));
        exit (1);
    }

    // Set number of channels
    err = snd_pcm_hw_params_set_channels (sound_in.capture_handle,hw_params,           
                               numchannel);
    if (err < 0) {
        fprintf (stderr, "cannot set channel count (%s)\n", 
                          snd_strerror (err));
        exit (1);
    }


    // Set the PCM hardware parameters, using the hw_params structure
    err = snd_pcm_hw_params (sound_in.capture_handle, hw_params);
    if (err < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror(err));
        exit (1);
    }

    // Free the hw_params structure
    snd_pcm_hw_params_free (hw_params);

    // Set the buffer
    sound_in.buf = bufsize;


    // Set the audio interface handle
    err = snd_pcm_prepare (sound_in.capture_handle);
    if (err < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n", 
                         snd_strerror (err));
        exit (1);
    }
}

int sound_in_get( short *b)
{
    int err;
    err = snd_pcm_readi (sound_in.capture_handle, b, sound_in.buf);
    // printf( "err: %d, %d\n", err, sound_in.buf);
    if( err != sound_in.buf){
        fprintf (stderr, "read from audio interface failed (err no %d : %s)\n", 
                         err, snd_strerror (err));
        snd_pcm_drain(sound_in.capture_handle);
    }
    return err;
}

void sound_in_close()
{
    snd_pcm_close( sound_in.capture_handle);
}


/* THE MAIN ROUTINE */

int main (int argc, char *argv[])
{
    int i;
    int samprate = argc > 2 ? atoi( argv[2]) : 44100;
    int numchannel = argc > 3 ? atoi( argv[3]) : 2;
    int bufsize = argc > 4 ? atoi( argv[4]) : 1024;
    char *indev, *outdev;
    short *b = ( short *)calloc( numchannel*bufsize*numchannel, sizeof( short));
    double *e;

    printf( "samprate: %d, numchannel: %d, bufsize: %d\n", 
            samprate, numchannel, bufsize);

    indev = argc > 5 ? argv[5] : NULL;
    outdev = argc > 1 ? argv[1] : strdup("default");

    //for( i = 0 ; i != numchannel*bufsize ; i++)
    //  b[i] = rand();

    printf("Attempting to open %s ..... ", indev); fflush(stdout);
    sound_in_open( samprate, numchannel, bufsize, indev);
    printf("done!\n"); fflush(stdout);

    if (outdev) sound_out_open( samprate, numchannel, bufsize, outdev);

    e = (double *) calloc(10*numchannel,sizeof(double));
    while( 1){
        sound_in_get( b);

        for( i = 0 ; i < numchannel ; i++ ) e[i] = 0;
        for( i = 0 ; i != numchannel*bufsize ; i++)
                e[i%numchannel] += fabs( ((double)b[i])/32768);
/*
        for( i = 0 ; i < numchannel ; i++ )
            fprintf(stdout,"%7.4f ",e[i]);
        fprintf(stdout,"\n"); fflush(stdout);
*/
        sound_out_queue( b);
    }

    sound_in_close();
    sound_out_close();
}

Reply via email to