示例#1
0
//
// Set up both the audio and video capturing on the card
//
void an_configure_capture_card( void )
{
    struct v4l2_cropcap cropcap;
    struct v4l2_crop    crop;
    struct v4l2_format  fmt;
    sys_config info;
    int input;
    u32 pix_fmt;

    dvb_config_get( &info );

    CLEAR(cropcap);
    CLEAR(crop);
    CLEAR(fmt);

    m_width  = PAL_WIDTH_CAPTURE;
    m_height = PAL_HEIGHT_CAPTURE;

    // Set the cropping, ignore any errors
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (ioctl(m_i_fd, VIDIOC_CROPCAP, &cropcap)==0) {
            crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            crop.c    = cropcap.defrect; /* reset to default */

            ioctl(m_i_fd, VIDIOC_S_CROP, &crop);
    }
    //
    // Analogue Video capture
    //
    pix_fmt = V4L2_PIX_FMT_YUV420;
    m_sws   = NULL;

    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = m_width;
    fmt.fmt.pix.height      = m_height;
    fmt.fmt.pix.pixelformat = pix_fmt;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;

    if (ioctl(m_i_fd, VIDIOC_S_FMT, &fmt) == 0)
    {
        an_set_image_size( AV_PIX_FMT_YUV420P );
    }
    else
    {
        pix_fmt = V4L2_PIX_FMT_YUYV; // capture format
        fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width       = m_width;
        fmt.fmt.pix.height      = m_height;
        fmt.fmt.pix.pixelformat = pix_fmt;
        fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
        if (ioctl(m_i_fd, VIDIOC_S_FMT, &fmt) == 0)
        {
            // Format conversion will be required
            m_sws = sws_getContext( m_width, m_height, AV_PIX_FMT_YUYV422,
                                    m_width, m_height, AV_PIX_FMT_YUV420P,
                                    SWS_BICUBIC, NULL,NULL, NULL);
            an_set_image_size( AV_PIX_FMT_YUYV422 );
        }
        else
        {
            logger("CAP ANALOGUE FORMAT NOT SUPPORTED");
        }
    }

    if(ioctl(m_i_fd, VIDIOC_G_FMT, &fmt)<0 )
        logger("can't get format");

    //	input = V4L2_INPUT_TYPE_CAMERA;
    input = info.video_capture_device_input;

    if( ioctl( m_i_fd, VIDIOC_S_INPUT, &input) < 0 )
    {
        loggerf("CAP Error VIDIOC_S_INPUT %d",input);
    }

/*
    v4l2_streamparm parm;
    memset(&parm,0,sizeof(v4l2_streamparm));
    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    parm.parm.capture.capturemode = 0;
    parm.parm.capture.readbuffers = 0;

    if( ioctl( m_i_fd, VIDIOC_S_PARM, &parm) < 0 )
    {
        loggerf("CAP Error VIDIOC_S_PARM");
    }
*/
    info.video_bitrate = calculate_video_bitrate();

    //
    // Analogue sound capture
    //
    snd_pcm_hw_params_t *hw_params;

    if(snd_pcm_open(&m_audio_handle, "pulse", SND_PCM_STREAM_CAPTURE, 0)< 0 )
    {
        loggerf("Unable to open sound device");
        return;
    }
    unsigned int rate = 48000;
    int r;
    r = snd_pcm_hw_params_malloc(&hw_params);
    r = snd_pcm_hw_params_any(m_audio_handle, hw_params);
    r = snd_pcm_hw_params_set_access(m_audio_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    r = snd_pcm_hw_params_set_format(m_audio_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    r = snd_pcm_hw_params_set_rate_near(m_audio_handle, hw_params, &rate, 0);
    r = snd_pcm_hw_params_set_channels(m_audio_handle, hw_params, 2);
    r = snd_pcm_hw_params(m_audio_handle, hw_params);
    snd_pcm_hw_params_free(hw_params);
    r = snd_pcm_prepare(m_audio_handle);

    an_init_codecs();
    m_capturing = true;
    an_setup_video_capturing( m_i_fd );
    an_setup_audio_capturing();
}
示例#2
0
static RD_BOOL
alsa_set_format(snd_pcm_t * pcm, RD_WAVEFORMATEX * pwfx)
{
	snd_pcm_hw_params_t *hwparams = NULL;
	int err;
	unsigned int buffertime;
	short samplewidth;
	int audiochannels;
	unsigned int rate;

	samplewidth = pwfx->wBitsPerSample / 8;

	if ((err = snd_pcm_hw_params_malloc(&hwparams)) < 0)
	{
		error("snd_pcm_hw_params_malloc: %s\n", snd_strerror(err));
		return False;
	}

	if ((err = snd_pcm_hw_params_any(pcm, hwparams)) < 0)
	{
		error("snd_pcm_hw_params_any: %s\n", snd_strerror(err));
		return False;
	}

	if ((err = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{
		error("snd_pcm_hw_params_set_access: %s\n", snd_strerror(err));
		return False;
	}

	if (pwfx->wBitsPerSample == 16)
	{
		if ((err = snd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16_LE)) < 0)
		{
			error("snd_pcm_hw_params_set_format: %s\n", snd_strerror(err));
			return False;
		}
	}
	else
	{
		if ((err = snd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S8)) < 0)
		{
			error("snd_pcm_hw_params_set_format: %s\n", snd_strerror(err));
			return False;
		}
	}

#if 0
	if ((err = snd_pcm_hw_params_set_rate_resample(pcm, hwparams, 1)) < 0)
	{
		error("snd_pcm_hw_params_set_rate_resample: %s\n", snd_strerror(err));
		return False;
	}
#endif

	rate = pwfx->nSamplesPerSec;
	if ((err = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, 0)) < 0)
	{
		error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));
		return False;
	}

	audiochannels = pwfx->nChannels;
	if ((err = snd_pcm_hw_params_set_channels(pcm, hwparams, pwfx->nChannels)) < 0)
	{
		error("snd_pcm_hw_params_set_channels: %s\n", snd_strerror(err));
		return False;
	}


	buffertime = 500000;	/* microseconds */
	if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams, &buffertime, 0)) < 0)
	{
		error("snd_pcm_hw_params_set_buffer_time_near: %s\n", snd_strerror(err));
		return False;
	}

	if ((err = snd_pcm_hw_params(pcm, hwparams)) < 0)
	{
		error("snd_pcm_hw_params: %s\n", snd_strerror(err));
		return False;
	}

	snd_pcm_hw_params_free(hwparams);

	if ((err = snd_pcm_prepare(pcm)) < 0)
	{
		error("snd_pcm_prepare: %s\n", snd_strerror(err));
		return False;
	}

	reopened = True;

	return True;
}
示例#3
0
int main()
{
	int fp;
  unsigned int pcm, tmp, dir;
  int buff_size;
	
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  
  snd_pcm_uframes_t frames;
  char *buff;
  int rate, channels, seconds;

  /* Open PCM device for recording (capture). */
  rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0);

  if (rc < 0) 
  {
    fprintf(stderr,"unable to open pcm device: %s\n",   snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,  SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_U8);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 1);

  /* 44100 bits/second sampling rate (CD quality) */
  val = 8000;
  
  snd_pcm_hw_params_set_rate_near(handle, params,  &val, &dir);

  /* Set period size to 32 frames. */
  frames = 32;
  snd_pcm_hw_params_set_period_size_near(handle,params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) 
  {
    fprintf(stderr,"unable to set hw parameters: %s\n", snd_strerror(rc));
    exit(1);
  }

  /* Use a buff large enough to hold one period */

  snd_pcm_hw_params_get_period_size(params,  &frames, &dir);
  size = frames * 4; /* 2 bytes/sample, 2 channels */
  buff = (char *) malloc(size);

  /* We want to loop for 5 seconds */

  snd_pcm_hw_params_get_period_time(params, &val, &dir);
  loops = 50000000 / val;

	fp=open("222.wav",O_WRONLY);
  while (loops > 0) 
  {
		loops--;
		bzero(buff,sizeof(buff));
		rc = snd_pcm_readi(handle, buff, frames);
		write(fp,buff,128);
		if (rc == -EPIPE) 
		{
		  /* EPIPE means overrun */
		  fprintf(stderr, "overrun occurred\n");
		  snd_pcm_prepare(handle);
		} else if (rc < 0) 
		{
		  fprintf(stderr,"error from read: %s\n",  snd_strerror(rc));
		} else if (rc != (int)frames) 
		{
		  fprintf(stderr, "short read, read %d frames\n", rc);
		}
		
		/*rc = write(1, buff, size);
		if (rc != size)
		  fprintf(stderr,"short write: wrote %d bytes\n", rc);
	*/
  }

  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  
	free(buff);

	return 0;
}
示例#4
0
// alsa	      
	main (int argc, char *argv[])
	{
		int i;
		int err;
		short buf[128];
		snd_pcm_t *playback_handle;
		snd_pcm_hw_params_t *hw_params;
	
		if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
			fprintf (stderr, "cannot open audio device %s (%s)\n", 
				 argv[1],
				 snd_strerror (err));
			exit (1);
		}
		   
		if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
			fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
				 
		if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
			fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
			fprintf (stderr, "cannot set access type (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
			fprintf (stderr, "cannot set sample format (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 44100, 0)) < 0) {
			fprintf (stderr, "cannot set sample rate (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
			fprintf (stderr, "cannot set channel count (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
			fprintf (stderr, "cannot set parameters (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		snd_pcm_hw_params_free (hw_params);
	
		if ((err = snd_pcm_prepare (playback_handle)) < 0) {
			fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		for (i = 0; i < 10; ++i) {
			if ((err = snd_pcm_writei (playback_handle, buf, 128)) != 128) {
				fprintf (stderr, "write to audio interface failed (%s)\n",
					 snd_strerror (err));
				exit (1);
			}
		}
	
		snd_pcm_close (playback_handle);
		exit (0);
	}
示例#5
0
static void* sound_thread(void* context)
{
    struct SPU* c = (struct SPU*)context;
    int div;
    snd_pcm_t* snd;
    snd_pcm_hw_params_t* hwp;
    int rate = c->sampling;
    int periods = 3;
    snd_pcm_hw_params_alloca(&hwp);
    if (snd_pcm_open(&snd, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        return NULL;
    }
    if (snd_pcm_hw_params_any(snd, hwp) < 0) {
        return NULL;
    }
    div = c->bit / 8;
    switch (c->bit) {
        case 8:
            if (snd_pcm_hw_params_set_format(snd, hwp, SND_PCM_FORMAT_U8) < 0) {
                return NULL;
            }
            break;
        case 16:
            if (snd_pcm_hw_params_set_format(snd, hwp, SND_PCM_FORMAT_S16_LE) < 0) {
                return NULL;
            }
            break;
        case 24:
            if (snd_pcm_hw_params_set_format(snd, hwp, SND_PCM_FORMAT_S24_LE) < 0) {
                return NULL;
            }
            break;
        case 32:
            if (snd_pcm_hw_params_set_format(snd, hwp, SND_PCM_FORMAT_S32_LE) < 0) {
                return NULL;
            }
            break;
        default:
            return NULL;
    }
    if (snd_pcm_hw_params_set_rate_near(snd, hwp, &rate, 0) < 0) {
        return NULL;
    }
    if (rate != SAMPLE_RATE) {
        return NULL;
    }
    if (snd_pcm_hw_params_set_channels(snd, hwp, c->ch) < 0) {
        return NULL;
    }
    if (snd_pcm_hw_params_set_periods(snd, hwp, periods, 0) < 0) {
        return NULL;
    }
    if (snd_pcm_hw_params_set_buffer_size(snd, hwp, (periods * c->size) / 4) < 0) {
        return NULL;
    }
    if (snd_pcm_hw_params(snd, hwp) < 0) {
        return NULL;
    }
    while (c->alive) {
        c->callback(c->buffer, c->size);
        while (c->alive) {
            if (snd_pcm_writei(snd, c->buffer, c->size / div) < 0) {
                snd_pcm_prepare(snd);
            } else {
                break;
            }
        }
    }
    snd_pcm_drain(snd);
    snd_pcm_close(snd);
    return NULL;
}
示例#6
0
 main() {
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
 unsigned char *buffer;
  int i=0;

/* socket setting */
   int sd;
   struct sockaddr_in s_addr;
   int n, n_send, status;

   int on = 1;


   sd = socket (AF_INET, SOCK_DGRAM, 0);

   bzero(&s_addr, sizeof(s_addr));
   s_addr.sin_family = AF_INET;
   s_addr.sin_addr.s_addr = inet_addr("192.168.42.255");
   s_addr.sin_port = htons(2007);

   if((status = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))) != 0 )
   {
      printf("setsockopt error\n");
      exit(-1);
   }


  /* Open PCM device for recording (capture). */
  rc = snd_pcm_open(&handle, "plughw:1,0",
                    SND_PCM_STREAM_CAPTURE, 0);
  if (rc < 0) {
    fprintf(stderr,
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_U8);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 1);

  /* 44100 bits/second sampling rate (CD quality) */
  val = 44100;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);

  /* Set period size to 32 frames. */
  frames =4800;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params,
                                      &frames, &dir);
  size = frames *1; /* 2 bytes/sample, 2 channels */

  buffer = (unsigned char*) malloc(size);
	
  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,
                                         &val, &dir);
  while (1) {
    rc = snd_pcm_readi(handle, buffer, frames);
    if (rc == -EPIPE) {
      /* EPIPE means overrun */
      fprintf(stderr, "overrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      fprintf(stderr,
              "error from read: %s\n",
              snd_strerror(rc));
    } else if (rc != (int)frames) {
      fprintf(stderr, "short read, read %d frames\n", rc);
    }

if ((n_send = sendto(sd, buffer, strlen(buffer), 0, (struct sockaddr *)&s_addr, sizeof(s_addr))) < 0 ) {
	fprintf(stderr, "sendto() error");
         exit(-3);
      }
   }
  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);
   close(sd);
}
示例#7
0
bool QAudioInputPrivate::open()
{
#ifdef DEBUG_AUDIO
    QTime now(QTime::currentTime());
    qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
#endif
    clockStamp.restart();
    timeStamp.restart();
    elapsedTimeOffset = 0;

    int dir;
    int err = 0;
    int count=0;
    unsigned int freakuency=settings.frequency();

    if (!settings.isValid()) {
        qWarning("QAudioOutput: open error, invalid format.");
    } else if (settings.sampleRate() <= 0) {
        qWarning("QAudioOutput: open error, invalid sample rate (%d).",
                 settings.sampleRate());
    } else {
        err = -1;
    }

    if (err == 0) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit errorChanged(errorState);
        return false;
    }


    QString dev = QString(QLatin1String(m_device.constData()));
    QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput);
    if(dev.compare(QLatin1String("default")) == 0) {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        if (devices.size() > 0)
            dev = QLatin1String(devices.first());
        else
            return false;
#else
        dev = QLatin1String("hw:0,0");
#endif
    } else {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(m_device);
#else
        int idx = 0;
        char *name;

        QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());

        while(snd_card_get_name(idx,&name) == 0) {
            if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
                break;
            idx++;
        }
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
#endif
    }

    // Step 1: try and open the device
    while((count < 5) && (err < 0)) {
        err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
        if(err < 0)
            count++;
    }
    if (( err < 0)||(handle == 0)) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit stateChanged(deviceState);
        return false;
    }
    snd_pcm_nonblock( handle, 0 );

    // Step 2: Set the desired HW parameters.
    snd_pcm_hw_params_alloca( &hwparams );

    bool fatal = false;
    QString errMessage;
    unsigned int chunks = 8;

    err = snd_pcm_hw_params_any( handle, hwparams );
    if ( err < 0 ) {
        fatal = true;
        errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err);
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_access( handle, hwparams, access );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = setFormat();
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err);
        }
    }
    if( err < 0) {
        qWarning()<<errMessage;
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit stateChanged(deviceState);
        return false;
    }
    snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
    buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
    snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
    period_size = snd_pcm_frames_to_bytes(handle,period_frames);
    snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
    snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);

    // Step 3: Set the desired SW parameters.
    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_alloca(&swparams);
    snd_pcm_sw_params_current(handle, swparams);
    snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
    snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
    snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
    snd_pcm_sw_params(handle, swparams);

    // Step 4: Prepare audio
    ringBuffer.resize(buffer_size);
    snd_pcm_prepare( handle );
    snd_pcm_start(handle);

    // Step 5: Setup timer
    bytesAvailable = checkBytesReady();

    if(pullMode)
        connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));

    // Step 6: Start audio processing
    chunks = buffer_size/period_size;
    timer->start(period_time*chunks/2000);

    errorState  = QAudio::NoError;

    totalTimeValue = 0;

    return true;
}
示例#8
0
void play(int sec, int freq, char *file)
{
	long loops;
	int rc;
	int size;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *params;
	unsigned int val;
	int dir;
	snd_pcm_uframes_t frames;
	char *buffer;
	int fd;

	/* Check ranges */
	if (sec < 1 || sec > 4000) {
		printf("WARNING: Incorrect time to play range [1,4000] s\n");
		printf("\tSetting time to play to 5s...\n");
		sec = 5;
	}
	if (freq < 1000 || freq > 100000) {
		printf("ERROR: Incorrect frequency range [1000,100000] Hz\n");
		printf("\tSetting frequency to 44.1 kHz...\n");
		freq = 44100;
	}

	/* Open file */
	fd = open(file, O_RDONLY);
	if (fd < 0) {
		/* There was an error opening the file */
		printf("ERROR: Couldn't open file to play\n");
		printf("\tPlease make sure file exists\n");
	} else {
		/* Print that the file is playing with its parameters */
		printf("Playing file %s for %d seconds", file, sec);
		printf(" and frequency %d...\n", freq);

		/* Open PCM device for playback */
		rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK,
			0);
		if (rc < 0) {
			fprintf(stderr, "unable to open pcm device: %s\n",
				snd_strerror(rc));
			exit(1);
		}

		/* Allocate a hardware parameters object */
		snd_pcm_hw_params_alloca(&params);
		/* Fill it in with default values */
		snd_pcm_hw_params_any(handle, params);

		/* Set hardware parameters */

		/* Interleaved mode */
		snd_pcm_hw_params_set_access(handle, params,
		SND_PCM_ACCESS_RW_INTERLEAVED);
		/* Signed 16-bit little-endian format */
		snd_pcm_hw_params_set_format(handle, params,
			SND_PCM_FORMAT_S16_LE);
		/* Two channels (stereo) */
		snd_pcm_hw_params_set_channels(handle, params, 2);
		/* freq bits/second sampling rate (CD quality) */
		val = freq;
		snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
		/* Set period size to 32 frames */
		frames = 32;
		snd_pcm_hw_params_set_period_size_near(handle, params,
			&frames, &dir);
		/* Write the parameters to the driver */
		rc = snd_pcm_hw_params(handle, params);
		if (rc < 0) {
			fprintf(stderr, "unable to set hw parameters: %s\n",
				snd_strerror(rc));
			exit(1);
		}

		/* Use a buffer large enough to hold one period */
		snd_pcm_hw_params_get_period_size(params, &frames, &dir);
		size = frames * 4; /* 2 bytes/sample, 2 channels */
		buffer = (char *) malloc(size);
		/* We want to loop for sec seconds */
		snd_pcm_hw_params_get_period_time(params, &val, &dir);
		/* sec seconds in microseconds divided by period time */
		loops = sec*1000000 / val;

		while (loops > 0) {
			loops--;
			rc = read(fd, buffer, size);
			if (rc == 0) {
				fprintf(stderr, "end of file on input\n");
				break;
			} else if (rc != size) {
				fprintf(stderr, "short read: read %d bytes\n",
					rc);
			}
			rc = snd_pcm_writei(handle, buffer, frames);
			if (rc == -EPIPE) {
				/* EPIPE means underrun */
				fprintf(stderr, "underrun occurred\n");
				snd_pcm_prepare(handle);
			} else if (rc < 0) {
				fprintf(stderr, "error from writei: %s\n",
				snd_strerror(rc));
			}  else if (rc != (int)frames) {
				fprintf(stderr,
					"short write, write %d frames\n", rc);
			}
		}
		/*Close handle and free buffer*/
		snd_pcm_drain(handle);
		snd_pcm_close(handle);
		free(buffer);
	}
}
/*----------------------------------------------------------------------
|    AlsaOutput_Write
+---------------------------------------------------------------------*/
static BLT_Result
AlsaOutput_Write(AlsaOutput* self, void* buffer, BLT_Size size)
{
    int          watchdog = 5;
    int          io_result;
    unsigned int sample_count;
    unsigned int sample_size;
    BLT_Result   result;

    /* ensure that the device is prepared */
    result = AlsaOutput_Prepare(self);
    if (BLT_FAILED(result)) return result;

    /* compute the number of samples */
    sample_size  = self->media_type.channel_count*self->media_type.bits_per_sample/8;
    sample_count = size / sample_size;
                           
    /* write samples to the device and handle underruns */       
    do {
        while (sample_count) {
            io_result = snd_pcm_writei(self->device_handle, 
                                       buffer, sample_count);
            if (io_result > 0) {
                buffer = (void*)((char*)buffer + io_result*sample_size);
                if ((unsigned int)io_result <= sample_count) {
                    sample_count -= io_result;
                } else {
                    /* strange, snd_pcm_writei returned more than we wrote */
                    sample_count = 0;
                }
            } else {
                break;
            }
        }        
        if (sample_count == 0) return BLT_SUCCESS;

        /* we reach this point if the first write failed */
        if (io_result < 0) {
            snd_pcm_status_t* status;
            snd_pcm_state_t   state;
            snd_pcm_status_alloca_no_assert(&status);

            io_result = snd_pcm_status(self->device_handle, status);
            if (io_result != 0) {
                return BLT_FAILURE;
            }
            state = snd_pcm_status_get_state(status);
            if (state == SND_PCM_STATE_XRUN) {
                ATX_LOG_FINE("**** UNDERRUN *****");
            
                /* re-prepare the channel */
                io_result = snd_pcm_prepare(self->device_handle);
                if (io_result != 0) {
                    return BLT_FAILURE;
                }
            } else {
               ATX_LOG_WARNING_1("**** STATE = %d ****", state);
            }
        } else {
            ATX_LOG_WARNING_1("snd_pcm_writei() returned %d", io_result); 
        }
        
        ATX_LOG_FINE("**** RETRY *****");

    } while(watchdog--);

    ATX_LOG_SEVERE("**** THE WATCHDOG BIT US ****");
    return BLT_FAILURE;
}
示例#10
0
void *audiothread(void *v) {
    int						policy;
    sched_param		sched;
    int						err;
    alsaaudio 		*dev;

    pthread_getschedparam(pthread_self(),&policy,&sched);
    sched.sched_priority++;//policy=SCHED_RR;
    pthread_setschedparam(pthread_self(),policy,&sched);
    dev=(alsaaudio*)v;

    unsigned int val;
    snd_pcm_t *fd;
    snd_pcm_uframes_t periodsize;
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_hw_params_alloca(&hwparams);
    int output_rate;
    int channels;
    int fragment_size;
    int fragment_count;

    err=snd_pcm_open(&fd, strdup("default"), SND_PCM_STREAM_PLAYBACK, 0);
    if (err<0) return -1;

    fragment_size=LINUXFRAG;  //overall buffer size
    fragment_count=2; //2 - 16 fragment count - 2 minimum, the lower it is potentially the lower the latency

//configure device
    if (snd_pcm_hw_params_any(fd, hwparams) < 0) {
        //printf("linuxaudio failed at params any\n");
        return -1;
    }
    if (snd_pcm_hw_params_set_access(fd, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
        //printf("linuxaudio failed at set access\n");
        return -1;
    }

    if (snd_pcm_hw_params_set_format(fd, hwparams,SND_PCM_FORMAT_S16_LE) < 0) {
        //printf("linuxaudio failed at set format\n");
        return -1;
    }
    val = 44100;
    if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) {
        // Try 48KHZ too
        //printf("linuxaudio - %d HZ not available, trying 48000HZ\n", output_rate);
        val = 48000;
        if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) {
            //printf("linuxaudio failed at setting output rate (%d)\n", output_rate);
            return -1;
        }
        dev->mix->freq=val;
    }
    channels=2;
    if (snd_pcm_hw_params_set_channels(fd, hwparams, channels) < 0) {
        //printf("linuxaudio failed at set channels (%d)\n", channels);
        return -1;
    }
    periodsize = (fragment_size) / 4; // bytes -> frames for 16-bit,stereo - should be a minimum of 512
    if (snd_pcm_hw_params_set_period_size_near(fd, hwparams,&periodsize, 0) < 0) {
        //printf("linuxaudio failed at set period size (%d)\n", (int)periodsize);
        return -1;
    }
    val = fragment_count;
    if (snd_pcm_hw_params_set_periods_near(fd, hwparams,&val, 0) < 0) {
        //printf("linuxaudio failed at set periods (%d)\n", val);
        //should attempt a one by one period increase up to 16?
        return -1;
    }
    if (snd_pcm_hw_params(fd, hwparams) < 0) {
        //printf("linuxaudio failed at installing hw params\n");
        return -1;
    }
    //loop while playing sound
    dev->playing=1;
    while (dev->playing)
    {
        dev->mix->mix16(dev->buffer);
        if ((snd_pcm_writei (fd, dev->buffer,LINUXFRAG/2)) < 0) {	//Half buffer for two channels?
            //printf ("linuxaudio warning: buffer underrun occurred\n");
            if (snd_pcm_prepare(fd) < 0) {
                //printf ("linuxaudio failed at preparing pcm\n");
                dev->playing=0; //die gracefully
            }
        }
    }
    snd_pcm_drop(fd);
    snd_pcm_close (fd);
    return 0;
}
示例#11
0
static int alsa_open (struct sound_params *sound_params)
{
	snd_pcm_hw_params_t *hw_params;
	int err;
	unsigned int period_time;
	unsigned int buffer_time;
	snd_pcm_uframes_t chunk_frames;
	snd_pcm_uframes_t buffer_frames;
	char fmt_name[128];

	switch (sound_params->fmt & SFMT_MASK_FORMAT) {
		case SFMT_S8:
			params.format = SND_PCM_FORMAT_S8;
			break;
		case SFMT_U8:
			params.format = SND_PCM_FORMAT_U8;
			break;
		case SFMT_S16:
			params.format = SND_PCM_FORMAT_S16;
			break;
		case SFMT_U16:
			params.format = SND_PCM_FORMAT_U16;
			break;
		case SFMT_S32:
			params.format = SND_PCM_FORMAT_S32;
			break;
		case SFMT_U32:
			params.format = SND_PCM_FORMAT_U32;
			break;
		default:
			error ("Unknown sample format: %s",
					sfmt_str(sound_params->fmt, fmt_name,
						sizeof(fmt_name)));
			params.format = SND_PCM_FORMAT_UNKNOWN;
			return 0;
	}

	if ((err = snd_pcm_open(&handle, options_get_str("AlsaDevice"),
					SND_PCM_STREAM_PLAYBACK,
					SND_PCM_NONBLOCK)) < 0) {
		error ("Can't open audio: %s", snd_strerror(err));
		return 0;
	}

	if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
		error ("Can't allocate alsa hardware parameters structure: %s",
				snd_strerror(err));
		return 0;
	}

	if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) {
		error ("Can't initialize hardware parameters structure: %s",
				snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
		error ("Can't set alsa access type: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if ((err = snd_pcm_hw_params_set_format (handle, hw_params,
					params.format)) < 0) {
		error ("Can't set sample format: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	params.rate = sound_params->rate;
	if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params,
					&params.rate, 0)) < 0) {
		error ("Can't set sample rate: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	logit ("Set rate to %d", params.rate);
	
	if ((err = snd_pcm_hw_params_set_channels (handle, hw_params,
					sound_params->channels)) < 0) {
		error ("Can't set number of channels: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if ((err = snd_pcm_hw_params_get_buffer_time_max(hw_params,
					&buffer_time, 0)) < 0) {
		error ("Can't get maximum buffer time: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if (buffer_time > BUFFER_MAX_USEC)
		buffer_time = BUFFER_MAX_USEC;
	period_time = buffer_time / 4;

	if ((err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, 
					&period_time, 0)) < 0) {
		error ("Can't set period time: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if ((err = snd_pcm_hw_params_set_buffer_time_near(handle, hw_params, 
					&buffer_time, 0)) < 0) {
		error ("Can't set buffer time: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
		error ("Can't set audio parameters: %s", snd_strerror(err));
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	snd_pcm_hw_params_get_period_size (hw_params, &chunk_frames, 0);
	snd_pcm_hw_params_get_buffer_size (hw_params, &buffer_frames);

	bytes_per_frame = sound_params->channels
		* sfmt_Bps(sound_params->fmt);

	logit ("Buffer time: %ldus", buffer_frames * bytes_per_frame);

	if (chunk_frames == buffer_frames) {
		error ("Can't use period equal to buffer size (%lu == %lu)",
				chunk_frames, buffer_frames);
		snd_pcm_hw_params_free (hw_params);
		return 0;
	}

	chunk_size = chunk_frames * bytes_per_frame;

	debug ("Chunk size: %d", chunk_size);
	
	snd_pcm_hw_params_free (hw_params);
	
	if ((err = snd_pcm_prepare(handle)) < 0) {
		error ("Can't prepare audio interface for use: %s",
				snd_strerror(err));
		return 0;
	}

	debug ("ALSA device initialized");
	
	params.channels = sound_params->channels;
	alsa_buf_fill = 0;
	return 1;
}
示例#12
0
static int ca_thread_func (void *arg)
{
    struct alsa_stream* stream = (struct alsa_stream*) arg;
    snd_pcm_t* pcm             = stream->ca_pcm;
    int size                   = stream->ca_buf_size;
    snd_pcm_uframes_t nframes  = stream->ca_frames;
    void* user_data            = stream->user_data;
    char* buf 		       = stream->ca_buf;
    pj_timestamp tstamp;
    int result;
    struct sched_param param;
    pthread_t* thid;

    thid = (pthread_t*) pj_thread_get_os_handle (pj_thread_this());
    param.sched_priority = sched_get_priority_max (SCHED_RR);
    PJ_LOG (5,(THIS_FILE, "ca_thread_func(%u): Set thread priority "
		          "for audio capture thread.",
		          (unsigned)syscall(SYS_gettid)));
    result = pthread_setschedparam (*thid, SCHED_RR, &param);
    if (result) {
	if (result == EPERM)
	    PJ_LOG (5,(THIS_FILE, "Unable to increase thread priority, "
				  "root access needed."));
	else
	    PJ_LOG (5,(THIS_FILE, "Unable to increase thread priority, "
				  "error: %d",
				  result));
    }

    pj_bzero (buf, size);
    tstamp.u64 = 0;

    TRACE_((THIS_FILE, "ca_thread_func(%u): Started",
	    (unsigned)syscall(SYS_gettid)));

    snd_pcm_prepare (pcm);

    while (!stream->quit) {
	pjmedia_frame frame;

	pj_bzero (buf, size);
	result = snd_pcm_readi (pcm, buf, nframes);
	if (result == -EPIPE) {
	    PJ_LOG (4,(THIS_FILE, "ca_thread_func: overrun!"));
	    snd_pcm_prepare (pcm);
	    continue;
	} else if (result < 0) {
	    PJ_LOG (4,(THIS_FILE, "ca_thread_func: error reading data!"));
	}
	if (stream->quit)
	    break;

	frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
	frame.buf = (void*) buf;
	frame.size = size;
	frame.timestamp.u64 = tstamp.u64;
	frame.bit_info = 0;

	result = stream->ca_cb (user_data, &frame);
	if (result != PJ_SUCCESS || stream->quit)
	    break;

	tstamp.u64 += nframes;
    }
    snd_pcm_drain (pcm);
    TRACE_((THIS_FILE, "ca_thread_func: Stopped"));

    return PJ_SUCCESS;
}
示例#13
0
int main(int argc, char **argv){
   int i;
   int aver,val,val2;
   int16_t buf[BUFSIZE];
   double d_buffer[BUFSIZE];
   double pitch = 0.0;
   struct timespec before,after;
   struct pitch_tracker_params *settings;
   snd_pcm_uframes_t period_size = PERIOD_SIZE;

   //ALSA PCM configuration
   snd_pcm_t *handle;
   snd_pcm_hw_params_t *params;
   int dir,rc;
   snd_pcm_uframes_t frames;

   /* Open PCM device for capture */
   rc = snd_pcm_open( &handle, "default" , SND_PCM_STREAM_CAPTURE , 0);

   if(rc < 0 ){
      fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc));
      exit(1);
   }

   /* Allocate a hardware parameters object. */
   snd_pcm_hw_params_alloca(&params);

   /* Fill it in with default values. */
   snd_pcm_hw_params_any(handle, params);

   /* Set the desired hardware parameters. */

   /* Interleaved mode */
   snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED);

   /* unsigned 16-bit format */
   snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16);

   snd_pcm_hw_params_set_channels(handle, params, 1);

   /* 44100 bits/second sampling rate */
   val = 44100;
   snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir);

   /* set size time*/
   snd_pcm_hw_params_set_period_size_near(handle, params, &period_size , &dir);

   /* write configuration */
   rc = snd_pcm_hw_params(handle,params);


   /*Display info*/

   printf("PCM handle name = '%s'\n",
         snd_pcm_name(handle));

   printf("PCM state = %s\n",
         snd_pcm_state_name(snd_pcm_state(handle)));

   snd_pcm_hw_params_get_access(params,
         (snd_pcm_access_t *) &val);
   printf("access type = %s\n",
         snd_pcm_access_name((snd_pcm_access_t)val));

   snd_pcm_hw_params_get_format(params, &val);
   printf("format = '%s' (%s)\n",
         snd_pcm_format_name((snd_pcm_format_t)val),
         snd_pcm_format_description(
            (snd_pcm_format_t)val));

   snd_pcm_hw_params_get_subformat(params,
         (snd_pcm_subformat_t *)&val);
   printf("subformat = '%s' (%s)\n",
         snd_pcm_subformat_name((snd_pcm_subformat_t)val),
         snd_pcm_subformat_description(
            (snd_pcm_subformat_t)val));

   snd_pcm_hw_params_get_channels(params, &val);
   printf("channels = %d\n", val);

   snd_pcm_hw_params_get_rate(params, &val, &dir);
   printf("rate = %d bps\n", val);

   snd_pcm_hw_params_get_period_time(params,
         &val, &dir);
   printf("period time = %d us\n", val);

   snd_pcm_hw_params_get_period_size(params,
         &frames, &dir);
   printf("period size = %d frames\n", (int)frames);

   snd_pcm_hw_params_get_buffer_time(params,
         &val, &dir);
   printf("buffer time = %d us\n", val);

   snd_pcm_hw_params_get_buffer_size(params,
         (snd_pcm_uframes_t *) &val);
   printf("buffer size = %d frames\n", val);

   snd_pcm_hw_params_get_periods(params, &val, &dir);
   printf("periods per buffer = %d frames\n", val);

   snd_pcm_hw_params_get_rate_numden(params,
         &val, &val2);
   printf("exact rate = %d/%d bps\n", val, val2);

   val = snd_pcm_hw_params_get_sbits(params);
   printf("significant bits = %d\n", val);

   val = snd_pcm_hw_params_is_batch(params);
   printf("is batch = %d\n", val);

   val = snd_pcm_hw_params_is_block_transfer(params);
   printf("is block transfer = %d\n", val);

   val = snd_pcm_hw_params_is_double(params);
   printf("is double = %d\n", val);

   val = snd_pcm_hw_params_is_half_duplex(params);
   printf("is half duplex = %d\n", val);

   val = snd_pcm_hw_params_is_joint_duplex(params);
   printf("is joint duplex = %d\n", val);

   val = snd_pcm_hw_params_can_overrange(params);
   printf("can overrange = %d\n", val);

   val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
   printf("can mmap = %d\n", val);

   val = snd_pcm_hw_params_can_pause(params);
   printf("can pause = %d\n", val);

   val = snd_pcm_hw_params_can_resume(params);
   printf("can resume = %d\n", val);

   val = snd_pcm_hw_params_can_sync_start(params);
   printf("can sync start = %d\n", val);

   settings = open_pitch_tracker();

   while(1){
      rc = snd_pcm_readi(handle, buf, frames);
      if (rc == -EPIPE) {
         /* EPIPE means overrun */
         fprintf(stderr, "overrun occurred\n");
         snd_pcm_prepare(handle);
      } else if (rc < 0) {
         fprintf(stderr,
               "error from read: %s\n",
               snd_strerror(rc));
      } else if (rc != (int)frames) {
         fprintf(stderr, "short read, read %d frames\n", rc);
      }


      for( i = 0 ; i< BUFSIZE ; i++){
         d_buffer[i] = (double) buf[i];
      }
      pitch = compute_pitch(d_buffer, BUFSIZE, S16, settings ,ACCURACY);
      if( pitch != 0.0 )
         printf("frequency -> %f\n",pitch);

      memset(buf,0,BUFSIZE);
   }


   close_pitch_tracker(&settings);
   snd_pcm_drain(handle);
   snd_pcm_close(handle);

   return 0;
}
示例#14
0
文件: record.cpp 项目: SPICEorg/spice
void WaveRecorder::stop()
{
    snd_pcm_drop(_pcm);
    snd_pcm_prepare(_pcm);
}
示例#15
0
文件: AESinkALSA.cpp 项目: Ilia/xbmc
bool CAESinkALSA::Initialize(AEAudioFormat &format, std::string &device)
{
  m_initDevice = device;
  m_initFormat = format;

  /* if we are raw, correct the data format */
  if (AE_IS_RAW(format.m_dataFormat))
  {
    m_channelLayout     = GetChannelLayout(format);
    format.m_dataFormat = AE_FMT_S16NE;
    m_passthrough       = true;
  }
  else
  {
    m_channelLayout = GetChannelLayout(format);
    m_passthrough   = false;
  }
#if defined(HAS_AMLPLAYER) || defined(HAS_LIBAMCODEC)
  if (aml_present())
  {
    aml_set_audio_passthrough(m_passthrough);
    device = "default";
  }
#endif

  if (m_channelLayout.Count() == 0)
  {
    CLog::Log(LOGERROR, "CAESinkALSA::Initialize - Unable to open the requested channel layout");
    return false;
  }

  format.m_channelLayout = m_channelLayout;

  AEDeviceType devType = AEDeviceTypeFromName(device);

  std::string AESParams;
  /* digital interfaces should have AESx set, though in practice most
   * receivers don't care */
  if (m_passthrough || devType == AE_DEVTYPE_HDMI || devType == AE_DEVTYPE_IEC958)
    GetAESParams(format, AESParams);

  CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Attempting to open device \"%s\"", device.c_str());

  /* get the sound config */
  snd_config_t *config;
  snd_config_copy(&config, snd_config);

  if (!OpenPCMDevice(device, AESParams, m_channelLayout.Count(), &m_pcm, config))
  {
    CLog::Log(LOGERROR, "CAESinkALSA::Initialize - failed to initialize device \"%s\"", device.c_str());
    snd_config_delete(config);
    return false;
  }

  /* get the actual device name that was used */
  device = snd_pcm_name(m_pcm);
  m_device = device;

  CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Opened device \"%s\"", device.c_str());

  /* free the sound config */
  snd_config_delete(config);

  if (!InitializeHW(format) || !InitializeSW(format))
    return false;

  snd_pcm_nonblock(m_pcm, 1);
  snd_pcm_prepare (m_pcm);

  m_format              = format;
  m_formatSampleRateMul = 1.0 / (double)m_format.m_sampleRate;

  return true;
}
示例#16
0
int main()
{

const snd_pcm_channel_area_t *areas;
int size;
unsigned char *buffer;
char *pcm_name;
unsigned int rate = 8000;
int chan;
int rc;
unsigned int  val;
char check;
int pcmreturn;

//Set PCM stream and handle
snd_pcm_t *pcm_handle;
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

//Set HARDWARE parameters
snd_pcm_hw_params_t *hwparams;


//pcm_name = (char *)malloc(10);
pcm_name = "plughw:0,0";


//allocate memory for hardware
if(snd_pcm_hw_params_malloc(&hwparams)<0)
	{

		fprintf(stderr,"No memory allocated for hardware");
		return(-1);
	
	}



if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
      fprintf(stderr, "Error opening PCM device %s\n", pcm_name);
            return(-1);
	        }

//INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD
	if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0)
		{
			fprintf(stderr,"The hardware device cannot be configured\n");


		}




//SET FORMAT TO 16 BIT LITTLE ENDIAN
snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE);


/* Two channels (stereo) */
 snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2);

 
    /* 44100 bits/second sampling rate (CD quality) */
      
 if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
       fprintf(stderr, "Error setting access.\n");
             return(-1);
	         }


//SETTING RATE ie SAMPLING FREQUENCY

snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0);


//SETTING HARDWARE PARAMETERS

	if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0)
		{
			fprintf(stderr,"\nCannot set hardware parameters\n");
			return -1;
		}



//snd_pcm_uframes_t periodsize = 8192;


snd_pcm_uframes_t  frames,offset ;//OF TYPE UNSIGNED LONG
snd_pcm_sframes_t commitres;
//frames =32;


//SETTING SOME MORE PARAMETERS

//size = frames*4;
//SETTING BUFFER SIZE

/*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) {
      fprintf(stderr, "Error setting buffersize.\n");
            return(-1);


}
*/

int first=0;;
int err;
snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle);
printf("\nNumber of frames available is : %d \n",(int)avail);


//-------------------------------------------------------------------------------------------------------
//<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Buffer size

snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val);
printf("\nThe buffer size is %d \n",val);


