bool PokeLaunchApplication::sound() {
#if JUCE_LINUX
  int err;
  int freq = 44100, channels = 2;
  snd_pcm_hw_params_t *hw_params;
  snd_pcm_sw_params_t *sw_params;

  snd_pcm_hw_params_malloc( &hw_params );
  snd_pcm_sw_params_malloc( &sw_params );
  err = snd_pcm_open( &g_alsa_playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0 );
  if( err < 0 )
  {
  	 DBG( "ALSA ERROR: Can't open audio device: " << snd_strerror( err ) );
	   return false;
  }
  DBG("Opened Audio Device");
  err = snd_pcm_hw_params_any( g_alsa_playback_handle, hw_params );
  if( err < 0 )
  {
	    DBG( "ALSA ERROR: Can't initialize hardware parameter structure: " << snd_strerror( err ) );
	    return false;
  }
  err = snd_pcm_hw_params_set_access( g_alsa_playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
  if( err < 0 )
  {
      DBG( "ALSA ERROR: Can't set access type: " << snd_strerror( err ) );
      return false;
  }
  //const UTF8_CHAR *sample_format = "";
  err = snd_pcm_hw_params_set_format( g_alsa_playback_handle, hw_params, SND_PCM_FORMAT_S16_LE );
  if( err < 0 )
  {
	    DBG( "ALSA ERROR: Can't set sample format :" << snd_strerror( err ) );
	    return false;
  }
  err = snd_pcm_hw_params_set_rate_near( g_alsa_playback_handle, hw_params, (unsigned int*)&freq, 0 );
  if( err < 0 )
  {
      DBG( "ALSA ERROR: Can't set sample rate: " << snd_strerror( err ) );
	    return false;
  }
  DBG( "ALSA Sample rate: "<< freq );
  err = snd_pcm_hw_params_set_channels( g_alsa_playback_handle, hw_params, channels );
  if( err < 0 )
  {
	    DBG( "ALSA ERROR: Can't set channel count: " << snd_strerror( err ) );
	    return false;
  }
  snd_pcm_uframes_t frames;
	frames = DEFAULT_BUFFER_SIZE;
  err = snd_pcm_hw_params_set_buffer_size_near( g_alsa_playback_handle, hw_params, &frames );
  if( err < 0 )
  {
	    DBG( "ALSA ERROR: Can't set buffer size: " << snd_strerror( err ) );
	    return false;
  }
  snd_pcm_hw_params_get_buffer_size( hw_params, &frames );
  DBG( "ALSA Buffer size: 4096 samples" );
  err = snd_pcm_hw_params( g_alsa_playback_handle, hw_params );
  if( err < 0 )
  {
	   DBG( "ALSA ERROR: Can't set parameters: " << snd_strerror( err ) );
	    return false;
  }
  snd_pcm_hw_params_free( hw_params );
  snd_pcm_sw_params_free( sw_params );

  err = snd_pcm_prepare( g_alsa_playback_handle );
  if( err < 0 )
  {
	   DBG( "ALSA ERROR: Can't prepare audio interface for use: " << snd_strerror( err ) );
	  return false;
  }

  /* Stop PCM device and drop pending frames */
  snd_pcm_drain(g_alsa_playback_handle);
#endif

  return true;
}
Beispiel #2
0
int 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;
	char *buffer;

	/* 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_S16_LE);

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

	/* 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 = 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 5 seconds */
	snd_pcm_hw_params_get_period_time(params,
			&val, &dir);
	loops = 5000000 / val;

	while (loops > 0) {
		loops--;
		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);
		}
		rc = write(1, buffer, size);
		if (rc != size)
			fprintf(stderr,
					"short write: wrote %d bytes\n", rc);
	}

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

	return 0;
}
Beispiel #3
0
static int pcm_open(struct alsa_pcm *alsa, const char *device_name,
                    snd_pcm_stream_t stream, int rate, int buffer_time)
{
    int r, dir;
    unsigned int p;
    size_t bytes;
    snd_pcm_hw_params_t *hw_params;
    
    r = snd_pcm_open(&alsa->pcm, device_name, stream, SND_PCM_NONBLOCK);
    if (r < 0) {
        alsa_error("open", r);
        return -1;
    }

    snd_pcm_hw_params_alloca(&hw_params);

    r = snd_pcm_hw_params_any(alsa->pcm, hw_params);
    if (r < 0) {
        alsa_error("hw_params_any", r);
        return -1;
    }
    
    r = snd_pcm_hw_params_set_access(alsa->pcm, hw_params,
                                     SND_PCM_ACCESS_RW_INTERLEAVED);
    if (r < 0) {
        alsa_error("hw_params_set_access", r);
        return -1;
    }
    
    r = snd_pcm_hw_params_set_format(alsa->pcm, hw_params, SND_PCM_FORMAT_S16);
    if (r < 0) {
        alsa_error("hw_params_set_format", r);
        fprintf(stderr, "16-bit signed format is not available. "
                "You may need to use a 'plughw' device.\n");
        return -1;
    }

    r = snd_pcm_hw_params_set_rate(alsa->pcm, hw_params, rate, 0);
    if (r < 0) {
        alsa_error("hw_params_set_rate", r);
        fprintf(stderr, "%dHz sample rate not available. You may need to use "
                "a 'plughw' device.\n", rate);
        return -1;
    }
    alsa->rate = rate;

    r = snd_pcm_hw_params_set_channels(alsa->pcm, hw_params, DEVICE_CHANNELS);
    if (r < 0) {
        alsa_error("hw_params_set_channels", r);
        fprintf(stderr, "%d channel audio not available on this device.\n",
                DEVICE_CHANNELS);
        return -1;
    }

    p = buffer_time * 1000; /* microseconds */
    dir = -1;
    r = snd_pcm_hw_params_set_buffer_time_max(alsa->pcm, hw_params, &p, &dir);
    if (r < 0) {
        alsa_error("hw_params_set_buffer_time_max", r);
        fprintf(stderr, "Buffer of %dms may be too small for this hardware.\n",
                buffer_time);
        return -1;
    }

    p = 2; /* double buffering */
    dir = 1;
    r = snd_pcm_hw_params_set_periods_min(alsa->pcm, hw_params, &p, &dir);
    if (r < 0) {
        alsa_error("hw_params_set_periods_min", r);
        fprintf(stderr, "Buffer of %dms may be too small for this hardware.\n",
                buffer_time);
        return -1;
    }

    r = snd_pcm_hw_params(alsa->pcm, hw_params);
    if (r < 0) {
        alsa_error("hw_params", r);
        return -1;
    }
    
    r = snd_pcm_hw_params_get_period_size(hw_params, &alsa->period, &dir);
    if (r < 0) {
        alsa_error("get_period_size", r);
        return -1;
    }

    bytes = alsa->period * DEVICE_CHANNELS * sizeof(signed short);
    alsa->buf = malloc(bytes);
    if (!alsa->buf) {
        perror("malloc");
        return -1;
    }

    /* snd_pcm_readi() returns uninitialised memory on first call,
     * possibly caused by premature POLLIN. Keep valgrind happy. */

    memset(alsa->buf, 0, bytes);

    return 0;
}
Beispiel #4
0
static int pcm_open(pcm_handle_t* pcm, const pcm_desc_t* desc)
{
  const snd_pcm_format_t fmt = SND_PCM_FORMAT_S16_LE;
  snd_pcm_stream_t stm;
  int err;

  if (desc->flags & PCM_FLAG_IN) stm = SND_PCM_STREAM_CAPTURE;
  else stm = SND_PCM_STREAM_PLAYBACK;

  err = snd_pcm_open
    (&pcm->pcm, desc->name, stm, SND_PCM_NONBLOCK);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_0);

  err = snd_pcm_hw_params_malloc(&pcm->hw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_1);

  err = snd_pcm_hw_params_any(pcm->pcm, pcm->hw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  err = snd_pcm_hw_params_set_access
    (pcm->pcm, pcm->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  err = snd_pcm_hw_params_set_format(pcm->pcm, pcm->hw_params, fmt);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  err = snd_pcm_hw_params_set_rate
    (pcm->pcm, pcm->hw_params, desc->fsampl, 0);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  pcm->nchan = desc->nchan;
  pcm->wchan = (size_t)snd_pcm_format_physical_width(fmt) / 8;
  pcm->scale = pcm->nchan * pcm->wchan;

  err = snd_pcm_hw_params_set_channels
    (pcm->pcm, pcm->hw_params, desc->nchan);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);
  
  err = snd_pcm_hw_params(pcm->pcm, pcm->hw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  err = snd_pcm_sw_params_malloc(&pcm->sw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_2);

  err = snd_pcm_sw_params_current(pcm->pcm, pcm->sw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_3);

#if 1
  err = snd_pcm_sw_params_set_avail_min
    (pcm->pcm, pcm->sw_params, 1024);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_3);
#endif

#if 1
  err = snd_pcm_sw_params_set_start_threshold
    (pcm->pcm, pcm->sw_params, 0U);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_3);