//Buffer time

snd_pcm_hw_params_get_buffer_time(hwparams, &val,0);
printf("\nBuffer time is : %d \n",val);


//Period size

snd_pcm_hw_params_get_period_size(hwparams,&frames,0);
printf("\nperiod size : %d \n",(int)frames);



////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//<<<<<<<<<<<<<mmap_begin>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames);


//Periods between buffer

snd_pcm_hw_params_get_periods(hwparams,&val,0);
printf("\n Periods between buffer is : %d \n",val);




//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

if(err<0)
	{
	printf("\nMMAP error\n");
	return -1;

	
	
	}
else printf("\n%d\n",err);


/*
commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames);
if(commitres<0)
	{
		printf("\nFrames not committed to memory\n");
	}

*/

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<               >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,OPENING FILE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>....



int dest =  open("sample3.wav",O_RDONLY);

if(dest<0)
	{
		perror("\nFile could not be opened\n");
		return -1;
	}



//buffer = (unsigned char *)malloc(1000);

/*

unsigned long buf = offset;
 if(read(dest,&offset,1)<0)
	{
		perror("\nNo destination for read\n");
		return -1;
	}
*/


/*
avail=snd_pcm_avail_update(pcm_handle);
printf("\nAvailable frames = %d \n\n",(int)avail);
struct timeval tvbefore,tvafter;
gettimeofday(&tvbefore,NULL);
*/
unsigned char *ptr[2];