#endif

  err = snd_pcm_sw_params(pcm->pcm, pcm->sw_params);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_3);
  
  err = snd_pcm_prepare(pcm->pcm);
  if (err) PERROR_GOTO(snd_strerror(err), on_error_3);

  pcm->rpos = 0;
  pcm->wpos = 0;
  pcm->nsampl = (size_t)desc->fsampl * 10;
  pcm->buf = malloc(pcm->nsampl * pcm->scale);
  if (pcm->buf == NULL) goto on_error_3;

  return 0;

 on_error_3:
  snd_pcm_sw_params_free(pcm->sw_params);
 on_error_2:
  snd_pcm_hw_params_free(pcm->hw_params);
 on_error_1:
  snd_pcm_close(pcm->pcm);
 on_error_0:
  return -1;
  
}
Beispiel #5
0
void SetupSound(void)
{
 snd_pcm_hw_params_t *hwparams;
 snd_pcm_sw_params_t *swparams;
 snd_pcm_status_t *status;
 int pspeed;
 int pchannels;
 int format;
 int buffer_time;
 int period_time;
 int err;

 if(iDisStereo) pchannels=1;
 else pchannels=2;

 pspeed=48000;
 format=SND_PCM_FORMAT_S16_LE;
 buffer_time=500000;
 period_time=buffer_time/4;

 if((err=snd_pcm_open(&handle, "default", 
                      SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))<0)
  {
   printf("Audio open error: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_nonblock(handle, 0))<0)
  {
   printf("Can't set blocking moded: %s\n", snd_strerror(err));
   return;
  }

 snd_pcm_hw_params_alloca(&hwparams);
 snd_pcm_sw_params_alloca(&swparams);
 if((err=snd_pcm_hw_params_any(handle, hwparams))<0)
  {
   printf("Broken configuration for this PCM: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED))<0)
  {
   printf("Access type not available: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_format(handle, hwparams, format))<0)
  {
   printf("Sample format not available: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_channels(handle, hwparams, pchannels))<0)
  {
   printf("Channels count not available: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0))<0)
  {
   printf("Rate not available: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0))<0)
  {
   printf("Buffer time error: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0))<0)
  {
   printf("Period time error: %s\n", snd_strerror(err));
   return;
  }

 if((err=snd_pcm_hw_params(handle, hwparams))<0)
  {
   printf("Unable to install hw params: %s\n", snd_strerror(err));
   return;
  }

 snd_pcm_status_alloca(&status);
 if((err=snd_pcm_status(handle, status))<0)
  {
   printf("Unable to get status: %s\n", snd_strerror(err));
   return;
  }

 buffer_size=snd_pcm_status_get_avail(status);
}
Beispiel #6
0
static int set_params_raw(alsa_param_t *alsa_params)
{
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_sw_params_t *swparams;
    //  snd_pcm_uframes_t buffer_size;
    //  snd_pcm_uframes_t boundary;
    //  unsigned int period_time = 0;
    //  unsigned int buffer_time = 0;
    snd_pcm_uframes_t bufsize;
    int err;
    unsigned int rate;
    snd_pcm_uframes_t start_threshold, stop_threshold;
    snd_pcm_hw_params_alloca(&hwparams);
    snd_pcm_sw_params_alloca(&swparams);

    err = snd_pcm_hw_params_any(alsa_params->handle, hwparams);
    if (err < 0) {
        adec_print("Broken configuration for this PCM: no configurations available");
        return err;
    }

    err = snd_pcm_hw_params_set_access(alsa_params->handle, hwparams,
                                       SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        adec_print("Access type not available");
        return err;
    }

    err = snd_pcm_hw_params_set_format(alsa_params->handle, hwparams, alsa_params->format);
    if (err < 0) {
        adec_print("Sample format non available");
        return err;
    }

    err = snd_pcm_hw_params_set_channels(alsa_params->handle, hwparams, alsa_params->channelcount);
    if (err < 0) {
        adec_print("Channels count non available");
        return err;
    }

    rate = alsa_params->rate;
    err = snd_pcm_hw_params_set_rate_near(alsa_params->handle, hwparams, &alsa_params->rate, 0);
    assert(err >= 0);
#if 0
    err = snd_pcm_hw_params_get_buffer_time_max(hwparams,  &buffer_time, 0);
    assert(err >= 0);
    if (buffer_time > 500000) {
        buffer_time = 500000;
    }

    period_time = buffer_time / 4;

    err = snd_pcm_hw_params_set_period_time_near(handle, hwparams,
            &period_time, 0);
    assert(err >= 0);

    err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams,
            &buffer_time, 0);
    assert(err >= 0);

#endif
    alsa_params->bits_per_sample = snd_pcm_format_physical_width(alsa_params->format);
    //bits_per_frame = bits_per_sample * hwparams.realchanl;
    alsa_params->bits_per_frame = alsa_params->bits_per_sample * alsa_params->channelcount;

    bufsize = 	PERIOD_NUM*PERIOD_SIZE*4;

    err = snd_pcm_hw_params_set_buffer_size_near(alsa_params->handle, hwparams,&bufsize);
    if (err < 0) {
        adec_print("Unable to set  buffer  size \n");
        return err;
    }

    err = snd_pcm_hw_params_set_period_size_near(alsa_params->handle, hwparams, &chunk_size, NULL);
    if (err < 0) {
        adec_print("Unable to set period size \n");
        return err;
    }
#if 0
    err = snd_pcm_hw_params_set_periods_near(alsa_params->handle, hwparams, &fragcount, NULL);
    if (err < 0) {
      adec_print("Unable to set periods \n");
      return err;
    }
#endif
    err = snd_pcm_hw_params(alsa_params->handle, hwparams);
    if (err < 0) {
        adec_print("Unable to install hw params:");
        return err;
    }

    err = snd_pcm_hw_params_get_buffer_size(hwparams, &bufsize);
    if (err < 0) {
        adec_print("Unable to get buffersize \n");
        return err;
    }
    adec_print("[%s::%d]--[alsa raw buffer frame size:%d]\n", __FUNCTION__, __LINE__,bufsize);
    alsa_params->buffer_size = bufsize * alsa_params->bits_per_frame / 8;

#if 1
    err = snd_pcm_sw_params_current(alsa_params->handle, swparams);
    if (err < 0) {
        adec_print("??Unable to get sw-parameters\n");
        return err;
    }

    //err = snd_pcm_sw_params_get_boundary(swparams, &boundary);
    //if (err < 0){
    //  adec_print("Unable to get boundary\n");
    //  return err;
    //}

    //err = snd_pcm_sw_params_set_start_threshold(handle, swparams, bufsize);
    //if (err < 0) {
    //  adec_print("Unable to set start threshold \n");
    //  return err;
    //}

    //err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, buffer_size);
    //if (err < 0) {
    //  adec_print("Unable to set stop threshold \n");
    //  return err;
    //}

    //  err = snd_pcm_sw_params_set_silence_size(handle, swparams, buffer_size);
    //  if (err < 0) {
    //      adec_print("Unable to set silence size \n");
    //      return err;
    //  }

    err = snd_pcm_sw_params(alsa_params->handle, swparams);
    if (err < 0) {
        adec_print("Unable to get sw-parameters\n");
        return err;
    }

    //snd_pcm_sw_params_free(swparams);
#endif


    //chunk_bytes = chunk_size * bits_per_frame / 8;

    return 0;
}
Beispiel #7
0
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const
{
    // Set nearest to closest settings that do work.
    // See if what is in settings will work (return value).
    int err = 0;
    snd_pcm_t* handle;
    snd_pcm_hw_params_t *params;
    QString dev = device;

    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().constData());
#else
        dev = QLatin1String("hw:0,0");
#endif
    } else {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = device;
#else
        int idx = 0;
        char *name;

        QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1);

        while(snd_card_get_name(idx,&name) == 0) {
            if(shortName.compare(QLatin1String(name)) == 0)
                break;
            idx++;
        }
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
#endif
    }
    if(mode == QAudio::AudioOutput) {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
    } else {
        err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
    }
    if(err < 0) {
        handle = 0;
        return false;
    }

    bool testChannel = false;
    bool testCodec = false;
    bool testFreq = false;
    bool testType = false;
    bool testSize = false;

    int  dir = 0;

    snd_pcm_nonblock( handle, 0 );
    snd_pcm_hw_params_alloca( &params );
    snd_pcm_hw_params_any( handle, params );

    // set the values!
    snd_pcm_hw_params_set_channels(handle,params,format.channels());
    snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
    switch(format.sampleSize()) {
        case 8:
            if(format.sampleType() == QAudioFormat::SignedInt)
                snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
            else if(format.sampleType() == QAudioFormat::UnSignedInt)
                snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
            break;
        case 16:
            if(format.sampleType() == QAudioFormat::SignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
            } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
            }
            break;
        case 32:
            if(format.sampleType() == QAudioFormat::SignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
            } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                if(format.byteOrder() == QAudioFormat::LittleEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
                else if(format.byteOrder() == QAudioFormat::BigEndian)
                    snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
            }
    }

    // For now, just accept only audio/pcm codec
    if(!format.codec().startsWith(QLatin1String("audio/pcm"))) {
        err=-1;
    } else
        testCodec = true;

    if(err>=0 && format.channels() != -1) {
        err = snd_pcm_hw_params_test_channels(handle,params,format.channels());
        if(err>=0)
            err = snd_pcm_hw_params_set_channels(handle,params,format.channels());
        if(err>=0)
            testChannel = true;
    }

    if(err>=0 && format.frequency() != -1) {
        err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0);
        if(err>=0)
            err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
        if(err>=0)
            testFreq = true;
    }

    if((err>=0 && format.sampleSize() != -1) &&
            (format.sampleType() != QAudioFormat::Unknown)) {
        switch(format.sampleSize()) {
            case 8:
                if(format.sampleType() == QAudioFormat::SignedInt)
                    err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
                else if(format.sampleType() == QAudioFormat::UnSignedInt)
                    err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
                break;
            case 16:
                if(format.sampleType() == QAudioFormat::SignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
                } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
                }
                break;
            case 32:
                if(format.sampleType() == QAudioFormat::SignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
                } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
                    if(format.byteOrder() == QAudioFormat::LittleEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
                    else if(format.byteOrder() == QAudioFormat::BigEndian)
                        err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
                }
        }
        if(err>=0) {
            testSize = true;
            testType = true;
        }
    }
    if(err>=0)
        err = snd_pcm_hw_params(handle, params);

    if(err == 0) {
        // settings work
        // close()
        if(handle)
            snd_pcm_close(handle);
        return true;
    }
    if(handle)
        snd_pcm_close(handle);

    return false;
}
/**
* @brief Setup the ALSA handle to the audio device
*/
void AlsaPlayback::setupHandle()
{
	if(alsa_handle)
	{
		snd_pcm_close(alsa_handle);
		alsa_handle = NULL;
	}

	if(snd_pcm_open(&alsa_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0)
	{
		TRACE("Unable to open playback device!!\n");
		alsa_handle = NULL;
	}
	else
	{
		int rc = -1;
		snd_pcm_hw_params_t *params = NULL;

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

		if(NULL != params)
		{
			int dir = 0;

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

			/* Set the desired hardware parameters. */
			/* Interleaved mode */
			snd_pcm_hw_params_set_access(alsa_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

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

			/* One channel (mono) */
			snd_pcm_hw_params_set_channels(alsa_handle, params, 1);

			/* set sampling rate */
			snd_pcm_hw_params_set_rate_near(alsa_handle, params, &AlsaPlayback::_sample_rate, &dir);

			/* Set period size to 128 frames (samples) */
			frames = AlsaPlayback::FRAME_PERIOD;
			snd_pcm_hw_params_set_period_size_near(alsa_handle, params, &frames, &dir);

			snd_pcm_uframes_t buf_size = MINIMUM_SAMPLE_SET_SIZE;
			snd_pcm_hw_params_set_buffer_size_near(alsa_handle, params, &buf_size);

			/* Write the parameters to the driver */
			rc = snd_pcm_hw_params(alsa_handle, params);

			if(rc >= 0)
			{
				TRACE("AlsaPlayback init completed successfully..\n");
			}
			else
			{
				snd_pcm_close(alsa_handle);
				alsa_handle = NULL;
				TRACE("AlsaPlayback init failed\n");
			}

			snd_pcm_hw_params_free(params);
			params = NULL;
		}
		else
		{
			TRACE("playAudio - snd_pcm_hw_params_alloc() failed\n");
		}
	}
}
Beispiel #9
0
void create_recorder(int samp_rate,char* dev_name,int nchan,void **capture_handle_f)
{
  int err;
  snd_pcm_t *capture_handle;
  snd_pcm_hw_params_t *hw_params;
  printf("From C: *capture_handle_f=%p\n",*capture_handle_f);
  if ((err = snd_pcm_open ((snd_pcm_t**)capture_handle_f, dev_name,
			   SND_PCM_STREAM_CAPTURE, 0)) < 0) {
    fprintf (stderr, "cannot open audio device %s (%s)\n", 
	     dev_name,
	     snd_strerror (err));
    fprintf(stderr, "Hint: Use \"arecord -l\" to list recording devices.\n");
    exit (1);
  }
  capture_handle = (snd_pcm_t*)(*capture_handle_f);
  printf("made handle %p (&=%p) to %s at %d\n",capture_handle,&capture_handle,dev_name,samp_rate);
     
  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 (capture_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 (capture_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 (capture_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_resample(capture_handle,hw_params, 0)) < 0) {
    fprintf(stderr, "failed attempting to prevent ALSA resampling. (%s)",
	    snd_strerror(err));
    exit (1);
  }
  
  int dir = 0;
  unsigned int val = samp_rate;
  if ((err = snd_pcm_hw_params_set_rate_near (capture_handle,
       hw_params, &val, &dir)) < 0) {
    fprintf (stderr, "cannot set sample rate (%s)\n",
	     snd_strerror (err));
    exit (1);
  }

  if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, nchan)) < 0) {
    fprintf (stderr, "cannot set channel count (%s)\n",
	     snd_strerror (err));
    exit (1);
  }
  
  if ((err = snd_pcm_hw_params (capture_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 (capture_handle)) < 0) {
    fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
	     snd_strerror (err));
    exit (1);
  }

  /*
  int nbuf = 8000;
  short *buf = (short*)malloc(sizeof(short)*nbuf);
  int i;
  
  for (i=0; i<2; ++i) {
    if ((err = snd_pcm_readi(capture_handle, buf, nbuf)) != nbuf) {
      fprintf (stderr, "read from audio interface failed (%s)\n",
	       snd_strerror(err));
      exit (1);
    }
    else {
      printf("read from C using %p into %p.\n",capture_handle,buf);
      }
  }
  */

}
Beispiel #10
0
int main()
{
    long loops;
    int rc,i = 0;
    int size;
    FILE *fp ;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    unsigned int val,val2;
    int dir;
    snd_pcm_uframes_t frames;
    char *buffer;
    if(  (fp =fopen("sound.wav","w")) < 0)
        printf("open sound.wav fial\n");
    /* 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_S16_LE);
    /* Two channels (stereo) */
    snd_pcm_hw_params_set_channels(handle, params, 2);
    /* 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 = 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 */
    printf("size = %d\n",size);
    buffer = (char *) malloc(size);
    /* We want to loop for 5 seconds */
    snd_pcm_hw_params_get_period_time(params,  &val, &dir);
    loops = 10000000 / val;
    while (loops > 0)
    {
        loops--;
        rc = snd_pcm_readi(handle, buffer, frames);
        printf("%d\n",i++);
        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 = fwrite( buffer,1, size,fp);
        rc = write(1,buffer,size);
        if (rc != size)
            fprintf(stderr,  "short write: wrote %d bytes/n", rc);
        else printf("fwrite buffer success\n");
    }
    /******************打印参数*********************/
    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);
//snd_pcm_hw_params_get_tick_time(params,  &val, &dir);
    printf("tick time = %d us\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);
    /*******************************************************************/
    snd_pcm_drain(handle);
    snd_pcm_close(handle);
    fclose(fp);
    free(buffer);
    return 0;

}
Beispiel #11
0
int main(int argc, char *argv[])
{
	ros::init(argc, argv, "cmd_control");
	ros::NodeHandle n;
	ros::Publisher motor_pub = n.advertise<std_msgs::Char>("motor_chatter", 1000);
	std::string port;
	ros::param::param<std::string>("~port", port, "/dev/ttyACM0");
	int baud;
	ros::param::param<int>("~baud", baud, 57600);
	int byte_per_sample = bits_per_sample >> 3;
	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;
	char *speechbuf;

	/* 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_S16_LE);

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

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

	/* Set period size to 32 frames. */
	frames = frames_per_period;
	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 * channels * byte_per_sample; /* 2 bytes/sample, 1 channels */
	speechbuf = (char *) malloc(size);
	//printf("buffer size  %d\n", size);
 
	/* We want to loop for 5 seconds */
	snd_pcm_hw_params_get_period_time(params,
			&val, &dir);
	
	int client_sockfd;  
	struct sockaddr_in remote_addr; //服务器端网络地址结构体  
	memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零  
	remote_addr.sin_family=AF_INET; //设置为IP通信  
	remote_addr.sin_addr.s_addr=inet_addr("10.0.1.0");//服务器IP地址  
	remote_addr.sin_port=htons(port); //服务器端口号  

	/*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/  
	if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)  
	{  
		perror("socket failed\n");  
		return 1;  
	}  

	/*将套接字绑定到服务器的网络地址上*/  
	if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)  
	{  
		perror("connect failed\n");  
		return 1;  
	}  
	printf("connected to server\n");  
	int len = 10 * FRAME_LEN;
	
	//printf("pcm size is %d", pcm_size);
	int totallen = 0;

	totallen = 0;
	int sendlen =0;
	int pcm_count = 0;
	int num = 0;

	pthread_t thread_recv;
	int err;
	void *tret;
	if((err = pthread_create(&thread_recv, NULL, &recv_cmd_func, &client_sockfd)) != 0)
	{
		printf("thread recv erro : %s \n", strerror(err));
		return -1;
	}
	sleep(1);
	
	//printf("thread creat is\n" );
    //fflush(stdout);
	while(1)
	{
		rc = snd_pcm_readi(handle, speechbuf, 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);
			break;
		}
		sendlen = send(client_sockfd, speechbuf, len, 0);
		if(sendlen < 0)
			printf("send failed \n");

	}
	if((err = pthread_join(thread_recv, &tret)) != 0)
	{
		printf("can not join thread_recv %s!\n", strerror(err));
		exit(-1);
	}
	getchar();
	close(client_sockfd);
	snd_pcm_drain(handle);
	snd_pcm_close(handle);
	free(speechbuf);
	return 0;
}
    /**
     * Create and initialize Alsa audio output device with given parameters.
     *
     * @param Parameters - optional parameters
     * @throws AudioOutputException  if output device cannot be opened
     */
    AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, true, 1, 0) {
        pcm_handle           = NULL;
        stream               = SND_PCM_STREAM_PLAYBACK;
        this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
        this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
        this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
        uint Fragments       = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt();
        String Card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();

        dmsg(2,("Checking if hw parameters supported...\n"));
        if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {
            pcm_name = "hw:" + Card;
        }
        else {
            fprintf(stderr, "Warning: your soundcard doesn't support chosen hardware parameters; ");
            fprintf(stderr, "trying to compensate support lack with plughw...");
            fflush(stdout);
            pcm_name = "plughw:" + Card;
        }
        dmsg(2,("HW check completed.\n"));

        int err;

        snd_pcm_hw_params_alloca(&hwparams);  // Allocate the snd_pcm_hw_params_t structure on the stack.

        /* Open PCM. The last parameter of this function is the mode. */
        /* If this is set to 0, the standard mode is used. Possible   */
        /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC.       */
        /* If SND_PCM_NONBLOCK is used, read / write access to the    */
        /* PCM device will return immediately. If SND_PCM_ASYNC is    */
        /* specified, SIGIO will be emitted whenever a period has     */
        /* been completely processed by the soundcard.                */
        if ((err = snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0)) < 0) {
            throw AudioOutputException(String("Error opening PCM device ") + pcm_name + ": " + snd_strerror(err));
        }

        if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
            throw AudioOutputException(String("Error, cannot initialize hardware parameter structure: ") + snd_strerror(err));
        }

        /* Set access type. This can be either    */
        /* SND_PCM_ACCESS_RW_INTERLEAVED or       */
        /* SND_PCM_ACCESS_RW_NONINTERLEAVED.      */
        if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
            throw AudioOutputException(String("Error snd_pcm_hw_params_set_access: ") + snd_strerror(err));
        }

        /* Set sample format */
        #if WORDS_BIGENDIAN
        if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_BE)) < 0)
        #else // little endian
        if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE)) < 0)
        #endif
        {
            throw AudioOutputException(String("Error setting sample format: ") + snd_strerror(err));
        }

        int dir = 0;

        /* Set sample rate. If the exact rate is not supported */
        /* by the hardware, use nearest possible rate.         */
        #if ALSA_MAJOR > 0
        if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &uiSamplerate, &dir)) < 0)
        #else
        if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, uiSamplerate, &dir)) < 0)
        #endif
        {
            throw AudioOutputException(String("Error setting sample rate: ") + snd_strerror(err));
        }

        if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, uiAlsaChannels)) < 0) {
            throw AudioOutputException(String("Error setting number of channels: ") + snd_strerror(err));
        }

        /* Set number of periods. Periods used to be called fragments. */
        if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, Fragments, dir)) < 0) {
            throw AudioOutputException(String("Error setting number of ") + ToString(Fragments) + " periods: " + snd_strerror(err));
        }

        /* Set buffer size (in frames). The resulting latency is given by */
        /* latency = periodsize * periods / (rate * bytes_per_frame)     */
        if ((err = snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (FragmentSize * Fragments))) < 0) {
            throw AudioOutputException(String("Error setting buffersize: ") + snd_strerror(err));
        }

        /* Apply HW parameter settings to */
        /* PCM device and prepare device  */
        if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
            throw AudioOutputException(String("Error setting HW params: ") + snd_strerror(err));
        }

        if (snd_pcm_sw_params_malloc(&swparams) != 0) {
            throw AudioOutputException(String("Error in snd_pcm_sw_params_malloc: ") + snd_strerror(err));
        }

        if (snd_pcm_sw_params_current(pcm_handle, swparams) != 0) {
            throw AudioOutputException(String("Error in snd_pcm_sw_params_current: ") + snd_strerror(err));
        }

        if (snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams, 0xffffffff) != 0) {
            throw AudioOutputException(String("Error in snd_pcm_sw_params_set_stop_threshold: ") + snd_strerror(err));
        }

        if (snd_pcm_sw_params(pcm_handle, swparams) != 0) {
            throw AudioOutputException(String("Error in snd_pcm_sw_params: ") + snd_strerror(err));
        }

        if ((err = snd_pcm_prepare(pcm_handle)) < 0) {
            throw AudioOutputException(String("Error snd_pcm_prepare: ") + snd_strerror(err));
        }

        // allocate Alsa output buffer
        pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];

        // create audio channels for this audio device to which the sampler engines can write to
        for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize));

	if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
		Play();
	}
    }
Beispiel #13
0
int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access )
{
	int err, dir;

	// choose all parameters
	if( ( err = snd_pcm_hw_params_any( m_handle, m_hwParams ) ) < 0 )
	{
		printf( "Broken configuration for playback: no configurations "
				"available: %s\n", snd_strerror( err ) );
		return err;
	}

	// set the interleaved read/write format
	if( ( err = snd_pcm_hw_params_set_access( m_handle, m_hwParams,
							_access ) ) < 0 )
	{
		printf( "Access type not available for playback: %s\n",
							snd_strerror( err ) );
		return err;
	}

	// set the sample format
	if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams,
						SND_PCM_FORMAT_S16_LE ) ) < 0 )
	{
		if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams,
						SND_PCM_FORMAT_S16_BE ) ) < 0 )
		{
			printf( "Neither little- nor big-endian available for "
					"playback: %s\n", snd_strerror( err ) );
			return err;
		}
		m_convertEndian = isLittleEndian();
	}
	else
	{
		m_convertEndian = !isLittleEndian();
	}

	// set the count of channels
	if( ( err = snd_pcm_hw_params_set_channels( m_handle, m_hwParams,
							_channels ) ) < 0 )
	{
		printf( "Channel count (%i) not available for playbacks: %s\n"
				"(Does your soundcard not support surround?)\n",
					_channels, snd_strerror( err ) );
		return err;
	}

	// set the sample rate
	if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams,
						sampleRate(), 0 ) ) < 0 )
	{
		if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams,
				mixer()->baseSampleRate(), 0 ) ) < 0 )
		{
			printf( "Could not set sample rate: %s\n",
							snd_strerror( err ) );
			return err;
		}
	}

	m_periodSize = mixer()->framesPerPeriod();
	m_bufferSize = m_periodSize * 8;
	dir = 0;
	err = snd_pcm_hw_params_set_period_size_near( m_handle, m_hwParams,
							&m_periodSize, &dir );
	if( err < 0 )
	{
		printf( "Unable to set period size %lu for playback: %s\n",
					m_periodSize, snd_strerror( err ) );
		return err;
	}
	dir = 0;
	err = snd_pcm_hw_params_get_period_size( m_hwParams, &m_periodSize,
									&dir );
	if( err < 0 )
	{
		printf( "Unable to get period size for playback: %s\n",
							snd_strerror( err ) );
	}

	dir = 0;
	err = snd_pcm_hw_params_set_buffer_size_near( m_handle, m_hwParams,
								&m_bufferSize );
	if( err < 0 )
	{
		printf( "Unable to set buffer size %lu for playback: %s\n",
					m_bufferSize, snd_strerror( err ) );
		return ( err );
	}
	err = snd_pcm_hw_params_get_buffer_size( m_hwParams, &m_bufferSize );

	if( 2 * m_periodSize > m_bufferSize )
	{
		printf( "buffer to small, could not use\n" );
		return ( err );
	}


	// write the parameters to device
	err = snd_pcm_hw_params( m_handle, m_hwParams );
	if( err < 0 )
	{
		printf( "Unable to set hw params for playback: %s\n",
							snd_strerror( err ) );
		return ( err );
	}

	return ( 0 );	// all ok
}
Beispiel #14
0
void pcm_init()
{
	int n, m, err;
	snd_pcm_hw_params_t *hw_params;

	if (!sound)
	{
		pcm.hz = 11025;
		pcm.len = 4096;
		pcm.buf = malloc(pcm.len);
		pcm.pos = 0;
		playback_handle = NULL;
		return;
	}

	if (!dsp_device) dsp_device = strdup(DSP_DEVICE);

	if ((err = snd_pcm_open (&playback_handle, dsp_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
		fprintf (stderr, "cannot open audio device %s (%s)\n", 
			 dsp_device,
			 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_U8)) < 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, samplerate, 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, stereo ? 2 : 1)) < 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);
	}

	pcm.stereo = stereo;
	pcm.hz = samplerate;
	pcm.len = 4096;
	pcm.buf = malloc(pcm.len);
}
Beispiel #15
0
static int alsa_set_params(snd_pcm_t *pcm_handle, int rw, int bits, int stereo, int rate)
{
	snd_pcm_hw_params_t *hwparams=NULL;
	snd_pcm_sw_params_t *swparams=NULL;
	int dir;
	uint exact_uvalue;
	unsigned long exact_ulvalue;
	int channels;
	int periods=ALSA_PERIODS;
	int periodsize=ALSA_PERIOD_SIZE;
	int err;
	int format;
	
	/* Allocate the snd_pcm_hw_params_t structure on the stack. */
	snd_pcm_hw_params_alloca(&hwparams);
	
	/* Init hwparams with full configuration space */
	if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
		ms_warning("alsa_set_params: Cannot configure this PCM device.\n");
		return -1;
	}
	
	if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		ms_warning("alsa_set_params: Error setting access.\n");
		return -1;
	}
	/* Set sample format */
	format=SND_PCM_FORMAT_S16;
	if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) < 0) {
		ms_warning("alsa_set_params: Error setting format.\n");
		return -1;
	}
	/* Set number of channels */
	if (stereo) channels=2;
	else channels=1;
	if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels) < 0) {
		ms_warning("alsa_set_params: Error setting channels.\n");
		return -1;
	}
	/* Set sample rate. If the exact rate is not supported */
	/* by the hardware, use nearest possible rate.         */ 
	exact_uvalue=rate;
	dir=0;
	if ((err=snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_uvalue, &dir))<0){
		ms_warning("alsa_set_params: Error setting rate to %i:%s",rate,snd_strerror(err));
		return -1;
	}
	if (dir != 0) {
		ms_warning("alsa_set_params: The rate %d Hz is not supported by your hardware.\n "
		"==> Using %d Hz instead.\n", rate, exact_uvalue);
	}
	/* choose greater period size when rate is high */
	periodsize=periodsize*(rate/8000);	
	
	/* Set buffer size (in frames). The resulting latency is given by */
	/* latency = periodsize * periods / (rate * bytes_per_frame)     */
	/* set period size */
	exact_ulvalue=periodsize;
	dir=0;
	if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &exact_ulvalue, &dir) < 0) {
		ms_warning("alsa_set_params: Error setting period size.\n");
		return -1;
	}
	if (dir != 0) {
		ms_warning("alsa_set_params: The period size %d is not supported by your hardware.\n "
		"==> Using %d instead.\n", periodsize, (int)exact_ulvalue);
	}
	periodsize=exact_ulvalue;
	/* Set number of periods. Periods used to be called fragments. */ 
	exact_uvalue=periods;
	dir=0;
	if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &exact_uvalue, &dir) < 0) {
		ms_warning("alsa_set_params: Error setting periods.\n");
		return -1;
	}
	if (dir != 0) {
		ms_warning("alsa_set_params: The number of periods %d is not supported by your hardware.\n "
		"==> Using %d instead.\n", periods, exact_uvalue);
	}
	/* Apply HW parameter settings to */
	/* PCM device and prepare device  */
	if ((err=snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
		ms_warning("alsa_set_params: Error setting HW params:%s",snd_strerror(err));
		return -1;
	}
	/*prepare sw params */
	if (rw){
		snd_pcm_sw_params_alloca(&swparams);
		snd_pcm_sw_params_current(pcm_handle, swparams);
		if ((err=snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,periodsize*4 ))<0){
			ms_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err));
		}
		if ((err=snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams,periodsize*periods ))<0){
			ms_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err));
		}
		if ((err=snd_pcm_sw_params(pcm_handle, swparams))<0){
			ms_warning("alsa_set_params: Error setting SW params:%s",snd_strerror(err));
			return -1;
		}
	}
	return 0;	
}
Beispiel #16
0
int init_alsa(unsigned int channels, unsigned sample_rate,
				 snd_pcm_format_t format)
{
	int	ret;
	snd_pcm_hw_params_t *hw_params;

	playback_handle = NULL;
	ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK,
			0);
	if (ret < 0) {
		fprintf(stderr, "can NOT open soundcard\n");
		goto fail;
	}

	ret = snd_pcm_hw_params_malloc(&hw_params);
	if (ret < 0) {
		fprintf(stderr, "can NOT allocate hardware paramter structure (%s)\n",
				snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params_any(playback_handle, hw_params);
	if (ret < 0) {
		fprintf(stderr, "can NOT initialize hardware paramter structure (%s)\n",
				snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params_set_access(playback_handle, hw_params,
									   SND_PCM_ACCESS_RW_INTERLEAVED);
	if (ret < 0) {
		fprintf(stderr, "can NOT set access type (%s)\n", snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params_set_format(playback_handle, hw_params, format);
	if (ret < 0) {
		fprintf(stderr, "can NOT set sample format (%s)\n", snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params,
										  &sample_rate, 0);
	if (ret < 0) {
		fprintf(stderr, "can NOT set sample rate (%s)\n", snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params_set_channels(playback_handle, hw_params, channels);
	if (ret < 0) {
		fprintf(stderr, "can NOT set channels (%s)\n", snd_strerror(ret));
		goto fail;
	}

	snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
	buffer_size = buffer_size < ALSA_BUFFER_SIZE_MAX ?
				  buffer_size : ALSA_BUFFER_SIZE_MAX;
	ret = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params,
												 &buffer_size);
	if (ret < 0) {
		fprintf(stderr, "can NOT set alsa buffer size (%s)\n", snd_strerror(ret));
		goto fail;
	}

	snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL);
	if (!period_size)
		period_size = buffer_size / 4;
	ret = snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params,
												 &period_size, NULL);
	if (ret < 0) {
		fprintf(stderr, "can NOT set alsa period size (%s)\n", snd_strerror(ret));
		goto fail;
	}

	ret = snd_pcm_hw_params(playback_handle, hw_params);
	if (ret < 0) {
		fprintf(stderr, "can NOT set parameters (%s)\n", snd_strerror(ret));
		goto fail;
	}
	
	snd_pcm_hw_params_free(hw_params);

	audio_channels = channels;
	audio_sample_rate = sample_rate;
	audio_format = format;

	ret = 0;

	return ret;
fail:
	if (playback_handle) {
		snd_pcm_close(playback_handle);
		playback_handle = NULL;
	}
	return ret;
}
Beispiel #17
0
static void *alsa_init(const char *device, unsigned rate, unsigned latency)
{
   alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
   if (!alsa)
      return NULL;

   snd_pcm_hw_params_t *params = NULL;
   snd_pcm_sw_params_t *sw_params = NULL;

   unsigned latency_usec = latency * 1000;
   unsigned channels = 2;
   unsigned periods = 4;
   snd_pcm_format_t format;

   const char *alsa_dev = "default";
   if (device)
      alsa_dev = device;

   snd_pcm_uframes_t buffer_size;

   TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
   TRY_ALSA(snd_pcm_hw_params_malloc(&params));
   alsa->has_float = find_float_format(alsa->pcm, params);
   format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;

   TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
   TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
   TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
   TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
   TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));

   TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL));
   TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL));

   TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));

   snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL);
   RARCH_LOG("ALSA: Period size: %d frames\n", (int)buffer_size);
   snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
   RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);
   alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
   alsa->can_pause = snd_pcm_hw_params_can_pause(params);
   RARCH_LOG("ALSA: Can pause: %s.\n", alsa->can_pause ? "yes" : "no");

   TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
   TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
   TRY_ALSA(snd_pcm_sw_params_set_start_threshold(alsa->pcm, sw_params, buffer_size / 2));
   TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));

   snd_pcm_hw_params_free(params);
   snd_pcm_sw_params_free(sw_params);

   return alsa;