int i;
//unsigned int steps=0;

for(i=0;i<2;i++)
 ptr[i] = (unsigned char*)areas[i].addr  + (areas[i].first/8) + offset*(areas[i].step/8);

printf("\nOffset of the first sample : %u \n",areas[0].first);
printf("\n\nOffset of the memory map is : %u \n",areas[0].step/8);
printf("\nAreas start address is : %u \n",areas[0].addr);
printf("\nNumber of frames ; %u \n",frames);

printf("\n\nPointer before ; %u \n",ptr[0]);


long pl;
for(pl=0;pl<100000;pl++);

if(ptr[1]==NULL)
printf("\nNull pointer 1  allocated\n");
if(ptr[0]==NULL)
printf("\nNull pointer 0 allocated \n");




int check2=1;

snd_pcm_sframes_t size2 =30;
while(1)
	{
		for(i=0;i<2;i++)
		{
		//ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8);
		
		if(read(dest,ptr[i],120)!=0)
			{
				
				
					if(ptr[i]!=NULL)
					{
						 	
						if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,ptr[i],size2)<0)
							{
								snd_pcm_prepare(pcm_handle);
								printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n");
								break;
							}
					
			

						//	printf("\n%d\n",pcmreturn);
						ptr[i]+=0;
						printf("\n%lu\n",ptr[i]);


					}
											

			}
			else {
				check2=0;
				break;
				}
		}
		
		

		if(check2==0)
		break;
		

			
		
	//	l:break;

	}

	commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames);
	 if(commitres<0)
	         {
	                 printf("\nFrames not committed to memory\n");
	         }

	
}
示例#17
0
文件: dsoutput.c 项目: r6144/wine
static HRESULT SetFormat(IDsDriverBufferImpl *This, LPWAVEFORMATEX pwfx)
{
    snd_pcm_t *pcm = NULL;
    snd_pcm_hw_params_t *hw_params = This->hw_params;
    unsigned int buffer_time = 500000;
    snd_pcm_format_t format = -1;
    snd_pcm_uframes_t psize;
    DWORD rate = pwfx->nSamplesPerSec;
    int err=0;

    switch (pwfx->wBitsPerSample)
    {
        case  8: format = SND_PCM_FORMAT_U8; break;
        case 16: format = SND_PCM_FORMAT_S16_LE; break;
        case 24: format = SND_PCM_FORMAT_S24_3LE; break;
        case 32: format = SND_PCM_FORMAT_S32_LE; break;
        default: FIXME("Unsupported bpp: %d\n", pwfx->wBitsPerSample); return DSERR_GENERIC;
    }

    err = snd_pcm_open(&pcm, WOutDev[This->drv->wDevID].pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
    if (err < 0)
    {
        if (errno != EBUSY || !This->pcm)
        {
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_GENERIC;
        }
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
        This->pcm = NULL;
        err = snd_pcm_open(&pcm, WOutDev[This->drv->wDevID].pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
        if (err < 0)
        {
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_BUFFERLOST;
        }
    }

    /* Set some defaults */
    snd_pcm_hw_params_any(pcm, hw_params);
    err = snd_pcm_hw_params_set_channels(pcm, hw_params, pwfx->nChannels);
    if (err < 0) { WARN("Could not set channels to %d\n", pwfx->nChannels); goto err; }

    err = snd_pcm_hw_params_set_format(pcm, hw_params, format);
    if (err < 0) { WARN("Could not set format to %d bpp\n", pwfx->wBitsPerSample); goto err; }

    /* Alsa's rate resampling is only used if the application specifically requests
     * a buffer at a certain frequency, else it is better to disable it due to unwanted
     * side effects, which may include: Less granular pointer, changing buffer sizes, etc
     */
#if SND_LIB_VERSION >= 0x010009
    snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
#endif

    err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, NULL);
    if (err < 0) { rate = pwfx->nSamplesPerSec; WARN("Could not set rate\n"); goto err; }

    if (!ALSA_NearMatch(rate, pwfx->nSamplesPerSec))
    {
        WARN("Could not set sound rate to %d, but instead to %d\n", pwfx->nSamplesPerSec, rate);
        pwfx->nSamplesPerSec = rate;
        pwfx->nAvgBytesPerSec = rate * pwfx->nBlockAlign;
        /* Let DirectSound detect this */
    }

    snd_pcm_hw_params_set_periods_integer(pcm, hw_params);
    snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_time, NULL);
    buffer_time = 10000;
    snd_pcm_hw_params_set_period_time_near(pcm, hw_params, &buffer_time, NULL);

    err = snd_pcm_hw_params_get_period_size(hw_params, &psize, NULL);
    buffer_time = 16;
    snd_pcm_hw_params_set_periods_near(pcm, hw_params, &buffer_time, NULL);

    if (!This->mmap)
    {
        HeapFree(GetProcessHeap(), 0, This->mmap_buffer);
        This->mmap_buffer = NULL;
    }

    err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
    if (err >= 0)
        This->mmap = 1;
    else
    {
        This->mmap = 0;
        err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    }

    err = snd_pcm_hw_params(pcm, hw_params);

    /* ALSA needs at least 3 buffers to work successfully */
    This->mmap_commitahead = 3 * psize;
    while (This->mmap_commitahead <= 512)
        This->mmap_commitahead += psize;

    if (This->pcm)
    {
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
    }
    This->pcm = pcm;
    snd_pcm_prepare(This->pcm);
    DSDB_CreateMMAP(This);
    return S_OK;

    err:
    if (err < 0)
        WARN("Failed to apply changes: %s\n", snd_strerror(err));

    if (!This->pcm)
        This->pcm = pcm;
    else
        snd_pcm_close(pcm);

    if (This->pcm)
        snd_pcm_hw_params_current(This->pcm, This->hw_params);

    return DSERR_BADFORMAT;
}
示例#18
0
static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa)
{
    snd_pcm_hw_params_t* hw_params;
    snd_pcm_sw_params_t* sw_params;
    int error;
    snd_pcm_uframes_t frames;
    snd_pcm_uframes_t start_threshold;

    snd_pcm_drop(alsa->out_handle);

    error = snd_pcm_hw_params_malloc(&hw_params);
    if (error < 0)
    {
        DEBUG_WARN("snd_pcm_hw_params_malloc failed");
        return;
    }
    snd_pcm_hw_params_any(alsa->out_handle, hw_params);
    snd_pcm_hw_params_set_access(alsa->out_handle, hw_params,
                                 SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(alsa->out_handle, hw_params,
                                 alsa->format);
    snd_pcm_hw_params_set_rate_near(alsa->out_handle, hw_params,
                                    &alsa->actual_rate, NULL);
    snd_pcm_hw_params_set_channels_near(alsa->out_handle, hw_params,
                                        &alsa->actual_channels);
    if (alsa->latency < 0)
        frames = alsa->actual_rate * 4; /* Default to 4-second buffer */
    else
        frames = alsa->latency * alsa->actual_rate * 2 / 1000; /* Double of the latency */
    if (frames < alsa->actual_rate / 2)
        frames = alsa->actual_rate / 2; /* Minimum 0.5-second buffer */
    snd_pcm_hw_params_set_buffer_size_near(alsa->out_handle, hw_params,
                                           &frames);
    snd_pcm_hw_params(alsa->out_handle, hw_params);
    snd_pcm_hw_params_free(hw_params);

    error = snd_pcm_sw_params_malloc(&sw_params);
    if (error < 0)
    {
        DEBUG_WARN("snd_pcm_sw_params_malloc failed");
        return;
    }
    snd_pcm_sw_params_current(alsa->out_handle, sw_params);
    if (alsa->latency == 0)
        start_threshold = 0;
    else
        start_threshold = frames / 2;
    snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params, start_threshold);
    snd_pcm_sw_params(alsa->out_handle, sw_params);
    snd_pcm_sw_params_free(sw_params);

    snd_pcm_prepare(alsa->out_handle);

    DEBUG_SVC("hardware buffer %d frames, playback buffer %.2g seconds",
              (int)frames, (double)frames / 2.0 / (double)alsa->actual_rate);
    if ((alsa->actual_rate != alsa->source_rate) ||
            (alsa->actual_channels != alsa->source_channels))
    {
        DEBUG_SVC("actual rate %d / channel %d is different from source rate %d / channel %d, resampling required.",
                  alsa->actual_rate, alsa->actual_channels, alsa->source_rate, alsa->source_channels);
    }
}
示例#19
0
alsa_dev_t* alsa_open(char *name)
{
    alsa_dev_t *alsa_dev = NULL;
    snd_pcm_hw_params_t *params = NULL;
    uint32_t val = 0;
    int32_t rc = 0;
    int32_t dir = 0;

    alsa_dev = malloc(sizeof(alsa_dev_t));
    if (!alsa_dev)
    {
        syslog(LOG_ERR, "Failed to create audio device: Out of memory");
        exit(EXIT_FAILURE);
    }

    /* Open PCM device for recording (capture). */
    rc = snd_pcm_open(&alsa_dev->snd_pcm, name, SND_PCM_STREAM_CAPTURE, 0);
    if (rc < 0)
    {
        syslog(LOG_ERR, "Cannot open pcm device: %s", snd_strerror(rc));
        exit(EXIT_FAILURE);
    }

    alsa_dev->name = name;

    /* Allocate a hardware parameters object. */
    snd_pcm_hw_params_alloca(&params);

    /* Fill it in with default values. */
    snd_pcm_hw_params_any(alsa_dev->snd_pcm, params);

    /* Set the desired hardware parameters. */

    /* Interleaved mode */
    snd_pcm_hw_params_set_access(alsa_dev->snd_pcm, params, 
                                 SND_PCM_ACCESS_RW_INTERLEAVED);

    /* Signed 16-bit little-endian format */
    snd_pcm_hw_params_set_format(alsa_dev->snd_pcm, params, 
                                 SND_PCM_FORMAT_S16_LE);

    /* Two channels (stereo) */
    snd_pcm_hw_params_set_channels(alsa_dev->snd_pcm, params, AUDIO_CHANNEL_NUM);

    /* 44100 bits/second sampling rate (CD quality) */
    val = AUDIO_SAMPLE_RATE;
    snd_pcm_hw_params_set_rate_near(alsa_dev->snd_pcm, params, &val, &dir);

    alsa_dev->frames = 1152;
    snd_pcm_hw_params_set_period_size_near(alsa_dev->snd_pcm, params, 
                                           &alsa_dev->frames, &dir);

    /* Write the parameters to the driver */
    rc = snd_pcm_hw_params(alsa_dev->snd_pcm, params);
    if (rc < 0)
    {
        syslog(LOG_ERR, "Cannot set hw parameters: %s", snd_strerror(rc));
        exit(EXIT_FAILURE);
    }

    /* Use a buffer large enough to hold one period */
    snd_pcm_hw_params_get_period_size(params, &alsa_dev->frames, &dir);

    /* We want to loop for 5 seconds */
    snd_pcm_hw_params_get_period_time(params, &val, &dir);

    snd_pcm_prepare(alsa_dev->snd_pcm);

    snd_pcm_start(alsa_dev->snd_pcm);

    return alsa_dev;
}
示例#20
0
文件: sound.c 项目: azuk/emacs
static void
alsa_configure (struct sound_device *sd)
{
  int val, err, dir;
  unsigned uval;
  struct alsa_params *p = (struct alsa_params *) sd->data;
  snd_pcm_uframes_t buffer_size;

  xassert (p->handle != 0);

  err = snd_pcm_hw_params_malloc (&p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not allocate hardware parameter structure", err);

  err = snd_pcm_sw_params_malloc (&p->swparams);
  if (err < 0)
    alsa_sound_perror ("Could not allocate software parameter structure", err);

  err = snd_pcm_hw_params_any (p->handle, p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not initialize hardware parameter structure", err);

  err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
                                      SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err < 0)
    alsa_sound_perror ("Could not set access type", err);

  val = sd->format;
  err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val);
  if (err < 0)
    alsa_sound_perror ("Could not set sound format", err);

  uval = sd->sample_rate;
  err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &uval, 0);
  if (err < 0)
    alsa_sound_perror ("Could not set sample rate", err);

  val = sd->channels;
  err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val);
  if (err < 0)
    alsa_sound_perror ("Could not set channel count", err);

  err = snd_pcm_hw_params (p->handle, p->hwparams);
  if (err < 0)
    alsa_sound_perror ("Could not set parameters", err);


  err = snd_pcm_hw_params_get_period_size (p->hwparams, &p->period_size, &dir);
  if (err < 0)
    alsa_sound_perror ("Unable to get period size for playback", err);

  err = snd_pcm_hw_params_get_buffer_size (p->hwparams, &buffer_size);
  if (err < 0)
    alsa_sound_perror ("Unable to get buffer size for playback", err);

  err = snd_pcm_sw_params_current (p->handle, p->swparams);
  if (err < 0)
    alsa_sound_perror ("Unable to determine current swparams for playback",
                       err);

  /* Start the transfer when the buffer is almost full */
  err = snd_pcm_sw_params_set_start_threshold (p->handle, p->swparams,
                                               (buffer_size / p->period_size)
                                               * p->period_size);
  if (err < 0)
    alsa_sound_perror ("Unable to set start threshold mode for playback", err);

  /* Allow the transfer when at least period_size samples can be processed */
  err = snd_pcm_sw_params_set_avail_min (p->handle, p->swparams, p->period_size);
  if (err < 0)
    alsa_sound_perror ("Unable to set avail min for playback", err);

  err = snd_pcm_sw_params (p->handle, p->swparams);
  if (err < 0)
    alsa_sound_perror ("Unable to set sw params for playback\n", err);

  snd_pcm_hw_params_free (p->hwparams);
  p->hwparams = NULL;
  snd_pcm_sw_params_free (p->swparams);
  p->swparams = NULL;

  err = snd_pcm_prepare (p->handle);
  if (err < 0)
    alsa_sound_perror ("Could not prepare audio interface for use", err);

  if (sd->volume > 0)
    {
      int chn;
      snd_mixer_t *handle;
      snd_mixer_elem_t *e;
      const char *file = sd->file ? sd->file : DEFAULT_ALSA_SOUND_DEVICE;

      if (snd_mixer_open (&handle, 0) >= 0)
        {
          if (snd_mixer_attach (handle, file) >= 0
              && snd_mixer_load (handle) >= 0
              && snd_mixer_selem_register (handle, NULL, NULL) >= 0)
            for (e = snd_mixer_first_elem (handle);
                 e;
                 e = snd_mixer_elem_next (e))
              {
                if (snd_mixer_selem_has_playback_volume (e))
                  {
                    long pmin, pmax, vol;
                    snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax);
                    vol = pmin + (sd->volume * (pmax - pmin)) / 100;

                    for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++)
                      snd_mixer_selem_set_playback_volume (e, chn, vol);
                  }
              }
          snd_mixer_close (handle);
        }
    }
}
示例#21
0
qint64 QAudioInputPrivate::read(char* data, qint64 len)
{
    // Read in some audio data and write it to QIODevice, pull mode
    if ( !handle )
        return 0;

    int bytesRead = 0;
    int bytesInRingbufferBeforeRead = ringBuffer.bytesOfDataInBuffer();

    if (ringBuffer.bytesOfDataInBuffer() < len) {

        // bytesAvaiable is saved as a side effect of checkBytesReady().
        int bytesToRead = checkBytesReady();

        if (bytesToRead < 0) {
            // bytesAvailable as negative is error code, try to recover from it.
            xrun_recovery(bytesToRead);
            bytesToRead = checkBytesReady();
            if (bytesToRead < 0) {
                // recovery failed must stop and set error.
                close();
                errorState = QAudio::IOError;
                deviceState = QAudio::StoppedState;
                emit stateChanged(deviceState);
                return 0;
            }
        }

        bytesToRead = qMin<qint64>(len, bytesToRead);
        bytesToRead = qMin<qint64>(ringBuffer.freeBytes(), bytesToRead);
        bytesToRead -= bytesToRead % period_size;

        int count=0;
        int err = 0;
        while(count < 5 && bytesToRead > 0) {
            char buffer[bytesToRead];
            int chunks = bytesToRead / period_size;
            int frames = chunks * period_frames;
            if (frames > (int)buffer_frames)
                frames = buffer_frames;

            int readFrames = snd_pcm_readi(handle, buffer, frames);

            if (readFrames >= 0) {
                bytesRead = snd_pcm_frames_to_bytes(handle, readFrames);
                ringBuffer.write(buffer, bytesRead);
#ifdef DEBUG_AUDIO
                qDebug() << QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(bytesRead).arg(readFrames).toLatin1().constData();
#endif
                break;
            } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
                errorState = QAudio::IOError;
                err = 0;
                break;
            } else {
                if(readFrames == -EPIPE) {
                    errorState = QAudio::UnderrunError;
                    err = snd_pcm_prepare(handle);
                } else if(readFrames == -ESTRPIPE) {
                    err = snd_pcm_prepare(handle);
                }
                if(err != 0) break;
            }
            count++;
        }

    }

    bytesRead += bytesInRingbufferBeforeRead;

    if (bytesRead > 0) {
        // got some send it onward
#ifdef DEBUG_AUDIO
        qDebug() << "frames to write to QIODevice = " <<
            snd_pcm_bytes_to_frames( handle, (int)bytesRead ) << " (" << bytesRead << ") bytes";
#endif
        if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
            return 0;

        if (pullMode) {
            qint64 l = 0;
            qint64 bytesWritten = 0;
            while (ringBuffer.bytesOfDataInBuffer() > 0) {
                l = audioSource->write(ringBuffer.availableData(), ringBuffer.availableDataBlockSize());
                if (l > 0) {
                    ringBuffer.readBytes(l);
                    bytesWritten += l;
                } else {
                    break;
                }
            }

            if (l < 0) {
                close();
                errorState = QAudio::IOError;
                deviceState = QAudio::StoppedState;
                emit stateChanged(deviceState);
            } else if (l == 0 && bytesWritten == 0) {
                if (deviceState != QAudio::IdleState) {
                    errorState = QAudio::NoError;
                    deviceState = QAudio::IdleState;
                    emit stateChanged(deviceState);
                }
            } else {
                bytesAvailable -= bytesWritten;
                totalTimeValue += bytesWritten;
                resuming = false;
                if (deviceState != QAudio::ActiveState) {
                    errorState = QAudio::NoError;
                    deviceState = QAudio::ActiveState;
                    emit stateChanged(deviceState);
                }
            }

            return bytesWritten;
        } else {
            while (ringBuffer.bytesOfDataInBuffer() > 0) {
                int size = ringBuffer.availableDataBlockSize();
                memcpy(data, ringBuffer.availableData(), size);
                data += size;
                ringBuffer.readBytes(size);
            }

            bytesAvailable -= bytesRead;
            totalTimeValue += bytesRead;
            resuming = false;
            if (deviceState != QAudio::ActiveState) {
                errorState = QAudio::NoError;
                deviceState = QAudio::ActiveState;
                emit stateChanged(deviceState);
            }

            return bytesRead;
        }
    }

    return 0;
}
示例#22
0
//*******************************************************************************
//*  audio_thread_fxn                                                          **
//*******************************************************************************
//*  Input Parameters:                                                         **
//*      void *envByRef    --  a pointer to an audio_thread_env structure      **
//*                            as defined in audio_thread.h                    **
//*                                                                            **
//*          envByRef.quit -- when quit != 0, thread will cleanup and exit     **
//*                                                                            **
//*  Return Value:                                                             **
//*      void *            --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as **
//*                            defined in audio_thread.h                       **
//*******************************************************************************
void *audio_thread_fxn( void *envByRef )
{

// Variables and definitions
// *************************

    // Thread parameters and return value
    audio_thread_env * envPtr = envByRef;                  // < see above >
    void             * status = AUDIO_THREAD_SUCCESS;      // < see above >
    // The levels of initialization for initMask

    #define     INPUT_ALSA_INITIALIZED      0x1
    #define     INPUT_BUFFER_ALLOCATED      0x2
    #define     OUTPUT_ALSA_INITIALIZED     0x4
    #define     OUTPUT_BUFFER_ALLOCATED     0x8

    unsigned  int   initMask =  0x0;	// Used to only cleanup items that were init'd

    // Input and output driver variables
    //FILE	* inputFile = NULL;		// Input file pointer (i.e. handle)
    snd_pcm_t	*pcm_output_handle;
    snd_pcm_t	*pcm_capture_handle;		// Handle for the PCM device
    snd_pcm_uframes_t exact_bufsize;		// bufsize is in frames.  Each frame is 4 bytes

    int   blksize = BLOCKSIZE;			// Raw input or output frame size in bytes
    char *outputBuffer = NULL;
    char *outputBuffer2 = NULL;			// Output buffer for driver to read from
	char *playingBuffer = NULL;
// Thread Create Phase -- secure and initialize resources
// ******************************************************

    // Setup audio input device
    // ************************
    // Open an ALSA device channel for audio input
    exact_bufsize = blksize/BYTESPERFRAME;

    if( audio_io_setup( &pcm_capture_handle, SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_CAPTURE, &exact_bufsize ) == AUDIO_FAILURE )
    {
        ERR( "Audio_input_setup failed in audio_thread_fxn\n\n" );
        status = AUDIO_THREAD_FAILURE;
        goto cleanup;
    }
    DBG( "exact_bufsize = %d\n", (int) exact_bufsize);

    // Record that input OSS device was opened in initialization bitmask
    initMask |= INPUT_ALSA_INITIALIZED;

    blksize = exact_bufsize*BYTESPERFRAME;

    // Initialize audio output device
    // ******************************
    // Initialize the output ALSA device
    DBG( "pcm_output_handle before audio_output_setup = %d\n", (int) pcm_output_handle);
    exact_bufsize = blksize/BYTESPERFRAME;
    DBG( "Requesting bufsize = %d\n", (int) exact_bufsize);
    if( audio_io_setup( &pcm_output_handle, OUT_SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_PLAYBACK, &exact_bufsize) == AUDIO_FAILURE )
    {
        ERR( "audio_output_setup failed in audio_thread_fxn\n" );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	blksize = exact_bufsize;
	DBG( "pcm_output_handle after audio_output_setup = %d\n", (int) pcm_output_handle);
	DBG( "blksize = %d, exact_bufsize = %d\n", blksize, (int) exact_bufsize);

    // Record that input ALSA device was opened in initialization bitmask
    initMask |= OUTPUT_ALSA_INITIALIZED;

    // Create output buffer to write from into ALSA output device
    if( ( outputBuffer = malloc( blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	// Create 5 seconds of output buffer to circularly update
    if( ( outputBuffer2 = malloc( 500*blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	// This adds the two audio files together for play when enter is pressed
    if( ( playingBuffer = malloc( 500*blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated output audio buffer of size %d to address %p\n", blksize, outputBuffer );

    // Record that the output buffer was allocated in initialization bitmask
    initMask |= OUTPUT_BUFFER_ALLOCATED;


// Thread Execute Phase -- perform I/O and processing
// **************************************************
    // Get things started by sending some silent buffers out.
    int i;

    memset(outputBuffer, 0, blksize);		// Clear the buffer
    memset(outputBuffer2, 0, blksize);		// Clear the buffer
    memset(playingBuffer, 0, blksize);		// Clear the buffer
    for(i=0; i<4; i++) {
	snd_pcm_readi(pcm_capture_handle, outputBuffer, blksize/BYTESPERFRAME);
	if ((snd_pcm_writei(pcm_output_handle, outputBuffer,
		exact_bufsize)) < 0) {
	    snd_pcm_prepare(pcm_output_handle);
	    ERR( "<<<Pre Buffer Underrun >>> \n");
	      }
	}


//
// Processing loop
//
    DBG( "Entering audio_thread_fxn processing loop\n" );

    int count = 0;			//count for the specific audio frame being played
	int count2 = 0;			//count to 500 to keep track of circular loop
	int flag = 0;			//goes high to indicate that 500 frames are captured and ready to be played back
	int playaudiocheck = 1; //goes high to indicate that 500 frames have been played and are ready for capture and play again
    while( !envPtr->quit )
    {

        // Read capture buffer from ALSA input device

        if( snd_pcm_readi(pcm_capture_handle, outputBuffer, blksize/BYTESPERFRAME) < 0 )
        {
	    snd_pcm_prepare(pcm_capture_handle);
        }

        // Write output buffer into ALSA output device
		if(!audiocaller || !flag){
			//If not playing last five seconds of audio or the buffer isn't filled to the 5 second capacity, then we want to continue to play audio regularly
        	if (snd_pcm_writei(pcm_output_handle, outputBuffer, blksize/BYTESPERFRAME) < 0) {
            	snd_pcm_prepare(pcm_output_handle);
	    		// Send out an extra blank buffer if there is an underrun and try again.
	    memset(outputBuffer, 0, blksize);		// Clear the buffer
	    snd_pcm_writei(pcm_output_handle, outputBuffer, exact_bufsize);
      		}
		}

		//Now we want to check to see if the buffer is full and the audio needs to be played back as well as if the audio has finished playing back
		if(audiocaller && (count2 == 499) && playaudiocheck){
		// This will determine that we are playing audio from this point as well we will say not to come back into this loop until the audio has been played and set count2 back to 0 for playing from the beginning
			count2 = 0;
			flag = 1;
			playaudiocheck = 0;
		}

		//Now we will play audio only if the flag says that we have a full buffer
		if(audiocaller && flag){
		//We have to add the signals from what sound is currently happening to the sounds that happened over the last 5 seconds together and then have them playback byter for byte
		for(i=0; i < blksize; i++){
			playingBuffer[i] = outputBuffer2[(count2*blksize)+i] + outputBuffer[i];
		}
		
		//When the audio has been formed it them plays back through the speakers with a snd_pcm_writei call for playingBuffer
		if (snd_pcm_writei(pcm_output_handle, playingBuffer, blksize/BYTESPERFRAME) < 0){ 
		   	snd_pcm_prepare(pcm_output_handle);
		    // Send out an extra blank buffer if there is an underrun and try again.
	        memset(playingBuffer, 0, blksize);		// Clear the buffer
	        snd_pcm_writei(pcm_output_handle, playingBuffer, blksize/BYTESPERFRAME);
        }
		//We now need to detect whether or not the buffer has come to an end and if it has we need to let the program know that we don't want to continue playing both audios together as well as let the buffer know it can be recalled to play again
		if(count2 > 498){
			audiocaller = 0;
			playaudiocheck = 1;
			flag = 0;
		}

}
	//Copies the recorded audio into the new buffer at the specified index
	memcpy(outputBuffer2 + (count2*blksize), outputBuffer, blksize);
	count++;
	count2++;
	count2 = count2 % 500;

	//DBG("%d, ", count++);
    }
    DBG("\n");

    DBG( "Exited audio_thread_fxn processing loop\n" );


// Thread Delete Phase -- free up resources allocated by this file
// ***************************************************************

cleanup:

    DBG( "Starting audio thread cleanup to return resources to system\n" );


    // Close output ALSA device
    if( initMask & OUTPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_output_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_output_cleanup() failed for file descriptor %d\n", (int)pcm_output_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Free allocated buffers
    // **********************

    // Free output buffer
    if( initMask & OUTPUT_BUFFER_ALLOCATED )
    {
        free( outputBuffer );
		free( outputBuffer2 );
		free( playingBuffer );
        DBG( "Freed audio output buffer at location %p\n", outputBuffer );
    }

    // Return from audio_thread_fxn function
    // *************************************
	
    // Return the status at exit of the thread's execution
    DBG( "Audio thread cleanup complete. Exiting audio_thread_fxn\n" );
    return status;
}
bool QAudioOutputPrivate::open()
{
    if(opened)
        return true;

#ifdef DEBUG_AUDIO
    QTime now(QTime::currentTime());
    qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
#endif
    timeStamp.restart();
    elapsedTimeOffset = 0;

    int dir;
    int err=-1;
    int count=0;
    unsigned int freakuency=settings.frequency();

    QString dev = QString(QLatin1String(m_device.constData()));
    QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput);
    if(dev.compare(QLatin1String("default")) == 0) {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(devices.first());
#else
        dev = QLatin1String("hw:0,0");
#endif
    } else {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(m_device);
#else
        int idx = 0;
        char *name;

        QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());

	while(snd_card_get_name(idx,&name) == 0) {
            if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
                break;
            idx++;
	}
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
#endif
    }

    // Step 1: try and open the device
    while((count < 5) && (err < 0)) {
        err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
        if(err < 0)
            count++;
    }
    if (( err < 0)||(handle == 0)) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        return false;
    }
    snd_pcm_nonblock( handle, 0 );

    // Step 2: Set the desired HW parameters.
    snd_pcm_hw_params_alloca( &hwparams );

    bool fatal = false;
    QString errMessage;
    unsigned int chunks = 8;

    err = snd_pcm_hw_params_any( handle, hwparams );
    if ( err < 0 ) {
        fatal = true;
        errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_any: err = %1").arg(err);
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_access( handle, hwparams, access );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_access: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = setFormat();
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_format: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        unsigned int maxBufferTime = 0;
        unsigned int minBufferTime = 0;
        unsigned int maxPeriodTime = 0;
        unsigned int minPeriodTime = 0;

        err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &maxBufferTime, &dir);
        if ( err >= 0)
            err = snd_pcm_hw_params_get_buffer_time_min(hwparams, &minBufferTime, &dir);
        if ( err >= 0)
            err = snd_pcm_hw_params_get_period_time_max(hwparams, &maxPeriodTime, &dir);
        if ( err >= 0)
            err = snd_pcm_hw_params_get_period_time_min(hwparams, &minPeriodTime, &dir);

        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: buffer/period min and max: err = %1").arg(err);
        } else {
            if (maxBufferTime < buffer_time || buffer_time < minBufferTime || maxPeriodTime < period_time || minPeriodTime > period_time) {
#ifdef DEBUG_AUDIO
                qDebug()<<"defaults out of range";
                qDebug()<<"pmin="<<minPeriodTime<<", pmax="<<maxPeriodTime<<", bmin="<<minBufferTime<<", bmax="<<maxBufferTime;
#endif
                period_time = minPeriodTime;
                if (period_time*4 <= maxBufferTime) {
                    // Use 4 periods if possible
                    buffer_time = period_time*4;
                    chunks = 4;
                } else if (period_time*2 <= maxBufferTime) {
                    // Use 2 periods if possible
                    buffer_time = period_time*2;
                    chunks = 2;
                } else {
                    qWarning()<<"QAudioOutput: alsa only supports single period!";
                    fatal = true;
                }
#ifdef DEBUG_AUDIO
                qDebug()<<"used: buffer_time="<<buffer_time<<", period_time="<<period_time;
#endif
            }
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params: err = %1").arg(err);
        }
    }
    if( err < 0) {
        qWarning()<<errMessage;
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        return false;
    }
    snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
    buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
    snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
    period_size = snd_pcm_frames_to_bytes(handle,period_frames);
    snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
    snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);

    // Step 3: Set the desired SW parameters.
    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_alloca(&swparams);
    snd_pcm_sw_params_current(handle, swparams);
    snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
    snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
    snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
    snd_pcm_sw_params(handle, swparams);

    // Step 4: Prepare audio
    if(audioBuffer == 0)
        audioBuffer = new char[snd_pcm_frames_to_bytes(handle,buffer_frames)];
    snd_pcm_prepare( handle );
    snd_pcm_start(handle);

    // Step 5: Setup callback and timer fallback
    snd_async_add_pcm_handler(&ahandler, handle, async_callback, this);
    bytesAvailable = bytesFree();

    // Step 6: Start audio processing
    timer->start(period_time/1000);

    clockStamp.restart();
    timeStamp.restart();
    elapsedTimeOffset = 0;
    errorState  = QAudio::NoError;
    totalTimeValue = 0;
    opened = true;

    return true;
}
示例#24
0
void *Audio_ALSA::open (AudioConfig &cfg, const char *)
{
    AudioConfig tmpCfg;

    if (_audioHandle != NULL)
    {
        _errorString = "ERROR: Device already in use";
        return NULL;
     }

#ifdef HAVE_ALSA_ASOUNDLIB_H
    snd_pcm_uframes_t    buffer_frames;
    snd_pcm_hw_params_t *hw_params = 0;

    if (snd_pcm_open (&_audioHandle, "default", SND_PCM_STREAM_PLAYBACK, 0))
    {
        _errorString = "ERROR: Could not open audio device.";
        goto open_error;
    }

    // May later be replaced with driver defaults.
    tmpCfg = cfg;

    if (snd_pcm_hw_params_malloc (&hw_params))
    {
        _errorString = "ERROR: could not malloc hwparams.";
        goto open_error;
    }

    if (snd_pcm_hw_params_any (_audioHandle, hw_params))
    {
        _errorString = "ERROR: could not initialize hw params";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_access (_audioHandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED))
    {
        _errorString = "ERROR: could not set access type";
        goto open_error;
    }

    snd_pcm_format_t alsamode;
    switch (tmpCfg.precision)
    {
    case 8:
        tmpCfg.encoding = AUDIO_UNSIGNED_PCM;
        alsamode = SND_PCM_FORMAT_U8;
        break;
    case 16:
        tmpCfg.encoding = AUDIO_SIGNED_PCM;
        alsamode = SND_PCM_FORMAT_S16;
        break;
    default:
        _errorString = "ERROR: set desired number of bits for audio device.";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_format (_audioHandle, hw_params, alsamode))
    {
        _errorString = "ERROR: could not set sample format";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_channels (_audioHandle, hw_params, tmpCfg.channels))
    {
        _errorString = "ERROR: could not set channel count";
        goto open_error;
    }

    {   // Gentoo bug #98769, comment 4
        unsigned int rate = tmpCfg.frequency;
        if (snd_pcm_hw_params_set_rate_near (_audioHandle, hw_params, &rate, 0))
        {
            _errorString = "ERROR: could not set sample rate";
            goto open_error;
        }
    }

    _alsa_to_frames_divisor = tmpCfg.channels * tmpCfg.precision / 8;
    buffer_frames = 4096;
    snd_pcm_hw_params_set_period_size_near(_audioHandle, hw_params, &buffer_frames, 0);

    if (snd_pcm_hw_params (_audioHandle, hw_params))
    {
        _errorString = "ERROR: could not set hw parameters";
        goto open_error;
    }

    snd_pcm_hw_params_free (hw_params);
    hw_params = 0;

    if (snd_pcm_prepare (_audioHandle))
    {
        _errorString = "ERROR: could not prepare audio interface for use";
        goto open_error;
    }

    tmpCfg.bufSize = buffer_frames * _alsa_to_frames_divisor;					
#else // HAVE_ALSA_ASOUNDLIB_H
    // Obsolete interface
    int mask, wantedFormat, format;
    int rtn;
    int card = -1, dev = 0;
   
    if ((rtn = snd_pcm_open_preferred (&_audioHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK)))
    {
        _errorString = "ERROR: Could not open audio device.";
        goto open_error;
    }
    
    // Transfer input parameters to this object.
    // May later be replaced with driver defaults.
    tmpCfg = cfg;

    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;
 
    snd_pcm_channel_info_t pi;
   
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_info (_audioHandle, &pi)))
    {
        _errorString = "ALSA: snd_pcm_plugin_info failed.";
        goto open_error;
    }
			
    memset(&pp, 0, sizeof (pp));
	
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_PLAYBACK;
    pp.start_mode = SND_PCM_START_FULL;
    pp.stop_mode = SND_PCM_STOP_STOP;
				     
    pp.buf.block.frag_size = pi.max_fragment_size;

    pp.buf.block.frags_max = 1;
    pp.buf.block.frags_min = 1;
   
    pp.format.interleave = 1;
    pp.format.rate = tmpCfg.frequency;
    pp.format.voices = tmpCfg.channels;
   
    // Set sample precision and type of encoding.
    if ( tmpCfg.precision == 8 )
    {
        tmpCfg.encoding = AUDIO_UNSIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_U8;
    }
    if ( tmpCfg.precision == 16 )
    {
        tmpCfg.encoding = AUDIO_SIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_S16_LE;
    }

    if ((rtn = snd_pcm_plugin_params (_audioHandle, &pp)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_params failed.";
        goto open_error;
    }
   
    if ((rtn = snd_pcm_plugin_prepare (_audioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_prepare failed.";
        goto open_error;
    }
   
    memset (&setup, 0, sizeof (setup));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_setup (_audioHandle, &setup)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_setup failed.";
        goto open_error;
    }

    tmpCfg.bufSize = setup.buf.block.frag_size;
#endif
    
#ifdef HAVE_EXCEPTIONS
    _sampleBuffer = new(std::nothrow) int_least8_t[tmpCfg.bufSize];
#else
    _sampleBuffer = new int_least8_t[tmpCfg.bufSize];
#endif

    if (!_sampleBuffer)
    {
        _errorString = "AUDIO: Unable to allocate memory for sample buffers.";
        goto open_error;
    }

    // Setup internal Config
    _settings = tmpCfg;
    // Update the users settings
    getConfig (cfg);
    return _sampleBuffer;

open_error:
#ifdef HAVE_ALSA_ASOUNDLIB_H
    if (hw_params)
        snd_pcm_hw_params_free (hw_params);
#endif
    if (_audioHandle != NULL)
        close ();
    perror ("ALSA");
    return NULL;
}
示例#25
0
int sndout_alsa_start(int rate_, int stereo)
{
	snd_pcm_hw_params_t *hwparams = NULL;
	unsigned int rate = rate_;
	int samples, shift;
	int ret;

	samples = rate * 40 / 1000;
	for (shift = 8; (1 << shift) < samples; shift++)
		;
	period_size = 1 << shift;
	buffer_size = 8 * period_size;

	snd_pcm_hw_params_alloca(&hwparams);

	ret  = snd_pcm_hw_params_any(handle, hwparams);
	ret |= snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	ret |= snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE);
	ret |= snd_pcm_hw_params_set_channels(handle, hwparams, stereo ? 2 : 1);
	ret |= snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, 0);
	ret |= snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
	ret |= snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, NULL);

	if (ret != 0) {
		fprintf(stderr, PFX "failed to set hwparams\n");
		goto fail;
	}

	ret = snd_pcm_hw_params(handle, hwparams);
	if (ret != 0) {
		fprintf(stderr, PFX "failed to apply hwparams: %d\n", ret);
		goto fail;
	}

	snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
	snd_pcm_hw_params_get_period_size(hwparams, &period_size, NULL);
	snd_pcm_hw_params_get_channels(hwparams, &channels);

	silent_period = realloc(silent_period, period_size * 2 * channels);
	if (silent_period != NULL)
		memset(silent_period, 0, period_size * 2 * channels);

	ret = snd_pcm_prepare(handle);
	if (ret != 0) {
		fprintf(stderr, PFX "snd_pcm_prepare failed: %d\n", ret);
		goto fail;
	}

	ret = snd_pcm_start(handle);
	if (ret != 0) {
		fprintf(stderr, PFX "snd_pcm_start failed: %d\n", ret);
		goto fail;
	}

	failure_counter = 0;

	return 0;

fail:
	// to flush out redirected logs
	fflush(stdout);
	fflush(stderr);
	return -1;
}
static gboolean
alsa_open (void *dp)
{
    alsa_driver * const d = dp;
    gint mf, err, pers;

    if(pcm_open_and_load_hwparams(d) < 0)
	goto out;

    // ---
    // Set non-blocking mode.
    // ---

    d->outtime = 0;

    // --
    // Set channel parameters
    // --
    if((err = snd_pcm_hw_params_set_access(d->soundfd, d->hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0){
	alsa_error(N_("Unable to set access"), err);
	goto out;
    }

    if((err = snd_pcm_hw_params_set_format(d->soundfd, d->hwparams,
				    (d->bits - 8) ? d->signedness16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U16 :
						    d->signedness8 ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8) < 0)) {
	alsa_error(N_("Unable to set audio format"), err);
	goto out;
    }
    /* Handle endianess aspects. TODO! */
    switch(d->bits) {
	case 16:
	    mf = d->signedness16 ? ST_MIXER_FORMAT_S16_LE : ST_MIXER_FORMAT_U16_LE;
	    break;
	case 8:
	default:
	    mf = d->signedness8 ? ST_MIXER_FORMAT_S8 : ST_MIXER_FORMAT_U8;
	    break;
    }

    if((err = snd_pcm_hw_params_set_channels(d->soundfd, d->hwparams, d->stereo + 1)) < 0) {
	alsa_error(N_("Unable to set channels number"), err);
	goto out;
    }
    if((d->stereo)) {
	mf |= ST_MIXER_FORMAT_STEREO;
    }
    d->mf = mf;

    d->p_mixfreq = d->playrate;
    if ((err = snd_pcm_hw_params_set_rate_near(d->soundfd, d->hwparams, &(d->p_mixfreq), NULL)) < 0) {
	alsa_error(N_("Unable to set sample rate"), err);
	goto out;
    }

    if(snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size) < 0) {
	/* Some soundcards report wrong maximal buffer size (maybe alsa bug). So we should try
	   to downscale its value before the reporting an error. The spinbutton still may display
	   the wrong number, but actually the correct value will be implemented.*/
	while((--d->buffer_size) >= 8)
	    if(!snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size))
		break;
	if(d->buffer_size < 8) {
	    error_error(N_("Unable to set appropriate buffer size"));
	    goto out;
	}
    }
    pers = 1 << d->num_periods;
    if ((err = snd_pcm_hw_params_set_periods_near(d->soundfd, d->hwparams, &pers, NULL)) < 0) {
	alsa_error(N_("Unable to set periods number"), err);
	goto out;
    }
    if ((err = snd_pcm_hw_params_get_period_size(d->hwparams, &(d->p_fragsize), NULL)) < 0) {
	alsa_error(N_("Unable to get period size"), err);
	goto out;
    }

    if((err = snd_pcm_hw_params(d->soundfd, d->hwparams))) {
	alsa_error(N_("Error setting hw parameters"), err);
	goto out;
    }

    /* The following piece of code is directly c_n_p'ed from the ALSA pcm example (whith a little adopting) */
    /* get the current swparams */
    err = snd_pcm_sw_params_current(d->soundfd, d->swparams);
    if (err < 0) {
            alsa_error(N_("Unable to determine current swparams for playback"), err);
	    goto out;
    }
    /* start the transfer when the buffer is full */
    err = snd_pcm_sw_params_set_start_threshold(d->soundfd, d->swparams, d->p_fragsize);
    if (err < 0) {
            alsa_error(N_("Unable to set start threshold mode for playback"), err);
	    goto out;
    }
    /* allow the transfer when at least period_size samples can be processed */
    err = snd_pcm_sw_params_set_avail_min(d->soundfd, d->swparams, d->p_fragsize);
    if (err < 0) {
            alsa_error(N_("Unable to set avail min for playback"), err);
	    goto out;
    }
    /* align all transfers to 1 sample */
    err = snd_pcm_sw_params_set_xfer_align(d->soundfd, d->swparams, 1);
    if (err < 0) {
            alsa_error(N_("Unable to set transfer align for playback"), err);
	    goto out;
    }
    /* write the parameters to the playback device */
    err = snd_pcm_sw_params(d->soundfd, d->swparams);
    if (err < 0) {
            alsa_error(N_("Unable to set sw params for playback"), err);
	    goto out;
    }

    err = snd_pcm_prepare(d->soundfd);
    if (err < 0) {
            alsa_error(N_("Unable to prepare playback"), err);
	    goto out;
    }
    // ---
    // Get buffering parameters
    // ---
   
    if(d->verbose)
        snd_pcm_dump(d->soundfd, d->output);
    d->sndbuf = calloc((d->stereo + 1) * (d->bits / 8), d->p_fragsize);

    d->pfd = malloc(sizeof(struct pollfd));
    if ((err = snd_pcm_poll_descriptors(d->soundfd, d->pfd, 1)) < 0) {
        alsa_error(N_("Unable to obtain poll descriptors for playback"), err);
        goto out;
    }

    d->polltag = audio_poll_add(d->pfd->fd, GDK_INPUT_WRITE, alsa_poll_ready_playing, d);

    d->playtime = 0;
    d->firstpoll = TRUE;

    return TRUE;

  out:
    alsa_release(dp);
    return FALSE;
}
示例#27
0
void
alsa_play(void)
{
	struct audio_packet *packet;
	STREAM out;
	int len;
	static long prev_s, prev_us;
	unsigned int duration;
	struct timeval tv;
	int next_tick;

	if (reopened)
	{
		reopened = False;
		gettimeofday(&tv, NULL);
		prev_s = tv.tv_sec;
		prev_us = tv.tv_usec;
	}

	/* We shouldn't be called if the queue is empty, but still */
	if (rdpsnd_queue_empty())
		return;

	packet = rdpsnd_queue_current_packet();
	out = &packet->s;

	next_tick = rdpsnd_queue_next_tick();

	len = (out->end - out->p) / (samplewidth_out * audiochannels_out);
	if ((len = snd_pcm_writei(out_handle, out->p, ((MAX_FRAMES < len) ? MAX_FRAMES : len))) < 0)
	{
		printf("Fooo!\n");
		snd_pcm_prepare(out_handle);
		len = 0;
	}
	out->p += (len * samplewidth_out * audiochannels_out);

	gettimeofday(&tv, NULL);

	duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000;

	if (packet->tick > next_tick)
		next_tick += 65536;

	if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
	{
		snd_pcm_sframes_t delay_frames;
		unsigned long delay_us;

		prev_s = tv.tv_sec;
		prev_us = tv.tv_usec;

		if (abs((next_tick - packet->tick) - duration) > 20)
		{
			DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick));
			DEBUG(("last: %d, is: %d, should: %d\n", packet->tick,
			       (packet->tick + duration) % 65536, next_tick % 65536));
		}

		if (snd_pcm_delay(out_handle, &delay_frames) < 0)
			delay_frames = out->size / (samplewidth_out * audiochannels_out);
		if (delay_frames < 0)
			delay_frames = 0;

		delay_us = delay_frames * (1000000 / rate_out);

		rdpsnd_queue_next(delay_us);
	}
}
示例#28
0
static int
alsa_write_float (snd_pcm_t *alsa_dev, float *data, int frames, int channels)
{	static	int epipe_count = 0 ;

	int total = 0 ;
	int retval ;

	if (epipe_count > 0)
		epipe_count -- ;

	while (total < frames)
	{	retval = snd_pcm_writei (alsa_dev, data + total * channels, frames - total) ;

		if (retval >= 0)
		{	total += retval ;
			if (total == frames)
				return total ;

			continue ;
			} ;

		switch (retval)
		{	case -EAGAIN :
					puts ("alsa_write_float: EAGAIN") ;
					continue ;
					break ;

			case -EPIPE :
					if (epipe_count > 0)
					{	printf ("alsa_write_float: EPIPE %d\n", epipe_count) ;
						if (epipe_count > 140)
							return retval ;
						} ;
					epipe_count += 100 ;

#if 0
					if (0)
					{	snd_pcm_status_t *status ;

						snd_pcm_status_alloca (&status) ;
						if ((retval = snd_pcm_status (alsa_dev, status)) < 0)
							fprintf (stderr, "alsa_out: xrun. can't determine length\n") ;
						else if (snd_pcm_status_get_state (status) == SND_PCM_STATE_XRUN)
						{	struct timeval now, diff, tstamp ;

							gettimeofday (&now, 0) ;
							snd_pcm_status_get_trigger_tstamp (status, &tstamp) ;
							timersub (&now, &tstamp, &diff) ;

							fprintf (stderr, "alsa_write_float xrun: of at least %.3f msecs. resetting stream\n",
									diff.tv_sec * 1000 + diff.tv_usec / 1000.0) ;
							}
						else
							fprintf (stderr, "alsa_write_float: xrun. can't determine length\n") ;
						} ;
#endif

					snd_pcm_prepare (alsa_dev) ;
					break ;

			case -EBADFD :
					fprintf (stderr, "alsa_write_float: Bad PCM state.n") ;
					return 0 ;
					break ;

			case -ESTRPIPE :
					fprintf (stderr, "alsa_write_float: Suspend event.n") ;
					return 0 ;
					break ;

			case -EIO :
					puts ("alsa_write_float: EIO") ;
					return 0 ;

			default :
					fprintf (stderr, "alsa_write_float: retval = %d\n", retval) ;
					return 0 ;
					break ;
			} ; /* switch */
		} ; /* while */

	return total ;
} /* alsa_write_float */
示例#29
0
void *data_streaming(void *socket_desc)
{
  int rc;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  int i;

  /* Open PCM device for recording (capture). */
  rc = snd_pcm_open(&handle, "plughw:1,0",
                    SND_PCM_STREAM_CAPTURE, 0);
  if (rc < 0) {
    fprintf(stderr,
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,
                              SND_PCM_FORMAT_U8);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 1);

  /* 44100 bits/second sampling rate (CD quality) */
  val = 32768;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);

  /* Set period size to 32 frames. */
  frames = SIZE;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params,
                                      &frames, &dir);
 /* 2 bytes/sample, 2 channels */

  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,
                                         &val, &dir);
  
  while (1) {
        pthread_mutex_lock(&mutex);
        rc = snd_pcm_readi(handle, buffer, frames);
        pthread_kill(tid, SIGUSR1);
        pthread_mutex_unlock(&mutex);

    if (rc == -EPIPE) {
      /* EPIPE means overrun */
      fprintf(stderr, "overrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      fprintf(stderr,"error from read: %s\n",snd_strerror(rc));
    } else if (rc != (int)frames) {
      fprintf(stderr, "short read, read %d frames\n", rc);
    }
   }

  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);

    return 0;
}
示例#30
0
qint64 QAudioInputPrivate::read(char* data, qint64 len)
{
    // Read in some audio data and write it to QIODevice, pull mode
    if ( !handle )
        return 0;

    // bytesAvaiable is saved as a side effect of checkBytesReady().
    int bytesToRead = checkBytesReady();

    if (bytesToRead < 0) {
        // bytesAvailable as negative is error code, try to recover from it.
        xrun_recovery(bytesToRead);
        bytesToRead = checkBytesReady();
        if (bytesToRead < 0) {
            // recovery failed must stop and set error.
            close();
            errorState = QAudio::IOError;
            deviceState = QAudio::StoppedState;
            emit stateChanged(deviceState);
            return 0;
        }
    }

    bytesToRead = qMin<qint64>(len, bytesToRead);
    bytesToRead -= bytesToRead % period_size;
    int count=0, err = 0;
    while(count < 5) {
        int chunks = bytesToRead/period_size;
        int frames = chunks*period_frames;
        if(frames > (int)buffer_frames)
            frames = buffer_frames;
        int readFrames = snd_pcm_readi(handle, audioBuffer, frames);
        if (readFrames >= 0) {
            err = snd_pcm_frames_to_bytes(handle, readFrames);
#ifdef DEBUG_AUDIO
            qDebug()<<QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData();
#endif
            break;
        } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
            errorState = QAudio::IOError;
            err = 0;
            break;
        } else {
            if(readFrames == -EPIPE) {
                errorState = QAudio::UnderrunError;
                err = snd_pcm_prepare(handle);
            } else if(readFrames == -ESTRPIPE) {
                err = snd_pcm_prepare(handle);
            }
            if(err != 0) break;
        }
        count++;
    }
    if(err > 0) {
        // got some send it onward
#ifdef DEBUG_AUDIO
        qDebug()<<"frames to write to QIODevice = "<<
            snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<<err<<") bytes";
#endif
        if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
            return 0;
        if (pullMode) {
            qint64 l = audioSource->write(audioBuffer,err);
            if(l < 0) {
                close();
                errorState = QAudio::IOError;
                deviceState = QAudio::StoppedState;
                emit stateChanged(deviceState);
            } else if(l == 0) {
                if (deviceState != QAudio::IdleState) {
                    errorState = QAudio::NoError;
                    deviceState = QAudio::IdleState;
                    emit stateChanged(deviceState);
                }
            } else {
                bytesAvailable -= err;
                totalTimeValue += err;
                resuming = false;
                if (deviceState != QAudio::ActiveState) {
                    errorState = QAudio::NoError;
                    deviceState = QAudio::ActiveState;
                    emit stateChanged(deviceState);
                }
            }
            return l;

        } else {
            memcpy(data,audioBuffer,err);
            bytesAvailable -= err;
            totalTimeValue += err;
            resuming = false;
            if (deviceState != QAudio::ActiveState) {
                errorState = QAudio::NoError;
                deviceState = QAudio::ActiveState;
                emit stateChanged(deviceState);
            }
            return err;
        }
    }
    return 0;
}