error:
   RARCH_ERR("ALSA: Failed to initialize...\n");
   if (params)
      snd_pcm_hw_params_free(params);

   if (sw_params)
      snd_pcm_sw_params_free(sw_params);

   if (alsa)
   {
      if (alsa->pcm)
         snd_pcm_close(alsa->pcm);

      free(alsa);
   }
   return NULL;
}
Beispiel #18
0
bool AlsaSound::AlsaInit()
{
	unsigned int sample_rate = m_mixer->GetSampleRate();
	int err;
	int dir;
	snd_pcm_sw_params_t *swparams;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_uframes_t buffer_size,buffer_size_max;
	unsigned int periods;

	err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Audio open error: %s\n", snd_strerror(err));
		return false;
	}

	snd_pcm_hw_params_alloca(&hwparams);

	err = snd_pcm_hw_params_any(handle, hwparams);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Broken configuration for this PCM: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Access type not available: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err));
		return false;
	}

	dir = 0;
	err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &sample_rate, &dir);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Rate not available: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params_set_channels(handle, hwparams, 2);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Channels count not available: %s\n", snd_strerror(err));
		return false;
	}

	periods = BUFFER_SIZE_MAX / FRAME_COUNT_MIN;
	err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &periods, &dir);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Cannot set Minimum periods: %s\n", snd_strerror(err));
		return false;
	}

	buffer_size_max = BUFFER_SIZE_MAX;
	err = snd_pcm_hw_params_set_buffer_size_max(handle, hwparams, &buffer_size_max);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Cannot set minimum buffer size: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params(handle, hwparams);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Unable to install hw params: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Cannot get buffer size: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_hw_params_get_periods_max(hwparams, &periods, &dir);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Cannot get periods: %s\n", snd_strerror(err));
		return false;
	}

	//periods is the number of fragments alsa can wait for during one
	//buffer_size
	frames_to_deliver = buffer_size / periods;
	//limit the minimum size. pulseaudio advertises a minimum of 32 samples.
	if (frames_to_deliver < FRAME_COUNT_MIN)
		frames_to_deliver = FRAME_COUNT_MIN;
	//it is probably a bad idea to try to send more than one buffer of data
	if ((unsigned int)frames_to_deliver > buffer_size)
		frames_to_deliver = buffer_size;
	NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d samples per fragments.\n", buffer_size, periods, frames_to_deliver);

	snd_pcm_sw_params_alloca(&swparams);

	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "cannot init sw params: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "cannot set start thresh: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_sw_params(handle, swparams);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "cannot set sw params: %s\n", snd_strerror(err));
		return false;
	}

	err = snd_pcm_prepare(handle);
	if (err < 0)
	{
		ERROR_LOG(AUDIO, "Unable to prepare: %s\n", snd_strerror(err));
		return false;
	}
	NOTICE_LOG(AUDIO, "ALSA successfully initialized.\n");
	return true;
}
Beispiel #19
0
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
                         unsigned int *sample_rate,
                         int channels, enum CodecID *codec_id)
{
    AlsaData *s = ctx->priv_data;
    const char *audio_device;
    int res, flags = 0;
    snd_pcm_format_t format;
    snd_pcm_t *h;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_uframes_t buffer_size, period_size;
    int64_t layout = ctx->streams[0]->codec->channel_layout;

    if (ctx->filename[0] == 0) audio_device = "default";
    else                       audio_device = ctx->filename;

    if (*codec_id == CODEC_ID_NONE)
        *codec_id = DEFAULT_CODEC_ID;
    format = codec_id_to_pcm_format(*codec_id);
    if (format == SND_PCM_FORMAT_UNKNOWN) {
        av_log(ctx, AV_LOG_ERROR, "sample format 0x%04x is not supported\n", *codec_id);
        return AVERROR(ENOSYS);
    }
    s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * channels;

    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
        flags = SND_PCM_NONBLOCK;
    }
    res = snd_pcm_open(&h, audio_device, mode, flags);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot open audio device %s (%s)\n",
               audio_device, snd_strerror(res));
        return AVERROR(EIO);
    }

    res = snd_pcm_hw_params_malloc(&hw_params);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot allocate hardware parameter structure (%s)\n",
               snd_strerror(res));
        goto fail1;
    }

    res = snd_pcm_hw_params_any(h, hw_params);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot initialize hardware parameter structure (%s)\n",
               snd_strerror(res));
        goto fail;
    }

    res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set access type (%s)\n",
               snd_strerror(res));
        goto fail;
    }

    res = snd_pcm_hw_params_set_format(h, hw_params, format);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set sample format 0x%04x %d (%s)\n",
               *codec_id, format, snd_strerror(res));
        goto fail;
    }

    res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set sample rate (%s)\n",
               snd_strerror(res));
        goto fail;
    }

    res = snd_pcm_hw_params_set_channels(h, hw_params, channels);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set channel count to %d (%s)\n",
               channels, snd_strerror(res));
        goto fail;
    }

    snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
    /* TODO: maybe use ctx->max_picture_buffer somehow */
    res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set ALSA buffer size (%s)\n",
               snd_strerror(res));
        goto fail;
    }

    snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL);
    res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n",
               snd_strerror(res));
        goto fail;
    }
    s->period_size = period_size;

    res = snd_pcm_hw_params(h, hw_params);
    if (res < 0) {
        av_log(ctx, AV_LOG_ERROR, "cannot set parameters (%s)\n",
               snd_strerror(res));
        goto fail;
    }

    snd_pcm_hw_params_free(hw_params);

    if (channels > 2 && layout) {
        if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) {
            char name[128];
            av_get_channel_layout_string(name, sizeof(name), channels, layout);
            av_log(ctx, AV_LOG_WARNING, "ALSA channel layout unknown or unimplemented for %s %s.\n",
                   name, mode == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
        }
        if (s->reorder_func) {
            s->reorder_buf_size = buffer_size;
            s->reorder_buf = av_malloc(s->reorder_buf_size * s->frame_size);
            if (!s->reorder_buf)
                goto fail1;
        }
    }

    s->h = h;
    return 0;

fail:
    snd_pcm_hw_params_free(hw_params);
fail1:
    snd_pcm_close(h);
    return AVERROR(EIO);
}
Beispiel #20
0
static int
set_hwparams (GstAlsaSrc * alsa)
{
  guint rrate;
  gint err;
  snd_pcm_hw_params_t *params;

  snd_pcm_hw_params_malloc (&params);

  /* choose all parameters */
  CHECK (snd_pcm_hw_params_any (alsa->handle, params), no_config);
  /* set the interleaved read/write format */
  CHECK (snd_pcm_hw_params_set_access (alsa->handle, params, alsa->access),
      wrong_access);
  /* set the sample format */
  CHECK (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format),
      no_sample_format);
  /* set the count of channels */
  CHECK (snd_pcm_hw_params_set_channels (alsa->handle, params, alsa->channels),
      no_channels);
  /* set the stream rate */
  rrate = alsa->rate;
  CHECK (snd_pcm_hw_params_set_rate_near (alsa->handle, params, &rrate, NULL),
      no_rate);
  if (rrate != alsa->rate)
    goto rate_match;

#ifndef GST_DISABLE_GST_DEBUG
  /* get and dump some limits */
  {
    guint min, max;

    snd_pcm_hw_params_get_buffer_time_min (params, &min, NULL);
    snd_pcm_hw_params_get_buffer_time_max (params, &max, NULL);

    GST_DEBUG_OBJECT (alsa, "buffer time %u, min %u, max %u",
        alsa->buffer_time, min, max);

    snd_pcm_hw_params_get_period_time_min (params, &min, NULL);
    snd_pcm_hw_params_get_period_time_max (params, &max, NULL);

    GST_DEBUG_OBJECT (alsa, "period time %u, min %u, max %u",
        alsa->period_time, min, max);

    snd_pcm_hw_params_get_periods_min (params, &min, NULL);
    snd_pcm_hw_params_get_periods_max (params, &max, NULL);

    GST_DEBUG_OBJECT (alsa, "periods min %u, max %u", min, max);
  }
#endif

  if (alsa->buffer_time != -1) {
    /* set the buffer time */
    CHECK (snd_pcm_hw_params_set_buffer_time_near (alsa->handle, params,
            &alsa->buffer_time, NULL), buffer_time);
    GST_DEBUG_OBJECT (alsa, "buffer time %u", alsa->buffer_time);
  }
  if (alsa->period_time != -1) {
    /* set the period time */
    CHECK (snd_pcm_hw_params_set_period_time_near (alsa->handle, params,
            &alsa->period_time, NULL), period_time);
    GST_DEBUG_OBJECT (alsa, "period time %u", alsa->period_time);
  }

  /* write the parameters to device */
  CHECK (snd_pcm_hw_params (alsa->handle, params), set_hw_params);

  CHECK (snd_pcm_hw_params_get_buffer_size (params, &alsa->buffer_size),
      buffer_size);

  CHECK (snd_pcm_hw_params_get_period_size (params, &alsa->period_size, NULL),
      period_size);

  snd_pcm_hw_params_free (params);
  return 0;

  /* ERRORS */
no_config:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Broken configuration for recording: no configurations available: %s",
            snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
wrong_access:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Access type not available for recording: %s", snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
no_sample_format:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Sample format not available for recording: %s", snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
no_channels:
  {
    gchar *msg = NULL;

    if ((alsa->channels) == 1)
      msg = g_strdup (_("Could not open device for recording in mono mode."));
    if ((alsa->channels) == 2)
      msg = g_strdup (_("Could not open device for recording in stereo mode."));
    if ((alsa->channels) > 2)
      msg =
          g_strdup_printf (_
          ("Could not open device for recording in %d-channel mode"),
          alsa->channels);
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, ("%s", msg),
        ("%s", snd_strerror (err)));
    g_free (msg);
    snd_pcm_hw_params_free (params);
    return err;
  }
no_rate:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Rate %iHz not available for recording: %s",
            alsa->rate, snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
rate_match:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Rate doesn't match (requested %iHz, get %iHz)", alsa->rate, err));
    snd_pcm_hw_params_free (params);
    return -EINVAL;
  }
buffer_time:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Unable to set buffer time %i for recording: %s",
            alsa->buffer_time, snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
buffer_size:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Unable to get buffer size for recording: %s", snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
period_time:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Unable to set period time %i for recording: %s", alsa->period_time,
            snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
period_size:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Unable to get period size for recording: %s", snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
set_hw_params:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Unable to set hw params for recording: %s", snd_strerror (err)));
    snd_pcm_hw_params_free (params);
    return err;
  }
}
Beispiel #21
0
/*----------------------------------------------------------------
 TIesrFA_ALSA_open

 Try to open an ALSA audio PCM channel.
  ----------------------------------------------------------------*/
TIesrFA_ALSA_Error_t TIesrFA_ALSA_open( TIesrFA_t * const aTIesrFAInstance )
{
    int rtnStatus;
    int openSuccess = 0;
    snd_pcm_uframes_t numSamples;
    snd_pcm_hw_params_t *hw_params = 0;
    snd_pcm_sw_params_t *sw_params = 0;


    TIesrFA_ALSA_t * const ALSAData = (TIesrFA_ALSA_t * const) aTIesrFAInstance->impl_data;

    /* Try to open a handle to the ALSA pcm in blocking mode. */
    rtnStatus = snd_pcm_open( &ALSAData->alsa_handle,
            aTIesrFAInstance->channel_name,
            SND_PCM_STREAM_CAPTURE,
            0 );
    if( rtnStatus < 0 )
        goto openExit;

    /* Set up the information for recording from the audio channelport.  This
     will include data specified by the user, such as data in
     aTIesrFAInstance->encoding, etc.   If setup fails, then the audio channel
     should be shut down and failure reported. */

    /* Setup hardware parameters of the ALSA pcm */
    rtnStatus = snd_pcm_hw_params_malloc( &hw_params );
    if( rtnStatus < 0 )
        goto openExit;

    rtnStatus = snd_pcm_hw_params_any( ALSAData->alsa_handle, hw_params );
    if( rtnStatus < 0 )
        goto openExit;

    /* There will only be a single channel */
    rtnStatus = snd_pcm_hw_params_set_channels( ALSAData->alsa_handle,
            hw_params, 1 );
    if( rtnStatus < 0 )
        goto openExit;

    /* Even though only one channel, must specify type of read. */
    rtnStatus = snd_pcm_hw_params_set_access( ALSAData->alsa_handle,
            hw_params,
            SND_PCM_ACCESS_RW_INTERLEAVED );
    if( rtnStatus < 0 )
        goto openExit;


    /* Format type - only 16 bit linear for now */
    rtnStatus = snd_pcm_hw_params_set_format( ALSAData->alsa_handle,
            hw_params,
            SND_PCM_FORMAT_S16 );
    if( rtnStatus < 0 )
        goto openExit;

    /* Set sample rate, it must be exactly supported */
    rtnStatus = snd_pcm_hw_params_set_rate( ALSAData->alsa_handle,
            hw_params,
            aTIesrFAInstance->sample_rate, 0 );
    if( rtnStatus < 0 )
        goto openExit;


    /* Size of ALSA PCM ring buffer is set to approximately the desired 
     number of multiples of read_samples in the buffer */
    numSamples = aTIesrFAInstance->num_audio_buffer_frames *
            ALSAData->read_samples;
    rtnStatus = snd_pcm_hw_params_set_buffer_size_near( ALSAData->alsa_handle,
            hw_params, &numSamples );
    if( rtnStatus < 0 )
        goto openExit;


    /* Set the hardware parameters in the PCM*/
    rtnStatus = snd_pcm_hw_params( ALSAData->alsa_handle, hw_params );
    if( rtnStatus < 0 )
        goto openExit;



    /* Set software parameters to interrupt at the end of an audio buffer 
     number of samples and to start-up manually */
    rtnStatus = snd_pcm_sw_params_malloc( &sw_params );
    if( rtnStatus < 0 )
        goto openExit;

    rtnStatus = snd_pcm_sw_params_current( ALSAData->alsa_handle, sw_params );
    if( rtnStatus < 0 )
        goto openExit;

    /* Number of samples needed in PCM buffer prior to interrupt */
    rtnStatus = snd_pcm_sw_params_set_avail_min( ALSAData->alsa_handle,
            sw_params, ALSAData->read_samples );
    if( rtnStatus < 0 )
        goto openExit;

    /* Set start threshold so startup is done manually */
    rtnStatus = snd_pcm_sw_params_set_start_threshold( ALSAData->alsa_handle,
            sw_params, ULONG_MAX );
    if( rtnStatus < 0 )
        goto openExit;

    /* Channel opened successfully */
    openSuccess = 1;


openExit:

    if( hw_params != NULL )
        snd_pcm_hw_params_free( hw_params );

    if( sw_params != NULL )
        snd_pcm_sw_params_free( sw_params );


    if( openSuccess )
        return TIesrFA_ALSAErrNone;

    return TIesrFA_ALSAErrFail;
}
Beispiel #22
0
const VisPluginInfo *get_plugin_info (void)
{
	static VisInputPlugin input = {
		.upload = inp_alsa_upload
	};

	static VisPluginInfo info = {
		.type     = VISUAL_PLUGIN_TYPE_INPUT,

		.plugname = "alsa",
		.name     = "alsa",
		.author   = "Vitaly V. Bursov <*****@*****.**>",
		.version  = "0.1",
		.about    = N_("ALSA capture plugin"),
		.help     = N_("Use this plugin to capture PCM data from the ALSA record device"),
		.license  = VISUAL_PLUGIN_LICENSE_LGPL,

		.init    = inp_alsa_init,
		.cleanup = inp_alsa_cleanup,
		.plugin  = &input
	};

	return &info;
}

int inp_alsa_init (VisPluginData *plugin)
{
	snd_pcm_hw_params_t *hwparams = NULL;
	alsaPrivate *priv;
	unsigned int rate = inp_alsa_var_samplerate;
	unsigned int exact_rate;
	unsigned int tmp;
	int dir = 0;
	int err;

#if ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
#endif

	priv = visual_mem_new0 (alsaPrivate, 1);
	visual_plugin_set_private (plugin, priv);

	if ((err = snd_pcm_open(&priv->chandle, inp_alsa_var_cdevice,
			SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
		visual_log(VISUAL_LOG_ERROR,
			    "Record open error: %s", snd_strerror(err));
		return FALSE;
	}

	snd_pcm_hw_params_malloc(&hwparams);
	visual_return_val_if_fail(hwparams != NULL, FALSE);

	if (snd_pcm_hw_params_any(priv->chandle, hwparams) < 0) {
		visual_log(VISUAL_LOG_ERROR,
			   "Cannot configure this PCM device");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	if (snd_pcm_hw_params_set_access(priv->chandle, hwparams,
					 SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		visual_log(VISUAL_LOG_ERROR, "Error setting access");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

#if VISUAL_LITTLE_ENDIAN == 1
	if (snd_pcm_hw_params_set_format(priv->chandle, hwparams,
					 SND_PCM_FORMAT_S16_LE) < 0) {
#else
	if (snd_pcm_hw_params_set_format(priv->chandle, hwparams,
					 SND_PCM_FORMAT_S16_BE) < 0) {
#endif
		visual_log(VISUAL_LOG_ERROR, "Error setting format");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	exact_rate = rate;

	if (snd_pcm_hw_params_set_rate_near(priv->chandle, hwparams,
					    &exact_rate, &dir) < 0) {
		visual_log(VISUAL_LOG_ERROR, "Error setting rate");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}
	if (exact_rate != rate) {
		visual_log(VISUAL_LOG_INFO,
			   "The rate %d Hz is not supported by your " \
			   "hardware.\n" \
			   "==> Using %d Hz instead", rate, exact_rate);
	}

	if (snd_pcm_hw_params_set_channels(priv->chandle, hwparams,
					   inp_alsa_var_channels) < 0) {
		visual_log(VISUAL_LOG_ERROR, "Error setting channels");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	/* Setup a large buffer */

	tmp = 1000000;
	if (snd_pcm_hw_params_set_period_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){
		visual_log(VISUAL_LOG_ERROR, "Error setting period time");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	tmp = 1000000*4;
	if (snd_pcm_hw_params_set_buffer_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){
		visual_log(VISUAL_LOG_ERROR, "Error setting buffer time");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}


	if (snd_pcm_hw_params(priv->chandle, hwparams) < 0) {
		visual_log(VISUAL_LOG_ERROR, "Error setting HW params");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	if (snd_pcm_prepare(priv->chandle) < 0) {
		visual_log(VISUAL_LOG_ERROR, "Failed to prepare interface");
		snd_pcm_hw_params_free(hwparams);
		return FALSE;
	}

	snd_pcm_hw_params_free(hwparams);

	priv->loaded = TRUE;

	return TRUE;
}

void inp_alsa_cleanup (VisPluginData *plugin)
{
	alsaPrivate *priv = visual_plugin_get_private (plugin);

	if (priv->loaded) {
		snd_pcm_close(priv->chandle);
    }

	visual_mem_free (priv);
}
Beispiel #23
0
/* Initialise audio devices. */
int digi_init()
{
	int err, tmp;
	char *device = "plughw:0,0";
	snd_pcm_hw_params_t *params;
 pthread_attr_t attr;
 pthread_mutexattr_t mutexattr;

 //added on 980905 by adb to init sound kill system
 memset(SampleHandles, 255, sizeof(SampleHandles));
 //end edit by adb

 /* Open the ALSA sound device */
	if ((err = snd_pcm_open(&snd_devhandle, device, SND_PCM_STREAM_PLAYBACK)) < 0)
	{
     con_printf(CON_CRITICAL, "open failed: %s\n", snd_strerror( err ));  
     return -1; 
	}

	snd_pcm_hw_params_alloca(&params);
	err = snd_pcm_hw_params_any(snd_devhandle, params);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}
	err = snd_pcm_hw_params_set_access(snd_devhandle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}
	err = snd_pcm_hw_params_set_format(snd_devhandle, params, SND_PCM_FORMAT_U8);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}
	err = snd_pcm_hw_params_set_channels(snd_devhandle, params, 2);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}
	tmp = 11025;
	err = snd_pcm_hw_params_set_rate_near(snd_devhandle, params, &tmp, NULL);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}
	snd_pcm_hw_params_set_periods(snd_devhandle, params, 3, 0);
	snd_pcm_hw_params_set_buffer_size(snd_devhandle,params, (SOUND_BUFFER_SIZE*3)/2);

	err = snd_pcm_hw_params(snd_devhandle, params);
	if (err < 0)
	{
		con_printf(CON_CRITICAL,"ALSA: Error %s\n", snd_strerror(err));
		return -1;
	}

 /* Start the mixer thread */

 /* We really should check the results of these */
 pthread_mutexattr_init(&mutexattr);
 pthread_mutex_init(&mutex,&mutexattr);
 pthread_mutexattr_destroy(&mutexattr);
 
 if (pthread_attr_init(&attr) != 0) {
  con_printf(CON_CRITICAL, "failed to init attr\n");
  snd_pcm_close( snd_devhandle ); 
  return -1;
 }

 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

 pthread_create(&thread_id,&attr,mixer_thread,NULL);
 pthread_attr_destroy(&attr);

 digi_initialised = 1;
 return 0;
}
Beispiel #24
0
int alsa_play_hw(alsa_play_t alsa_play, glc_audio_format_message_t *fmt_msg)
{
	snd_pcm_hw_params_t *hw_params = NULL;
	snd_pcm_access_t access;
	unsigned int period_time;
	unsigned int buffer_time;
	int dir = 0, ret = 0;

	if (unlikely(fmt_msg->id != alsa_play->id))
		return 0;

	alsa_play->flags    = fmt_msg->flags;
	alsa_play->format   = fmt_msg->format;
	alsa_play->rate     = fmt_msg->rate;
	alsa_play->channels = fmt_msg->channels;

	if (alsa_play->pcm) /* re-open */
		snd_pcm_close(alsa_play->pcm);

	if (alsa_play->flags & GLC_AUDIO_INTERLEAVED)
		access = SND_PCM_ACCESS_RW_INTERLEAVED;
	else
		access = SND_PCM_ACCESS_RW_NONINTERLEAVED;

	if (unlikely((ret = snd_pcm_open(&alsa_play->pcm, alsa_play->device,
				SND_PCM_STREAM_PLAYBACK, 0)) < 0))
		goto err;
	snd_pcm_hw_params_alloca(&hw_params);
	if (unlikely((ret = snd_pcm_hw_params_any(alsa_play->pcm, hw_params)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_set_access(alsa_play->pcm,
						hw_params, access)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_set_format(alsa_play->pcm, hw_params,
						glc_fmt_to_pcm_fmt(alsa_play->format))) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_set_channels(alsa_play->pcm, hw_params,
						  alsa_play->channels)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_set_rate(alsa_play->pcm, hw_params,
					      alsa_play->rate, 0)) < 0))
		goto err;

	if (unlikely((ret = snd_pcm_hw_params_get_buffer_time_max(hw_params,
						&buffer_time, 0))))
		goto err;

	if (buffer_time > 1000000) {
		glc_log(alsa_play->glc, GLC_INFO, "alsa_play",
			"buffer time max is %u usec. We will limit it to 1 sec",
			buffer_time);
		buffer_time = 1000000;
	}

	period_time = buffer_time / 4;
	alsa_play->silence_threshold = period_time*2000;

	if (unlikely((ret = snd_pcm_hw_params_set_period_time_near(alsa_play->pcm,
		hw_params, &period_time, 0)) < 0))
		goto err;

	if (unlikely((ret = snd_pcm_hw_params_set_buffer_time_near(alsa_play->pcm,
		hw_params, &buffer_time, 0)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params(alsa_play->pcm, hw_params)) < 0))
		goto err;

	alsa_play->bufs = (void **) malloc(sizeof(void *) * alsa_play->channels);

	glc_log(alsa_play->glc, GLC_INFO, "alsa_play",
		"opened pcm %s for playback. buffer_time: %u",
		alsa_play->device, buffer_time);

	return 0;
err:
	glc_log(alsa_play->glc, GLC_ERROR, "alsa_play",
		"can't initialize pcm %s: %s (%d)",
		alsa_play->device, snd_strerror(ret), ret);
	return -ret;
}
Beispiel #25
0
bool
AlsaSource::SetupHW ()
{
	bool result = false;
	bool rw_available = false;
	bool mmap_available = false;
#if DEBUG
	bool debug = debug_flags & RUNTIME_DEBUG_AUDIO;
#else
	bool debug = false;
#endif
	
	snd_pcm_hw_params_t *params = NULL;
	snd_output_t *output = NULL;
	guint32 buffer_time = 100000; // request 0.1 seconds of buffer time.
	int err = 0;
	int dir = 0;
	unsigned int rate = GetSampleRate ();
	unsigned int actual_rate = rate;
	guint32 channels = GetChannels ();

	if (debug) {
		err = snd_output_stdio_attach (&output, stdout, 0);
		if (err < 0)
			LOG_AUDIO ("AlsaSource::SetupHW (): Could not create alsa output: %s\n", snd_strerror (err));
	}

	err = snd_pcm_hw_params_malloc (&params);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (malloc): %s\n", snd_strerror (err));
		return false;
	}

	// choose all parameters
	err = snd_pcm_hw_params_any (pcm, params);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (no configurations available): %s\n", snd_strerror (err));
		goto cleanup;
	}
	
	if (debug && output != NULL) {
		LOG_AUDIO ("AlsaSource::SetupHW (): hw configurations:\n");
		snd_pcm_hw_params_dump (params, output);
	}
	
	// enable software resampling
	err = snd_pcm_hw_params_set_rate_resample (pcm, params, 1);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (could not enable resampling): %s\n", snd_strerror (err));
		goto cleanup;
	}
	
	// test for available transfer modes
	if (!(moonlight_flags & RUNTIME_INIT_AUDIO_ALSA_MMAP)) {
		err = snd_pcm_hw_params_test_access (pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED);
		if (err < 0) {
			LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: RW access mode not supported (%s).\n", snd_strerror (err));			
		} else {
			rw_available = true;
		}
	}
	if (!(moonlight_flags & RUNTIME_INIT_AUDIO_ALSA_RW)) {
		err = snd_pcm_hw_params_test_access (pcm, params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
		if (err < 0) {
			LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: MMAP access mode not supported (%s).\n", snd_strerror (err));
		} else {
			mmap_available = true;
		}
	}
	if (mmap_available) {
		mmap = true;
	} else if (rw_available) {
		mmap = false;
	} else {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed, no available access mode\n");
		goto cleanup;
	}

	LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup: using %s access mode.\n", mmap ? "MMAP" : "RW");

	// set transfer mode (mmap or rw in our case)
	err = snd_pcm_hw_params_set_access (pcm, params, mmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED : SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (access type not available for playback): %s\n", snd_strerror (err));
		goto cleanup;
	}

	// set audio format
	switch (GetInputBytesPerSample ()) {
	case 1: // 8 bit audio
		err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S16);
		SetOutputBytesPerSample (2);
		break;
	case 2: // 16 bit audio
		err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S16);
		SetOutputBytesPerSample (2);
		break;
	case 3: // 24 bit audio
		// write as 32 bit audio, this is a lot easier to write to than 24 bit.
		err = snd_pcm_hw_params_set_format (pcm, params, SND_PCM_FORMAT_S32);
		SetOutputBytesPerSample (4);
		break;
	default:
		LOG_AUDIO ("AlsaSource::SetupHW (): Invalid input bytes per sample, expected 1, 2 or 3, got %i\n", GetInputBytesPerSample ());
		goto cleanup;
	}
	
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample format not available for playback): %s\n", snd_strerror (err));
		goto cleanup;
	}
	
	// set channel count
	err = snd_pcm_hw_params_set_channels (pcm, params, channels);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (channels count %i not available for playback): %s\n", channels, snd_strerror (err));
		goto cleanup;
	}
	
	// set sample rate
	err = snd_pcm_hw_params_set_rate_near (pcm, params, &actual_rate, 0);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback): %s\n", rate, snd_strerror (err));
		goto cleanup;
	} else if (actual_rate != rate) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (sample rate %i Hz not available for playback, only got %i Hz).\n", rate, actual_rate);
		goto cleanup;
	}
	
	// set the buffer time
	err = snd_pcm_hw_params_set_buffer_time_near (pcm, params, &buffer_time, &dir);
	if (err < 0) {
		LOG_AUDIO ("AudioNode::SetupHW (): Audio HW setup failed (unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror (err));
		goto cleanup;
	}

	// write the parameters to device
	err = snd_pcm_hw_params (pcm, params);
	if (err < 0) {
		LOG_AUDIO ("AlsaSource::SetupHW (): Audio HW setup failed (unable to set hw params for playback: %s)\n", snd_strerror (err));
		if (debug && output != NULL) {
			LOG_AUDIO ("AlsaSource::SetupHW (): current hw configurations:\n");
			snd_pcm_hw_params_dump (params, output);
		}
		goto cleanup;
	}
	
	if (debug) {
		LOG_AUDIO ("AlsaSource::SetupHW (): hardware pause support: %s\n", snd_pcm_hw_params_can_pause (params) == 0 ? "no" : "yes"); 
		LOG_AUDIO ("AlsaSource::SetupHW (): succeeded\n");
		if (output != NULL) 
			snd_pcm_hw_params_dump (params, output);
	}

	result = true;
	
cleanup:
	snd_pcm_hw_params_free (params);
	
	return result;
}
Beispiel #26
0
static          size_t
alsa_configure(void)
{
  // <init:
  size_t          chunk_bytes,
                  bits_per_sample,
                  bits_per_frame = 0;
  snd_pcm_uframes_t chunk_size,
                  buffer_size = 0;
  snd_pcm_hw_params_t *params;
  unsigned int    rate = DEFAULT_SPEED;
  int             err;
  snd_pcm_hw_params_alloca(&params);
  // >
  // <defaults:

  err = snd_pcm_hw_params_any(AHandle, params);
  if (err < 0) {
    fprintf(stderr,
            "PCM: Broken configuration: no configurations available");
    exit(EXIT_FAILURE);
  }
  // >
  // <Format:

  err = snd_pcm_hw_params_set_format(AHandle, params, DEFAULT_FORMAT);
  if (err < 0) {
    fprintf(stderr, "Sample format non available");
    exit(EXIT_FAILURE);
  }
  // >
  // <Channels:

  err = snd_pcm_hw_params_set_channels(AHandle, params, 1);
  if (err < 0) {
    fprintf(stderr, "Channels count non available");
    exit(EXIT_FAILURE);
  }
  // >
  // <Rate:

  err = snd_pcm_hw_params_set_rate_near(AHandle, params, &rate, 0);
  assert(err >= 0);

  // >
  // <Access Mode:
  err = snd_pcm_hw_params_set_access(AHandle, params,
                                     SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err < 0) {
    fprintf(stderr, "Access type not available");
    exit(EXIT_FAILURE);
  }
  // >
  // < Set things explicitly if DEBUG
#ifdef DEBUG

  // <Compute buffer_time:
  unsigned int    period_time = 0;
  unsigned int    buffer_time = 0;
  snd_pcm_uframes_t period_frames = 0;
  snd_pcm_uframes_t buffer_frames = 0;
  // affected by defined buffer_size (e.g. via asoundrc)
  if (buffer_time == 0 && buffer_frames == 0) {
    err = snd_pcm_hw_params_get_buffer_time(params, &buffer_time, 0);
    assert(err >= 0);
    if (buffer_time > 500000)   // usecs
      buffer_time = 500000;
  }
  // >
  // <Compute period_time:

  if (period_time == 0 && period_frames == 0) {
    if (buffer_time > 0)
      period_time = buffer_time / 4;
    else
      period_frames = buffer_frames / 4;
  }
  if (period_time > 0)
    err =
        snd_pcm_hw_params_set_period_time_near(AHandle,
                                               params, &period_time, 0);
  else
    err =
        snd_pcm_hw_params_set_period_size_near(AHandle,
                                               params, &period_frames, 0);
  assert(err >= 0);
  if (buffer_time > 0) {
    err =
        snd_pcm_hw_params_set_buffer_time_near(AHandle,
                                               params, &buffer_time, 0);
  } else {
    err =
        snd_pcm_hw_params_set_buffer_size_near(AHandle,
                                               params, &buffer_frames);
  }
  assert(err >= 0);

  // >
#endif

  // >
  // <Commit hw params:
  err = snd_pcm_hw_params(AHandle, params);
  if (err < 0) {
    fprintf(stderr, "Unable to install hw params:");
    exit(EXIT_FAILURE);
  }
  // >
  // <finalize chunk_size and buffer_size:

  snd_pcm_hw_params_get_period_size(params, &chunk_size, 0);
  snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
  if (chunk_size == buffer_size) {
    fprintf(stderr,
            "Can't use period equal to buffer size (%lu == %lu)",
            chunk_size, buffer_size);
    exit(EXIT_FAILURE);
  }
  // >
  // < If DEBUG: SW Params Configure transfer:

#ifdef DEBUG
  size_t          n;
  snd_pcm_uframes_t xfer_align;
  snd_pcm_uframes_t start_threshold,
                  stop_threshold;
  int             start_delay = 5;
  int             stop_delay = 0;
  snd_pcm_sw_params_t *swParams;
  snd_pcm_sw_params_alloca(&swParams);
  snd_pcm_sw_params_current(AHandle, swParams);
  err = snd_pcm_sw_params_get_xfer_align(swParams, &xfer_align);
  if (err < 0) {
    fprintf(stderr, "Unable to obtain xfer align\n");
    exit(EXIT_FAILURE);
  }
  // round up to closest transfer boundary
  n = (buffer_size / xfer_align) * xfer_align;
  if (start_delay <= 0) {
    start_threshold =
        (snd_pcm_uframes_t) (n + (double) rate * start_delay / 1000000);
  } else
    start_threshold =
        (snd_pcm_uframes_t) ((double) rate * start_delay / 1000000);
  if (start_threshold < 1)
    start_threshold = 1;
  if (start_threshold > n)
    start_threshold = n;
  err =
      snd_pcm_sw_params_set_start_threshold(AHandle, swParams,
                                            start_threshold);
  assert(err >= 0);
  if (stop_delay <= 0)
    stop_threshold =
        (snd_pcm_uframes_t) (buffer_size +
                             (double) rate * stop_delay / 1000000);
  else
    stop_threshold =
        (snd_pcm_uframes_t) ((double) rate * stop_delay / 1000000);
  err =
      snd_pcm_sw_params_set_stop_threshold(AHandle, swParams,
                                           stop_threshold);
  assert(err >= 0);

  err = snd_pcm_sw_params_set_xfer_align(AHandle, swParams, xfer_align);
  assert(err >= 0);

  if (snd_pcm_sw_params(AHandle, swParams) < 0) {
    fprintf(stderr, "unable to install sw params:");
    exit(EXIT_FAILURE);
  }
#endif

  // >
  bits_per_sample = snd_pcm_format_physical_width(DEFAULT_FORMAT);
  bits_per_frame = bits_per_sample * 1; // mono
  chunk_bytes = chunk_size * bits_per_frame / 8;
  return chunk_bytes;
}
	main (int argc, char *argv[])
	{
		int i;
		int err;
		short buf[128];
		snd_pcm_t *capture_handle;
		snd_pcm_hw_params_t *hw_params;
	
		if ((err = snd_pcm_open (&capture_handle, argv[1], SND_PCM_STREAM_CAPTURE, 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 (capture_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 (capture_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 (capture_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 (capture_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 (capture_handle, hw_params, 2)) < 0) {
			fprintf (stderr, "cannot set channel count (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
	
		if ((err = snd_pcm_hw_params (capture_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 (capture_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_readi (capture_handle, buf, 128)) != 128) {
				fprintf (stderr, "read from audio interface failed (%s)\n",
					 snd_strerror (err));
				exit (1);
			}
		}
	
		snd_pcm_close (capture_handle);
		exit (0);
	}
Beispiel #28
0
static snd_pcm_t *alsa_open(char *dev, int rate, int channels)
{
	snd_pcm_hw_params_t *hwp;
	snd_pcm_sw_params_t *swp;
	snd_pcm_t *h;
	int r;
	int dir;
	snd_pcm_uframes_t period_size_min;
	snd_pcm_uframes_t period_size_max;
	snd_pcm_uframes_t buffer_size_min;
	snd_pcm_uframes_t buffer_size_max;
	snd_pcm_uframes_t period_size;
	snd_pcm_uframes_t buffer_size;

	if ((r = snd_pcm_open(&h, dev, SND_PCM_STREAM_PLAYBACK, 0) < 0))
		return NULL;

	hwp = alloca(snd_pcm_hw_params_sizeof());
	memset(hwp, 0, snd_pcm_hw_params_sizeof());
	snd_pcm_hw_params_any(h, hwp);

	snd_pcm_hw_params_set_access(h, hwp, SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(h, hwp, SND_PCM_FORMAT_S16_LE);
	snd_pcm_hw_params_set_rate(h, hwp, rate, 0);
	snd_pcm_hw_params_set_channels(h, hwp, channels);

	/* Configurue period */

	dir = 0;
	snd_pcm_hw_params_get_period_size_min(hwp, &period_size_min, &dir);
	dir = 0;
	snd_pcm_hw_params_get_period_size_max(hwp, &period_size_max, &dir);

	period_size = 1024;

	dir = 0;
	r = snd_pcm_hw_params_set_period_size_near(h, hwp, &period_size, &dir);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to set period size %lu (%s)\n",
		        period_size, snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	dir = 0;
	r = snd_pcm_hw_params_get_period_size(hwp, &period_size, &dir);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to get period size (%s)\n",
		        snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	/* Configurue buffer size */

	snd_pcm_hw_params_get_buffer_size_min(hwp, &buffer_size_min);
	snd_pcm_hw_params_get_buffer_size_max(hwp, &buffer_size_max);
	buffer_size = period_size * 4;

	dir = 0;
	r = snd_pcm_hw_params_set_buffer_size_near(h, hwp, &buffer_size);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to set buffer size %lu (%s)\n",
		        buffer_size, snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	r = snd_pcm_hw_params_get_buffer_size(hwp, &buffer_size);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to get buffer size (%s)\n",
		        snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	/* write the hw params */
	r = snd_pcm_hw_params(h, hwp);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to configure hardware parameters (%s)\n",
		        snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	/*
	 * Software parameters
	 */

	swp = alloca(snd_pcm_sw_params_sizeof());
	memset(hwp, 0, snd_pcm_sw_params_sizeof());
	snd_pcm_sw_params_current(h, swp);

	r = snd_pcm_sw_params_set_avail_min(h, swp, period_size);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to configure wakeup threshold (%s)\n",
		        snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	snd_pcm_sw_params_set_start_threshold(h, swp, 0);

	if (r < 0) {
		fprintf(stderr, "audio: Unable to configure start threshold (%s)\n",
		        snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	r = snd_pcm_sw_params(h, swp);

	if (r < 0) {
		fprintf(stderr, "audio: Cannot set soft parameters (%s)\n",
		snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	r = snd_pcm_prepare(h);
	if (r < 0) {
		fprintf(stderr, "audio: Cannot prepare audio for playback (%s)\n",
		snd_strerror(r));
		snd_pcm_close(h);
		return NULL;
	}

	return h;
}
Beispiel #29
0
void* play_thread(void *argv)
{
    char *__file_name = argv;
    struct WAVE *_wave;

#ifdef SOLO
    _wave = (struct WAVE*)malloc(sizeof(struct WAVE));
    memset(&_wave, 0, sizeof(struct _wave));
    if(!wave_read_file(argv, &_wave )){
	goto ERR;
    }
#else
    if(!list_count){
	fprintf(stderr,"[PLAY]: Not such wav sound file.\nPlease call \'play_read_filelist(DIR_PATH)\'\n");
	exit(1);
    }
    for(_wave=head;;_wave=_wave->next){
	if(!strcmp(_wave->file_name, __file_name))break;
	if(head->prev == _wave){
	    fprintf(stderr,"[PLAY]: Invalid file_name...\n");
	    return NULL;
	}
    }
#endif
    if(DISP)
	fprintf(stderr,"[PLAY]: Player will be playing \"%s\".\n",__file_name);

    snd_pcm_t *handle;                  // handle for sound_device
    snd_pcm_hw_params_t *params;        // params for sound_device
    int result_func = 0;                // result for function return
    unsigned int sampling_rate = _wave->rate;   // sampling rate
    int dir;    // sub unit direction
    snd_pcm_uframes_t frames = 32;        // size of frame
    unsigned int buffer_size;                   // buffer_size for frame
    int16_t *frameBuffer=NULL;                       // buffer for frame
    unsigned int approximate_period;                     // period[us]

    {// open the pcm device
	// open pcm device
	result_func = snd_pcm_open(
		&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if ( result_func < 0 )
	{
	    fprintf(stderr,
		    "[PLAY]: unable to open pcm device :%s\n",
		    snd_strerror(result_func));
	    goto ERR;
	}
    }

    {// set parameter to device
	// allocate device params
	snd_pcm_hw_params_alloca(&params);
	// get default param
	snd_pcm_hw_params_any(handle, params);
	// set parameter Interleaved mode
	snd_pcm_hw_params_set_access(handle, params,
		SND_PCM_ACCESS_RW_INTERLEAVED);
	// set format parameter : monoral 1ch 16bit LittleEndian
	snd_pcm_hw_params_set_format(handle, params,
		SND_PCM_FORMAT_S16_LE);
	// set output_device parameter stereo 2ch
	snd_pcm_hw_params_set_channels(handle, params, _wave->channel);
	// approximates to a specified sampling rate
	// pcm	PCM handle
	// params	Configuration space
	// val	approximate target rate / returned approximate set rate
	// dir	Sub unit direction 
	snd_pcm_hw_params_set_rate_near(
		handle, params, &sampling_rate, &dir);
	// set parameter size of frame
	snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
	// set parameter to hardware_device
	result_func = snd_pcm_hw_params(handle, params);

	// err check
	if (result_func < 0) {
	    fprintf(stderr, "[PLAY]: unable to set hw parameters: %s\n",
		    snd_strerror(result_func));
	    goto ERR;
	}

	// get bufferSize / frame
	snd_pcm_hw_params_get_period_size(params, &frames, &dir);
	// calculate buffer_size
	buffer_size = frames * 2; /*????????? 48000,monoral ver */
	// allocate buffer
	frameBuffer = (int16_t *)malloc(buffer_size);
	memset(frameBuffer, 0, sizeof(*frameBuffer));

	// get playback period
	// params	Configuration space
	// val	Returned approximate period duration in us
	// dir	Sub unit direction 
	snd_pcm_hw_params_get_period_time(params, &approximate_period, &dir);
    }


    { // playback process
	// playback time
	unsigned int ptime = approximate_period * 2 * 10;

	// playback
	while ( ptime-- )
	{
	    result_func = fread(
		    frameBuffer, sizeof(unsigned char),
		    buffer_size, _wave->fp);

	    // data is ended
	    if ( result_func == 0 )
	    {
		//fprintf(stdout, "[PLAY]: end of input devce\n");
		break;
	    }

	    // buffer_size is not correct
	    if ( result_func != buffer_size )
	    {
		/*
		   fprintf(stderr,
		   "short read: read %d bytes\n", result_func);
		   */
		break;
	    }

	    // playback
	    result_func = snd_pcm_writei(
		    handle, frameBuffer, frames);
	}
    }

    // for unplayed frame,wait sound finish
    snd_pcm_drain(handle);
    if(DISP)
	fprintf(stderr,"[PLAY]: Finished playing %s.\n",__file_name);

ERR :
    { // release
	if ( frameBuffer != NULL ){ free(frameBuffer); }
	if ( handle != NULL ) { snd_pcm_close(handle); }
    }
    return NULL;
}
Beispiel #30
0
int main() {
  int result;
  snd_pcm_t *handle = NULL;
  snd_pcm_hw_params_t *params = NULL;
  snd_pcm_uframes_t frames;
  snd_pcm_access_t access;
  snd_pcm_format_t format;
  unsigned int rate = 44100;
  unsigned int val, val2;
  int dir = 0;
const char           *device = getenv ("ALSA_DEFAULT");
  if (device == NULL) {
    device = "default";
  }
  result = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0);
  if (result < 0) 
    showErrorAndExit(result, "Error: Unable to open PCM device: %s\n");
  result = snd_pcm_hw_params_malloc(&params);
  if (result < 0) 
    showErrorAndExit(result, "Error: No memory for hardware parameters: %s\n");
  result = snd_pcm_hw_params_any(handle, params);
  if (result < 0) 
    showErrorAndExit(result, "Error: Cannot read HW params: %s\n");
  result = snd_pcm_hw_params_set_access(handle, params,
                                        SND_PCM_ACCESS_RW_INTERLEAVED);
  if (result < 0)
    showErrorAndExit(result, "Could not set access method: %s\n");
  result = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not set output format: %s\n");
  result = snd_pcm_hw_params_set_channels(handle, params, 1);
  if (result < 0)
    showErrorAndExit(result, "Error: Cannot set to 1 channel: %s\n");
  result = snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not set rate: %s\n");
  result = snd_pcm_hw_params(handle, params);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not write HW params: %s\n");
  printf("Card Parameters\n");
  printf("%30s: %s\n", "Alsa Library Version", snd_asoundlib_version());
  result = snd_pcm_hw_params_get_access(params, &access);
  if (result < 0) {
    showErrorAndExit(result, "Error: Could not retrieve access mode: %s\n");
  } else {
    printf("%30s: %s\n", "Access Method", snd_pcm_access_name(access));
  }
  result = snd_pcm_hw_params_get_format(params, &format);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve format type: %d\n");
  } else {
    printf("%30s: %s\n", "Format", snd_pcm_format_name(format));
  }
  result = snd_pcm_hw_params_get_channels(params, &val);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve channel count: %s\n");
  } else {
    printf("%30s: %d\n", "Channels", val);
  }
  result = snd_pcm_hw_params_get_rate(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve rate: %s\n");
  } else {
    printf("%30s: %d bps\n", "Rate", val);
  }
  result = snd_pcm_hw_params_get_period_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve period time: %s\n");
  } else {
    printf("%30s: %d us\n", "Period Time", val);
  }
  result = snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve period size: %s\n");
  } else {
    printf("%30s: %d frames\n", "Period Size", (int) frames);
  }
  result = snd_pcm_hw_params_get_buffer_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve buffer time: %s\n");
  } else {
    printf("%30s: %d us\n", "Buffer Time", val);
  }
  result = snd_pcm_hw_params_get_buffer_size(params, &frames);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve buffer size: %s\n");
  } else {
    printf("%30s: %d frames\n", "Buffer Size", (int) frames);
  }
  result = snd_pcm_hw_params_get_periods(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to get buffer periods: %s\n");
  } else {
    printf("%30s: %d frames\n", "Periods per Buffer", val);
  }
  result = snd_pcm_hw_params_get_rate_numden(params, &val, &val2);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to get rate numerator/denominator: %s\n");
  } else {
    printf("%30s: %d/%d bps\n", "Exact Rate", val, val2);
  }
  val = snd_pcm_hw_params_get_sbits(params);
  printf("%30s: %d\n", "Significant Bits", val);
  result = snd_pcm_hw_params_get_tick_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Could not retrieve tick time: %s\n");
  } else {
    printf("%30s: %d\n", "Tick Time", val);
  }
  printf("Card Capabilities\n");
  val = snd_pcm_hw_params_is_batch(params);
  printf("%30s: %s\n", "Batch Transfer", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_block_transfer(params);
  printf("%30s: %s\n", "Block Transfer", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_double(params);
  printf("%30s: %s\n", "Double Buffering", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_half_duplex(params);
  printf("%30s: %s\n", "Half Duplex Only", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_joint_duplex(params);
  printf("%30s: %s\n", "Joint Duplex Capable", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_overrange(params);
  printf("%30s: %s\n", "Support Overrange Detection", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
  printf("%30s: %s\n", "Support Sample-res Mmap", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_pause(params);
  printf("%30s: %s\n", "Can Pause", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_resume(params);
  printf("%30s: %s\n", "Can Resume", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_sync_start(params);
  printf("%30s: %s\n", "Support Sync Start", (val ? "Yes" : "No"));
  result = snd_pcm_close(handle);
  if (result < 0) 
    showErrorAndExit(result, "Error: Could not close PCM device: %s\n");
  return 0;
}