Esempio n. 1
0
void alsa_driver_do_command(unsigned char play_record,
				char *file_to_open,
				unsigned int sample_freq,
				unsigned int volume,
				unsigned char samplingTimeInSec)
{
	unsigned int direction, status, size;
	unsigned long loops;
	char *buffer;
	FILE *id;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *params;
	snd_pcm_uframes_t frames;
	SetAlsaMasterVolume(volume*10);
	frames = 32;
	printf("Opening %s...\n", file_to_open);
	if (play_record == 0)
		id = fopen(file_to_open, "r");
	else
		id = fopen(file_to_open, "w");
	printf("file open\n");
	printf("Opening device driver...\n");
	if (id != 0) {
		if (play_record == 0) {
			status = snd_pcm_open(&handle,
						"default",
						SND_PCM_STREAM_PLAYBACK,
						 0);
		} else if (play_record == 1) {
			status = snd_pcm_open(&handle,
						"default",
						SND_PCM_STREAM_CAPTURE,
						0);
		} else if (play_record != 1 || play_record != 0) {
			printf("ERROR occured while opening device driver.\n");
			return;
		}
		if (status < 0) {
			printf("ERROR occured while opening device driver.\n");
			exit(1);
		}
		printf("Device open\n");
		/* 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);
		/* sample_freq bits/second sampling rate */
		snd_pcm_hw_params_set_rate_near(handle, params,
						&sample_freq, &direction);
		/* Set period size to 32 frames. */
		frames = 32;
		snd_pcm_hw_params_set_period_size_near(handle, params,
							&frames, &direction);
		/* Write the parameters to the driver */
		printf("Setting hardware driver..\n");
		status = snd_pcm_hw_params(handle, params);
		if (status < 0) {
			fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(status));
			exit(1);
		}
		printf("hardware parameters loaded correctly\n");
		/* Use a buffer large enough to hold one period */
		snd_pcm_hw_params_get_period_size(params, &frames, &direction);
		size = frames * 4; /* 2 bytes/sample, 2 channels */
		buffer = (char *) malloc(size);
		/* We want to loop for samplingTimeInSec seconds */
		snd_pcm_hw_params_get_period_time(params,
						&sample_freq, &direction);
		loops  = 1000000 / sample_freq;
		loops *= samplingTimeInSec;
		printf("Hardware ready\n");
		while (loops > 0) {
			loops--;
			if (play_record == 0) {
				status = fread(buffer, size, 1, id);
				if (status == 0) {
					printf("End of file\n");
					break;
				}
				status = snd_pcm_writei(handle, buffer, frames);
				if (status == -EPIPE) {
					printf("overrun occurred\n");
					snd_pcm_prepare(handle);
				} else if (status < 0) {
					printf("Error while writing\n");
				}
			} else {
				status = snd_pcm_readi(handle, buffer, frames);
				if (status == -EPIPE) {
					printf("overrun occurred\n");
					snd_pcm_prepare(handle);
				} else if (status < 0) {
					printf("Error while reading.");
				}
				status = fwrite(buffer, size, 1, id);
			}
		}
		printf("closing device..\n");
		snd_pcm_drain(handle);
		snd_pcm_close(handle);
		printf("Releasing memory..\n");
		free(buffer);
		fclose(id);
	} else {
		printf("Error while accesing file.");
	}
}
Esempio n. 2
0
bool S9xAlsaSoundDriver::open_device()
{
    int err;
    unsigned int periods = 8;
    unsigned int buffer_size = gui_config->sound_buffer_size * 1000;
    snd_pcm_sw_params_t *sw_params;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_uframes_t alsa_buffer_size, alsa_period_size;
    unsigned int min = 0;
    unsigned int max = 0;

    printf("ALSA sound driver initializing...\n");
    printf("    --> (Device: default)...\n");

    err = snd_pcm_open(&pcm,
                       "default",
                       SND_PCM_STREAM_PLAYBACK,
                       SND_PCM_NONBLOCK);

    if (err < 0)
    {
        goto fail;
    }

    printf("    --> (16-bit Stereo, %dhz, %d ms)...\n",
           Settings.SoundPlaybackRate,
           gui_config->sound_buffer_size);

    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(pcm, hw_params);
    snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16);
    snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
    snd_pcm_hw_params_set_channels(pcm, hw_params, 2);

    snd_pcm_hw_params_get_rate_min(hw_params, &min, NULL);
    snd_pcm_hw_params_get_rate_max(hw_params, &max, NULL);
    printf("    --> Available rates: %d to %d\n", min, max);
    if (Settings.SoundPlaybackRate > max && Settings.SoundPlaybackRate < min)
    {
        printf("        Rate %d not available. Using %d instead.\n", Settings.SoundPlaybackRate, max);
        Settings.SoundPlaybackRate = max;
    }
    snd_pcm_hw_params_set_rate_near(pcm, hw_params, &Settings.SoundPlaybackRate, NULL);

    snd_pcm_hw_params_get_buffer_time_min(hw_params, &min, NULL);
    snd_pcm_hw_params_get_buffer_time_max(hw_params, &max, NULL);
    printf("    --> Available buffer sizes: %dms to %dms\n", min / 1000, max / 1000);
    if (buffer_size < min && buffer_size > max)
    {
        printf("        Buffer size %dms not available. Using %d instead.\n", buffer_size / 1000, (min + max) / 2000);
        buffer_size = (min + max) / 2;
    }
    snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_size, NULL);

    snd_pcm_hw_params_get_periods_min(hw_params, &min, NULL);
    snd_pcm_hw_params_get_periods_max(hw_params, &max, NULL);
    printf("    --> Period ranges: %d to %d blocks\n", min, max);
    if (periods > max)
    {
        periods = max;
    }
    snd_pcm_hw_params_set_periods_near(pcm, hw_params, &periods, NULL);

    if ((err = snd_pcm_hw_params(pcm, hw_params)) < 0)
    {
        printf("        Hardware parameter set failed.\n");
        goto close_fail;
    }

    snd_pcm_sw_params_alloca(&sw_params);
    snd_pcm_sw_params_current(pcm, sw_params);
    snd_pcm_get_params(pcm, &alsa_buffer_size, &alsa_period_size);
    /* Don't start until we're [nearly] full */
    snd_pcm_sw_params_set_start_threshold(pcm, sw_params, (alsa_buffer_size / 2));
    err = snd_pcm_sw_params(pcm, sw_params);

    output_buffer_size = snd_pcm_frames_to_bytes(pcm, alsa_buffer_size);

    if (err < 0)
    {
        printf("        Software parameter set failed.\n");
        goto close_fail;
    }

    printf("OK\n");

    S9xSetSamplesAvailableCallback(alsa_samples_available, this);

    return true;

close_fail:
    snd_pcm_drain(pcm);
    snd_pcm_close(pcm);
    pcm = NULL;

fail:
    printf("Failed: %s\n", snd_strerror(err));

    return false;
}
Esempio n. 3
0
snd_pcm_t *open_sound_dev(char *pcm_name,snd_pcm_stream_t type,int rate,int channel,int bit,int* pFrame){
	int err;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *hw_params;

	if ((err = snd_pcm_open (&handle, pcm_name, type, 0)) < 0) {
		return NULL;
	}

	if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
		fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) {
		fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
		fprintf (stderr, "cannot set access type (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	snd_pcm_format_t format=SND_PCM_FORMAT_S16_LE;
	switch(bit/8){
		case 1:format=SND_PCM_FORMAT_U8;
				break ;
		case 3:format=SND_PCM_FORMAT_S24_LE;
				break ;
	}
	if ((err = snd_pcm_hw_params_set_format (handle, hw_params, format)) < 0) {
		fprintf (stderr, "cannot set sample format (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &rate, 0)) < 0) {
		fprintf (stderr, "cannot set sample rate (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, channel)) < 0) {
		fprintf (stderr, "cannot set channel count (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, channel)) < 0) {
		fprintf (stderr, "cannot set channel count (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	snd_pcm_uframes_t buffer_size=rate/1000*channel*bit*8*2.1;
//	snd_pcm_uframes_t buffer_size= 4096*2.1;
	if(type==SND_PCM_STREAM_CAPTURE){
		if ((err = snd_pcm_hw_params_set_buffer_size_near (handle, hw_params, &buffer_size)) < 0) {
			fprintf (stderr, "cannot set buffer size (%s)\n",
				 snd_strerror (err));
			return NULL;
		}
	}

	snd_pcm_uframes_t period_size=rate/1000*channel*bit*4;
//	snd_pcm_uframes_t period_size = 256;
	if(type==SND_PCM_STREAM_CAPTURE){
		if ((err = snd_pcm_hw_params_set_period_size_near (handle, hw_params, &period_size, 0)) < 0) {
			fprintf (stderr, "cannot set period size (%s)\n",
				 snd_strerror (err));
			return NULL;
		}
	}

	if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
		fprintf (stderr, "cannot set parameters (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_get_period_size(hw_params,pFrame,0)) < 0) {
		fprintf (stderr, "cannot get period size (%s)\n",
			 snd_strerror (err));
		return NULL;
	}

	printf("ken debug, buffer_size=%d period_size=%d frames=%d\n",buffer_size,period_size,*pFrame);

	snd_pcm_hw_params_free (hw_params);

	return handle;
}
Esempio n. 4
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;
}
/* setup alsa data format and buffer geometry */
static inline int alsa_set_hwparams(ao_alsa_internal *internal,
		ao_sample_format *format)
{
	snd_pcm_hw_params_t   *params;
	int err;
	unsigned int rate = format->rate;

	/* allocate the hardware parameter structure */
	snd_pcm_hw_params_alloca(&params);

	/* fetch all possible hardware parameters */
	internal->cmd = "snd_pcm_hw_params_any";
	err = snd_pcm_hw_params_any(internal->pcm_handle, params);
	if (err < 0)
		return err;

	/* set the access type */
	internal->cmd = "snd_pcm_hw_params_set_access";
	err = snd_pcm_hw_params_set_access(internal->pcm_handle,
			params, internal->access_mask);
	if (err < 0)
		return err;

	/* set the sample bitformat */
	internal->cmd = "snd_pcm_hw_params_set_format";
	err = snd_pcm_hw_params_set_format(internal->pcm_handle,
			params, internal->bitformat);
	if (err < 0)
		return err;

	/* set the number of channels */
	internal->cmd = "snd_pcm_hw_params_set_channels";
	err = snd_pcm_hw_params_set_channels(internal->pcm_handle,
			params, (unsigned int)format->channels);
	if (err < 0)
		return err;

	/* save the sample size in bytes for posterity */
	internal->sample_size = format->bits * format->channels / 8;

	/* set the sample rate */
	internal->cmd = "snd_pcm_hw_params_set_rate_near";
	err = snd_pcm_hw_params_set_rate_near(internal->pcm_handle,
			params, &rate, 0);
	if (err < 0)
		return err;
	if (rate > 1.05 * format->rate || rate < 0.95 * format->rate) {
		fprintf(stderr, "warning: sample rate %i not supported "
			"by the hardware, using %u\n", format->rate, rate);
	}

	/* set the length of the hardware sample buffer in microseconds */
	internal->cmd = "snd_pcm_hw_params_set_buffer_time_near";
	err = snd_pcm_hw_params_set_buffer_time_near(internal->pcm_handle,
			params, &(internal->buffer_time), 0);
	if (err < 0)
		return err;

	/* calculate a period time of one half sample time */
	if ((internal->period_time == 0) && (rate > 0))
		internal->period_time =
			1000000 * AO_ALSA_SAMPLE_XFER / rate;

	/* set the time per hardware sample transfer */
	internal->cmd = "snd_pcm_hw_params_set_period_time_near";
	err = snd_pcm_hw_params_set_period_time_near(internal->pcm_handle,
			params, &(internal->period_time), 0);
	if (err < 0)
		return err;

	/* commit the params structure to the hardware via ALSA */
	internal->cmd = "snd_pcm_hw_params";
	err = snd_pcm_hw_params(internal->pcm_handle, params);
	if (err < 0)
		return err;

	/* save the period size in frames for posterity */
	internal->cmd = "snd_pcm_hw_get_period_size";
	err = snd_pcm_hw_params_get_period_size(params, 
						&(internal->period_size), 0);
	if (err < 0)
		return err;

	/* save the buffer size in frames for posterity */
	internal->cmd = "snd_pcm_hw_get_period_size";
	err = snd_pcm_hw_params_get_buffer_size(params, 
						&(internal->buffer_size)); 
	if (err < 0)
		return err;

	return 1;
}
Esempio n. 6
0
Error AudioDriverALSA::init() {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;
	samples_out = NULL;

	mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
	speaker_mode = SPEAKER_MODE_STEREO;
	channels = 2;

	int status;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;

#define CHECK_FAIL(m_cond)                                       \
	if (m_cond) {                                                \
		fprintf(stderr, "ALSA ERR: %s\n", snd_strerror(status)); \
		snd_pcm_close(pcm_handle);                               \
		ERR_FAIL_COND_V(m_cond, ERR_CANT_OPEN);                  \
	}

	//todo, add
	//6 chans - "plug:surround51"
	//4 chans - "plug:surround40";

	status = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

	ERR_FAIL_COND_V(status < 0, ERR_CANT_OPEN);

	snd_pcm_hw_params_alloca(&hwparams);

	status = snd_pcm_hw_params_any(pcm_handle, hwparams);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	CHECK_FAIL(status < 0);

	//not interested in anything else
	status = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE);
	CHECK_FAIL(status < 0);

	//todo: support 4 and 6
	status = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &mix_rate, NULL);
	CHECK_FAIL(status < 0);

	int latency = GLOBAL_DEF("audio/output_latency", 25);
	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);

	// set buffer size from project settings
	status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);
	CHECK_FAIL(status < 0);

	// make period size 1/8
	period_size = buffer_size >> 3;
	status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &period_size, NULL);
	CHECK_FAIL(status < 0);

	unsigned int periods = 2;
	status = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &periods, NULL);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params(pcm_handle, hwparams);
	CHECK_FAIL(status < 0);

	//snd_pcm_hw_params_free(&hwparams);

	snd_pcm_sw_params_alloca(&swparams);

	status = snd_pcm_sw_params_current(pcm_handle, swparams);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, period_size);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params(pcm_handle, swparams);
	CHECK_FAIL(status < 0);

	samples_in = memnew_arr(int32_t, period_size * channels);
	samples_out = memnew_arr(int16_t, period_size * channels);

	snd_pcm_nonblock(pcm_handle, 0);

	mutex = Mutex::create();
	thread = Thread::create(AudioDriverALSA::thread_func, this);

	return OK;
};
Esempio n. 7
0
int main() {
  kill_flag = 0;  //not killed yet

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

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

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

  /* Set the desired hardware parameters. */

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

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

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

  /* 44100 bits/second sampling rate (CD quality) */
  unsigned int val = SAMPLE_RATE; //assign value
  int dir; //direction (input/output)
  snd_pcm_hw_params_set_rate_near(speaker_handle, params, &val, &dir); //get closest match
  printf("rate is %d\n",val);

  /* Set period size to the constant frames. */
  size_t frames = PERIOD;
  snd_pcm_hw_params_set_period_size_near(speaker_handle, params, &frames, &dir);

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

  /* Allocate stream buffer and input buffer */
  snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  printf("Actual frames: %d\n",(int)frames);
  frame_size = frames * 4; /* 2 bytes/sample, 2 channels */
  input_buffer = (char*) malloc(frame_size * MAX_BUFFER);  //allocate buffer for network input
  in_buff_start = 0; in_buff_end = 0; //setup the queue
  
  /* create a server socket and thread to handle input */
  pthread_t thread;
  int flags = 0;
  rc = pthread_create(&thread, NULL, reciever_thread, (void*)&flags);
  if (rc){
     printf("ERROR; return code from pthread_create() is %d\n", rc);
     exit(-1);
  }

  char started = 0;  //track when to start reading data
  while(!kill_flag) { //loop until broken
    //rc = read(0, speaker_buffer, size); //read values in from console
    //wait for some buffer before starting, stop if empty
    if((!started && BUFFER_SIZE(in_buff_start,in_buff_end) < (MAX_BUFFER/2)) \
          || BUFFER_EMPTY(in_buff_start, in_buff_end)){
      //printf("Skipped (%d,%d)\n",BUFFER_SIZE(in_buff_start,in_buff_end),BUFFER_EMPTY(in_buff_start,in_buff_end));
      //if(started) printf("stopping\n");
      started = 0;
      continue; 
    }
    else {
      //if(!started) printf("starting\n");
      started = 1; //indicate that we've startd
    }
    
    //write data to speaker buffer, check responses
    rc = snd_pcm_writei(speaker_handle, input_buffer+(frame_size*in_buff_start), frames);
    //printf("wrote data to speakers\n");
    in_buff_start = (in_buff_start+1)%MAX_BUFFER;
    if (rc == -EPIPE){ /* EPIPE means underrun */
      fprintf(stderr, "underrun occurred\n");
      snd_pcm_prepare(speaker_handle);
    } else if (rc < 0) fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
    else if (rc != (int)frames) fprintf(stderr, "short write, write %d frames\n", rc);
  }

  // notify kernel to empty/close the buffers
  snd_pcm_drain(speaker_handle);
  snd_pcm_close(speaker_handle);

  free(input_buffer); //free our buffers

  kill_flag = 1;  //signal that threads should die
  pthread_exit(NULL); //exit without killing children
  return 0;
}
Esempio n. 8
0
int main(int argc, char **argv) 
{  
	long loops;  
	int rc,j = 0;  
	int size;  
	snd_pcm_t *handle;  
	snd_pcm_hw_params_t *params;  
	unsigned int val,val2;  
	int dir;  
	snd_pcm_uframes_t frames;  
	char *buffer;  
	FILE *fp ;

	if((fp = fopen("audio.pcm", "r")) < 0) {
		printf("open sound.wav fial\n");
	}

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

	/* Allocate a hardware parameters object. */  
	snd_pcm_hw_params_alloca(&params);  
	/* Fill it in with default values. */  
	snd_pcm_hw_params_any(handle, params);  
	/* Set 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 = 16;  //设置的值没有反应
	snd_pcm_hw_params_set_period_size_near(handle,  params, &frames, &dir); // 
	printf("frames is %d\n",(int)frames);
	/* 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);  

	/* 5 seconds in microseconds divided by * period time */  
	loops = 10000000 / val;  
	while (loops > 0) {  
		loops--;  
		//rc = fread(buffer,1, size,fp); 

		rc = read(0, buffer, size);
		//printf("%d\n",j++); 
		if (rc == 0) {  
			fprintf(stderr, "end of file on input\n");  
			break;  
		} else if (rc != size) {  
			fprintf(stderr,  "short read: read %d bytes\n", rc);
		}  
		//else printf("fread to buffer success\n");

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

	/******************打印参数*********************/
	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);
	free(buffer);

	fclose(fp);

	return 0;
}
Esempio n. 9
0
File: audio.c Progetto: hfeeki/dtmf
int AUDIO_Init(audio_config_t* config)
{
	int err;
	snd_pcm_hw_params_t *hw_params;

	memcpy(&audio_config, config, sizeof(audio_config));

	for (;;)
	{
		if ((err = snd_pcm_open(&audio_playback_handle, audio_config.device_name,
				SND_PCM_STREAM_PLAYBACK, 0)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot open %s (%s)\n", audio_config.device_name,
					snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
		{
			fprintf(stderr,
					"Audio device error: cannot allocate hardware parameter structure (%s)\n",
					snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params_any(audio_playback_handle, hw_params)) < 0)
		{
			fprintf(stderr,
					"Audio device error: cannot initialize hardware parameter structure (%s)\n",
					snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params_set_access(audio_playback_handle,
				hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot set access type (%s)\n", snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params_set_format(audio_playback_handle,
				hw_params, SND_PCM_FORMAT_S32_LE)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot set sample format (%s)\n",
					snd_strerror(err));
			break;
		}

		//FIXME: doesn't seem to work properly for other values than default
		if ((err = snd_pcm_hw_params_set_rate_near(audio_playback_handle,
				hw_params, &audio_config.sample_rate, 0)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot set sample rate (%s)\n", snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params_set_channels(audio_playback_handle,
				hw_params, 2)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot set channels count (%s)\n",
					snd_strerror(err));
			break;
		}

		if ((err = snd_pcm_hw_params(audio_playback_handle, hw_params)) < 0)
		{
			fprintf(stderr, "Audio device error: cannot set parameters (%s)\n", snd_strerror(err));
			break;
		}

		snd_pcm_hw_params_free(hw_params);

		return 0;
	}

	audio_playback_handle = NULL;
	return -1;
}
Esempio n. 10
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;

    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);

    s->h = h;
    return 0;

fail:
    snd_pcm_hw_params_free(hw_params);
fail1:
    snd_pcm_close(h);
    return AVERROR(EIO);
}
Esempio n. 11
0
int init_pcm_play(struct pcmConf *pcm)
{
	int rc;
	int ret;
	unsigned int val;
	snd_pcm_hw_params_t* params;//硬件信息和PCM流配置
	int dir=0;


	rc=snd_pcm_open(&(pcm->handle), "default", SND_PCM_STREAM_PLAYBACK, 0);
	if(rc<0)
	{
		perror("\nopen PCM device failed:");
		exit(1);
	}


	snd_pcm_hw_params_alloca(&params); //分配params结构体
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_alloca:");
		exit(1);
	}
	rc=snd_pcm_hw_params_any(pcm->handle, params);//初始化params
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_any:");
		exit(1);
	}
	rc=snd_pcm_hw_params_set_access(pcm->handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //初始化访问权限
	if(rc<0)
	{
		perror("\nsed_pcm_hw_set_access:");
		exit(1);

	}

	//采样位数
	switch(pcm->bit/8)
	{
		case 1:snd_pcm_hw_params_set_format(pcm->handle, params, SND_PCM_FORMAT_U8);
			   break ;
		case 2:snd_pcm_hw_params_set_format(pcm->handle, params, SND_PCM_FORMAT_S16_LE);
			   break ;
		case 3:snd_pcm_hw_params_set_format(pcm->handle, params, SND_PCM_FORMAT_S24_LE);
			   break ;

	}
	rc=snd_pcm_hw_params_set_channels(pcm->handle, params, pcm->channels); //设置声道,1表示单声>道,2表示立体声
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_set_channels:");
		exit(1);
	}
	val = pcm->sampleFrequency;
	rc=snd_pcm_hw_params_set_rate_near(pcm->handle, params, &val, &dir); //设置>频率
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_set_rate_near:");
		exit(1);
	}

	/* set period*/
	val = pcm->frames;
	rc=snd_pcm_hw_params_set_period_size_near(pcm->handle, params, &val, &dir);
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_set_period_size:");
		exit(1);
	}

	rc = snd_pcm_hw_params(pcm->handle, params);
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params: ");
		exit(1);
	}

	rc=snd_pcm_hw_params_get_period_size(params, &(pcm->frames), &dir); /*获取周期长度*/
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_get_period_size:");
		exit(1);
	}
	
	pcm->size = pcm->frames * (pcm->datablock); /*4 代表数据快长度*/

	pcm->buffer =(char*)malloc(pcm->size);

	//创建一个命名信号量
	pcm->semid=semget(SEM_KEY,1,IPC_CREAT | 0666);//创建了一个权限为666的信号量
	pcm->semVal.val = 1;

	/***对0号信号量设置初始值***/
	ret =semctl(pcm->semid,0,SETVAL,pcm->semVal);

	if (ret < 0 ){
		perror("ctl sem error");
		semctl(pcm->semid, 0, IPC_RMID,pcm->semVal);
		return -1 ;
	}


	return 0;
}
static int OpenAndPrepareSound(unsigned long ulFrequency)
{
#if defined(ANDROID)

  /* Only support certain frequencies.  Modify this to check frequency
     against a structure of valid frequencies */
#ifdef FILTER_ON
  if ( ulFrequency == 11025 )
  {
    if ( AudioSetInputFormat ( 44100, NR_OF_CHANNELS ) != 0 ) /* sample at 44100 then downsample */
    {
      PLogError ( "Audio In Error OpenAndPrepareSound - AudioSetInputFormat failed!\n");
      return LHS_E_AUDIOIN_COULDNOTOPENDEVICE; 
    }
  }
  else
  {
    PLogError ( "Audio In Error OpenAndPrepareSound - invalid frequency!");
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }
#else
  if ( ( ulFrequency == 11025 ) || ( ulFrequency == 8000 ) )
  {
    if ( AudioSetInputFormat ( ulFrequency, NR_OF_CHANNELS ) != 0 )
    {
      PLogError ( "Audio In Error OpenAndPrepareSound - AudioSetInputFormat failed!");
      return LHS_E_AUDIOIN_COULDNOTOPENDEVICE; 
    }
  }
  else
  {
    PLogError ( "Audio In Error OpenAndPrepareSound - invalid frequency!");
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }
#endif

  /* set some variables */
  gAudioInInfo.u32SamplesAvailable = 0;

  /* Open Audio driver */
  if (AudioOpen() < 0)
  {
    PLogError ( "Audio In Error OpenAndPrepareSound - AudioOpen failed!");
    return ~LHS_AUDIOIN_OK;
  }

#else

  snd_pcm_hw_params_t *hwparams;
  unsigned int         exact_rate;
  int                  dir;
  int                  rc;

  /* step 1 : open the sound device */
  /* ------------------------------ */
  if ((rc = snd_pcm_open(&ghPCM, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_open() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  if ((rc = snd_pcm_hw_params_malloc(&hwparams)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_malloc() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  /* step 2 : configuring the audio channel */
  /* -------------------------------------- */

  if ((rc = snd_pcm_hw_params_any(ghPCM, hwparams)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_any() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  if ((rc = snd_pcm_hw_params_set_access(ghPCM, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_set_access() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  if ((rc = snd_pcm_hw_params_set_format(ghPCM, hwparams, SND_PCM_FORMAT_S16_LE)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_set_format() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

#ifdef FILTER_ON
  if (ulFrequency == 11025)
  {
    exact_rate = 44100;
  }
  else
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
#else
  exact_rate = ulFrequency;
#endif  

  dir = 0;

#if 0
  /* This version seems to have problems when the code is compiled into a shared library.
     The subsequent call to snd_pcm_hw_params() fails. */
  if ((rc = snd_pcm_hw_params_set_rate_near(ghPCM, hwparams, &exact_rate, &dir)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_set_rate_near() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }
#else
  /* This version works better and in fact makes more sense. */
  if ((rc = snd_pcm_hw_params_set_rate(ghPCM, hwparams, exact_rate, dir)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_set_rate() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }
#endif


  if ((rc = snd_pcm_hw_params_set_channels(ghPCM, hwparams, NR_OF_CHANNELS)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params_set_channels() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  if ((rc = snd_pcm_hw_params(ghPCM, hwparams)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_hw_params() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  /* step 3 : preparing for read */
  /* --------------------------- */

  /*prepare the channel */

  if ((rc = snd_pcm_prepare(ghPCM)) < 0)
  {
    PLogError ( "Audio In Error snd_pcm_prepare() (rc = %d: %s)\n", rc, snd_strerror(rc));
    return LHS_E_AUDIOIN_COULDNOTOPENDEVICE;
  }

  /* set some variables */
  gAudioInInfo.u32SamplesAvailable = 0;


#endif

  /* prepare to read samples */
  setCloseOff();

  return 0;
}
Esempio n. 13
0
int audio_open_output() {
  int err;
  snd_pcm_hw_params_t *hw_params;
  int rate=48000;
  int dir=0;


  if(n_selected_output_device<0 || n_selected_output_device>=n_output_devices) {
    n_selected_output_device=-1;
    return -1;
  }

  int i;
  char hw[16];
  char *selected=output_devices[n_selected_output_device];
 
fprintf(stderr,"audio_open_output: selected=%d:%s\n",n_selected_output_device,selected);

  i=0;
  while(selected[i]!=' ') {
    hw[i]=selected[i];
    i++;
  }
  hw[i]='\0';
  
  if ((err = snd_pcm_open (&playback_handle, hw, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    fprintf (stderr, "audio_open_output: cannot open audio device %s (%s)\n", 
            hw,
            snd_strerror (err));
    return -1;
  }


  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
    fprintf (stderr, "audio_open_output: cannot allocate hardware parameter structure (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
    fprintf (stderr, "audio_open_output: cannot initialize hardware parameter structure (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    fprintf (stderr, "audio_open_output: cannot set access type (%s)\n",
            snd_strerror (err));
    return -1;
}
	
  if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
    fprintf (stderr, "audio_open_output: cannot set sample format (%s)\n",
            snd_strerror (err));
    return -1;
  }
	

  if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, &dir)) < 0) {
    fprintf (stderr, "audio_open_output: cannot set sample rate (%s)\n",
            snd_strerror (err));
    return -1;
  }
	
  if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
    fprintf (stderr, "audio_open_output: cannot set channel count (%s)\n",
            snd_strerror (err));
    return -1;
  }
	
  if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
    fprintf (stderr, "audio_open_output: cannot set parameters (%s)\n",
            snd_strerror (err));
    return -1;
  }
	
  snd_pcm_hw_params_free (hw_params);

  audio_offset=0;
  audio_buffer=(unsigned char *)malloc(AUDIO_BUFFER_SIZE);

  return 0;
}
Esempio n. 14
0
int audio_open_input() {
  int err;
  snd_pcm_hw_params_t *hw_params;
  int rate=48000;
  int dir=0;

  if(n_selected_output_device<0 || n_selected_output_device>=n_output_devices) {
    n_selected_output_device=-1;
    return -1;
  }

  int i;
  char hw[16];
  char *selected=input_devices[n_selected_input_device];
  fprintf(stderr,"audio_open_input: selected=%d:%s\n",n_selected_input_device,selected);
  
  switch(protocol) {
    case ORIGINAL_PROTOCOL:
      mic_buffer_size = 720;
      break;
    case NEW_PROTOCOL:
      mic_buffer_size = 64;
      break;
	case RADIOBERRY_PROTOCOL:
		mic_buffer_size = 1024;
		break;
	default:
      break;
  }
  
  i=0;
  while(selected[i]!=' ') {
    hw[i]=selected[i];
    i++;
  }
  hw[i]='\0';


  if ((err = snd_pcm_open (&record_handle, hw, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
    fprintf (stderr, "audio_open_input: cannot open audio device %s (%s)\n",
            hw,
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
    fprintf (stderr, "audio_open_input: cannot allocate hardware parameter structure (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_any (record_handle, hw_params)) < 0) {
    fprintf (stderr, "audio_open_input: cannot initialize hardware parameter structure (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_set_access (record_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    fprintf (stderr, "audio_open_input: cannot set access type (%s)\n",
            snd_strerror (err));
    return -1;
}

  if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
    fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_set_rate_near (record_handle, hw_params, &rate, &dir)) < 0) {
    fprintf (stderr, "audio_open_input: cannot set sample rate (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params_set_channels (record_handle, hw_params, 1)) < 0) {
    fprintf (stderr, "audio_open_input: cannot set channel count (%s)\n",
            snd_strerror (err));
    return -1;
  }

  if ((err = snd_pcm_hw_params (record_handle, hw_params)) < 0) {
    fprintf (stderr, "audio_open_input: cannot set parameters (%s)\n",
            snd_strerror (err));
    return -1;
  }

  snd_pcm_hw_params_free (hw_params);

  mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);

  running=TRUE;
  err=pthread_create(&mic_read_thread_id,NULL,mic_read_thread,NULL);
  if(err != 0) {
    fprintf(stderr,"pthread_create failed on mic_read_thread: rc=%d\n", err);
    return -1;
  }

  return 0;
}
Esempio n. 15
0
int	play_wav(char *file)
{
	int nread;
	FILE *fp;
	fp = fopen(file, "rb");
	if(fp == NULL) {
		perror("open file failed:\n");
		exit(1);
	}
	nread = fread(&wav_header, 1, sizeof(wav_header), fp);

	int rc;
	int ret;
	int size;
	snd_pcm_t* handle; //PCI设备句柄
	snd_pcm_hw_params_t* params; //硬件信息和PCM流配置
	unsigned int val;
	int dir = 0;
	snd_pcm_uframes_t frames;
	char *buffer;
	int channels = wav_header.wChannels;
	int frequency = wav_header.nSamplesPersec;
	int bit = wav_header.wBitsPerSample;
	int datablock = wav_header.wBlockAlign;
	unsigned char ch[100]; //用来存储wav文件的头信息

	rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if(rc < 0)
	{
		perror("\nopen PCM device failed:");
		exit(1);
	}
	snd_pcm_hw_params_alloca(&params); //分配params结构体
	if(rc < 0)
	{
		perror("\nsnd_pcm_hw_params_alloca:");
		exit(1);
	}
	rc = snd_pcm_hw_params_any(handle, params); //初始化params
	if(rc<0)
	{
		perror("\nsnd_pcm_hw_params_any:");
		exit(1);
	}
	rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //初始化访问权限
	if(rc < 0)
	{
		perror("\nsed_pcm_hw_set_access:");
		exit(1);
	}
	//采样位数
	switch(bit / 8) {
	case 1:
		snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_U8);
		break;
	case 2:
		snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
		break;
	case 3:
		snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S24_LE);
		break;
	}
	rc = snd_pcm_hw_params_set_channels(handle, params, channels); //设置声道,1表示单声>道,2表示立体声
	if(rc < 0) {
		perror("\nsnd_pcm_hw_params_set_channels:");
		exit(1);
	}
	val = frequency;
	rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); //设置>频率
	if(rc < 0) {
		perror("\nsnd_pcm_hw_params_set_rate_near:");
		exit(1);
	}
	rc = snd_pcm_hw_params(handle, params);
	if(rc < 0) {
		perror("\nsnd_pcm_hw_params: ");
		exit(1);
	}
	rc = snd_pcm_hw_params_get_period_size(params, &frames, &dir); //获取周期长度
	if(rc < 0) {
		perror("\nsnd_pcm_hw_params_get_period_size:");
		exit(1);
	}
	size = frames * datablock; //4 代表数据快长度
	buffer = (char*)malloc(size);
	fseek(fp, 54, SEEK_SET); //定位歌曲到数据区

	while(1) {
		memset(buffer, 0, size);
		ret = fread(buffer, 1, size, fp);
		if(ret == 0) {
			printf("歌曲写入结束\n");
			break;
		} else if (ret != size) {}
		// 写音频数据到PCM设备 
		while((ret = snd_pcm_writei(handle, buffer, frames) < 0)) {
			usleep(2000); 
			if(ret == -EPIPE) {
				// EPIPE means underrun
				fprintf(stderr, "underrun occurred\n");
				//完成硬件参数设置,使设备准备好 
				snd_pcm_prepare(handle);
			} else if(ret < 0) {
				fprintf(stderr, "error from writei: %s\n", snd_strerror(ret));
			}
		}
	}
	snd_pcm_drain(handle);
	snd_pcm_close(handle);
	free(buffer);
	fclose(fp);
	return 0;
}
Esempio n. 16
0
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;
}
/// Open and init default sound card params
int init_soundcard()
{
	int err = 0;

	if ((err = snd_pcm_open(&capture_handle, snd_device,
			SND_PCM_STREAM_CAPTURE, 0)) < 0)
	{
		fprintf(stderr, "cannot open audio device %s (%s, %d)\n",
				snd_device, snd_strerror(err), err);
		return OPEN_ERROR;
	}

	if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
	{
		fprintf(
				stderr,
				"cannot allocate hardware parameter structure (%s, %d)\n",
				snd_strerror(err), err);
		return MALLOC_ERROR;
	}

	if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0)
	{
		fprintf(
				stderr,
				"cannot initialize hardware parameter structure (%s, %d)\n",
				snd_strerror(err), err);
		return ANY_ERROR;
	}

	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, %d)\n",
				snd_strerror(err), err);
		return ACCESS_ERROR;
	}

	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, %d)\n",
				snd_strerror(err), err);
		return FORMAT_ERROR;
	}

	if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params,
			&srate, 0)) < 0)
	{
		fprintf(stderr, "cannot set sample rate (%s, %d)\n",
				snd_strerror(err), err);
		return RATE_ERROR;
	}

	if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, nchan))
			< 0)
	{
		fprintf(stderr, "cannot set channel count (%s, %d)\n",
				snd_strerror(err), err);
		return CHANNELS_ERROR;
	}

	if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0)
	{
		fprintf(stderr, "cannot set parameters (%s, %d)\n",
				snd_strerror(err), err);
		return PARAMS_ERROR;
	}

	if ((err = snd_pcm_prepare(capture_handle)) < 0)
	{
		fprintf(
				stderr,
				"cannot prepare audio interface for use (%s, %d)\n",
				snd_strerror(err), err);
		return PREPARE_ERROR;
	}

	  //fprintf(stderr, "Capture handle1: %x\n", capture_handle);
	  //fprintf(stderr, "Capture state1: %d\n", snd_pcm_state(capture_handle));

	  // Start reading data from sound card
	  if ((err = snd_pcm_start(capture_handle)) < 0)
	  {
		  fprintf(stderr, "cannot start soundcard (%s, %d)\n", snd_strerror(err),
				  err);
		  return START_ERROR;
	  }

	  //fprintf(stderr, "Capture handle2: %x\n", capture_handle);
	  //fprintf(stderr, "Capture state2: %d\n", snd_pcm_state(capture_handle));

	/*
	fprintf(stderr, "%s\n", "Parameters of PCM:");
	fprintf(stderr, "%x\n", capture_handle);
	fprintf(stderr, "%s\n", snd_pcm_name(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_type(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_stream(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_poll_descriptors_count(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_state(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_avail(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_avail_update(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_rewindable(capture_handle));
	fprintf(stderr, "%d\n", snd_pcm_forwardable(capture_handle));
	fprintf(stderr, "%s\n", "-------------------------------------");
	fprintf(stderr, "%d\n", snd_pcm_info_malloc(&s_info));
	fprintf(stderr, "%d\n", snd_pcm_info(capture_handle, s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_device(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_subdevice(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_stream(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_card(s_info));
	fprintf(stderr, "%s\n", snd_pcm_info_get_id(s_info));
	fprintf(stderr, "%s\n", snd_pcm_info_get_name(s_info));
	fprintf(stderr, "%s\n", snd_pcm_info_get_subdevice_name(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_class(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_subclass(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_subdevices_count(s_info));
	fprintf(stderr, "%d\n", snd_pcm_info_get_subdevices_avail(s_info));
	fprintf(stderr, "%s\n", "-------------------------------------");
	fprintf(stderr, "%d\n", snd_pcm_hw_params_current(capture_handle, hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_double(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_batch(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_block_transfer(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_monotonic(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_can_overrange(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_can_pause(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_can_resume(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_half_duplex(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_is_joint_duplex(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_can_sync_start(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_can_disable_period_wakeup(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_sbits(hw_params));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_fifo_size(hw_params));
	fprintf(stderr, "%s\n", "-------------------------------------");
	unsigned int *tmp1 = (unsigned int *)malloc(sizeof(unsigned int));
	int *tmp2 = (int *)malloc(sizeof(int));
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_channels(hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_channels_min(hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_channels_max(hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_rate(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_rate_min(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_rate_max(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_rate_resample(capture_handle, hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_export_buffer(capture_handle, hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_period_wakeup(capture_handle, hw_params, tmp1)); fprintf(stderr, "%d\n", *tmp1);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_period_time(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_period_time_min(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	fprintf(stderr, "%d\n", snd_pcm_hw_params_get_period_time_max(hw_params, tmp1, tmp2)); fprintf(stderr, "%d\n", *tmp1 ,  *tmp2);
	*/

	snd_pcm_hw_params_free(hw_params);
	/*
	snd_pcm_info_free(s_info);
	free(tmp1);
	free(tmp2);
	*/

	return NO_ERROR;
}
/**
   Init the alsa sub-system

   TODO: add support for on-demand sample size adjustment and different bitrates

 * Class:     net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream
 * Method:    jni_alsa_init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1init
  (JNIEnv *env, jobject obj)
{
  int err;
  
  snd_pcm_hw_params_t *capture_params;
  
  char *device = "plughw:0,0";
  
  int rate = 8000;
  int exact_rate;
    
  printf("init called\n");

  if ((err = snd_pcm_open(&capture, device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
    fprintf(stderr, "alsa: can not open device %s for capture\n", device);
    return;
  }

  snd_pcm_hw_params_alloca(&capture_params);

  /* Init hwparams with full configuration space */
  if (snd_pcm_hw_params_any(capture, capture_params) < 0) {
    fprintf(stderr, "Can not configure this PCM device.\n");
    return;
  }
  
  if (snd_pcm_hw_params_set_access(capture, capture_params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
    fprintf(stderr, "Error setting access.\n");
    return;
  }
  
  /* Set sample format */
  if (snd_pcm_hw_params_set_format(capture, capture_params, SND_PCM_FORMAT_S16_LE) < 0) {
    fprintf(stderr, "Error setting format.\n");
    return;
  }
  
  /* Set sample rate. If the exact rate is not supported */
  /* by the hardware, use nearest possible rate.         */ 
  exact_rate = rate;
  if (snd_pcm_hw_params_set_rate_near(capture, capture_params, &exact_rate, 0) < 0) {
    fprintf(stderr, "Error setting rate.\n");
    snd_pcm_close(capture);
    return;
  }
  if (rate != exact_rate) {
    fprintf(stderr, "alsa: The rate %d Hz is not supported by your hardware.\n", rate); 
    snd_pcm_close(capture);
    return;
  }
  
  /* Set number of channels */
  if (snd_pcm_hw_params_set_channels(capture, capture_params, 1) < 0) {
    fprintf(stderr, "Error setting channels.\n");
    snd_pcm_close(capture);
    return;
  }

    /* Set number of periods. Periods used to be called fragments. */ 
  if (snd_pcm_hw_params_set_buffer_size_near(capture, capture_params, &buffersize) < 0) {
    fprintf(stderr, "Error setting buffer_size\n");
    snd_pcm_close(capture);
    return;
  }
	
  periodsize = buffersize / 2;
  if (snd_pcm_hw_params_set_period_size_near(capture, capture_params, &periodsize, 0) < 0) {
    fprintf(stderr, "Error setting period size\n");
    snd_pcm_close(capture);
    return;
  }

  if (snd_pcm_hw_params(capture, capture_params) < 0) {
    fprintf(stderr, "can not commit hw parameters\n");
    snd_pcm_close(capture);
    return;
  }

  printf("Rate is %d, buffer size is %d and period size is %d\n", rate, buffersize, periodsize);

  return;
}
Esempio n. 19
0
static HRESULT WINAPI IDsCaptureDriverBufferImpl_SetFormat(PIDSCDRIVERBUFFER iface, LPWAVEFORMATEX pwfx)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    WINE_WAVEDEV *wwi = &WInDev[This->drv->wDevID];
    snd_pcm_t *pcm = NULL;
    snd_pcm_hw_params_t *hw_params = This->hw_params;
    snd_pcm_format_t format = -1;
    snd_pcm_uframes_t buffer_size;
    DWORD rate = pwfx->nSamplesPerSec;
    int err=0;
    BOOL mmap;

    TRACE("(%p, %p)\n", iface, pwfx);

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

    /* **** */
    EnterCriticalSection(&This->pcm_crst);

    err = snd_pcm_open(&pcm, wwi->pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);

    if (err < 0)
    {
        if (errno != EBUSY || !This->pcm)
        {
            /* **** */
            LeaveCriticalSection(&This->pcm_crst);
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_GENERIC;
        }
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
        This->pcm = NULL;
        err = snd_pcm_open(&pcm, wwi->pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
        if (err < 0)
        {
            /* **** */
            LeaveCriticalSection(&This->pcm_crst);
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_BUFFERLOST;
        }
    }

    /* Set some defaults */
    snd_pcm_hw_params_any(pcm, hw_params);

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

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

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

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

    snd_pcm_hw_params_set_periods_integer(pcm, hw_params);
    buffer_size = This->mmap_buflen_bytes / pwfx->nBlockAlign;
    snd_pcm_hw_params_set_buffer_size_near(pcm, hw_params, &buffer_size);
    buffer_size = 5000;
    snd_pcm_hw_params_set_period_time_near(pcm, hw_params, (unsigned int*)&buffer_size, NULL);

    err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
    if (err < 0)
    {
        err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
        if (err < 0) { WARN("Could not set access\n"); goto err; }
        mmap = 0;
    }
    else
        mmap = 1;

    err = snd_pcm_hw_params(pcm, hw_params);
    if (err < 0) { WARN("Could not set hw parameters\n"); goto err; }

    if (This->pcm)
    {
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
    }
    This->pcm = pcm;
    This->mmap = mmap;

    snd_pcm_prepare(This->pcm);
    CreateMMAP(This);

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return S_OK;

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

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

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

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return DSERR_BADFORMAT;
}
Esempio n. 20
0
int main(int argc, char **argv)
{
	unsigned int pcm, tmp, dir;
	int rate, channels, seconds;
	snd_pcm_t *pcm_handle;
	snd_pcm_hw_params_t *params;
	snd_pcm_uframes_t frames;
	char *buff;
	int buff_size, loops;
	int fp; 
	/*if (argc < 4)
	{
		printf("Usage: %s <sample_rate> <channels> <seconds>\n",
				argv[0]);
		return -1;
	}*/

	rate = 8000;//atoi(argv[1]);
	channels = 1;//atoi(argv[2]);
	seconds = 10;//atoi(argv[3]);

	/* Open the PCM device in playback mode */
	if (pcm = snd_pcm_open(&pcm_handle, "default" ,	SND_PCM_STREAM_PLAYBACK, 0) < 0)
		printf("ERROR: Can't open \"%s\" PCM device. %s\n",	"default", snd_strerror(pcm));

	/* Allocate parameters object and fill it with default values*/
	snd_pcm_hw_params_alloca(&params);

	snd_pcm_hw_params_any(pcm_handle, params);

	/* Set parameters */
	if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
		printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_format(pcm_handle, params,SND_PCM_FORMAT_U8) < 0)
		printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels) < 0)
		printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0)
		printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));

	/* Write parameters */
	if (pcm = snd_pcm_hw_params(pcm_handle, params) < 0)
		printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm));

	/* Resume information */
	printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle));

	printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));

	snd_pcm_hw_params_get_channels(params, &tmp);
	printf("channels: %i ", tmp);

	if (tmp == 1)
		printf("(mono)\n");
	else if (tmp == 2)
		printf("(stereo)\n");

	snd_pcm_hw_params_get_rate(params, &tmp, 0);
	printf("rate: %d bps\n", tmp);

	printf("seconds: %d\n", seconds);	

	/* Allocate buffer to hold single period */
	snd_pcm_hw_params_get_period_size(params, &frames, 0);

	buff_size = frames * channels * 2 /* 2 -> sample size */;
	buff = (char *) malloc(buff_size*3);

	
	snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
	
	fp=open("222.wav",O_RDONLY);
	for (loops = (seconds * 1000000) / tmp; loops > 0; loops--)
	{

		if (pcm = read(fp, buff, buff_size) == 0)
		{
			printf("Early end of file.\n");
			//return 0;
		}
		
		
		if (pcm = snd_pcm_writei(pcm_handle, buff, frames) == -EPIPE)
		{
			printf("XRUN.\n");
			snd_pcm_prepare(pcm_handle);
		} else if (pcm < 0) {
			printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm));
		}
		
	}

	snd_pcm_drain(pcm_handle);
	snd_pcm_close(pcm_handle);
	free(buff);

	return 0;
}
Esempio n. 21
0
void * startThreadInAudio(void * arg){
	mainData_t* mainData = (mainData_t*)arg;
	int err;

	snd_pcm_t *capture_handle;
	snd_pcm_hw_params_t *hw_params;

	if ((err = snd_pcm_open (&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
		fprintf (stderr, "cannot open audio device %s (%s)\n",
				"default",
			 snd_strerror (err));
		return NULL;
	}

	if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
		fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
			 snd_strerror (err));
		snd_pcm_close (capture_handle);
		return NULL;
	}

	if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {
		fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
			 snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}

	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));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}

	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));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}
	unsigned int rate = 8000;
	if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &rate, 0)) < 0) {
		fprintf (stderr, "cannot set sample rate (%s)\n",
			 snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}

	if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 1)) < 0) {
		fprintf (stderr, "cannot set channel count (%s)\n",
			 snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}
	snd_pcm_uframes_t buffer_size = 160*10;
	if((err=snd_pcm_hw_params_set_buffer_size_near (capture_handle, hw_params, &buffer_size))<0){
		fprintf (stderr, "cannot set parameters (%s)\n",
			 snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}
	if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) {
		fprintf (stderr, "cannot set parameters (%s)\n",
			 snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close (capture_handle);
		return NULL;
	}

	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));
		snd_pcm_close (capture_handle);
		return NULL;
	}

	P_audioBufRaw outBuffer;
	netPacket_t outPacket;
	initDataPacket(&outPacket);
	gsm gsm = gsm_create();
	while(pthread_mutex_trylock(&mainData->threadInaudioQuit)==EBUSY ){
		err = snd_pcm_readi(capture_handle, &outBuffer, P_RawDataBuf);
		if (err < 0){
			printf("snd_pcm_readi error: %s\n", snd_strerror(err));
			err = snd_pcm_recover(capture_handle, err, 0);
		}
		if (err < 0) {
			printf("snd_pcm_readi failed: %s\n", snd_strerror(err));
			break;
		}
		encode(gsm,(unsigned short *)&outBuffer,(unsigned char *)&outPacket.Data);
		int i;
		for(i=0;i<mainData->usersArray->lenghtArray;i++){
			if(mainData->usersArray->users[i]!=NULL){
				sendFromUdpSocket(mainData->udpSocket,&outPacket,&mainData->usersArray->users[i]->addr);
			}
		}
		outPacket.count++;
	}
	pthread_mutex_unlock(&mainData->threadInaudioQuit);
	snd_pcm_close (capture_handle);
	gsm_destroy(gsm);
	return NULL;
}
Esempio n. 22
0
main (int argc, char *argv[])
{
  int i;
  int err;
  int buf[128];
  snd_pcm_t *playback_handle;
  snd_pcm_hw_params_t *hw_params;
  FILE *fin;
  size_t nread;
  unsigned int rate = 44100;	

  if (argc != 3) {
    fprintf(stderr, "Usage: %s card file\n", argv[0]);
    exit(1);
  }

  if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    fprintf (stderr, "cannot open audio device %s (%s)\n", 
	     argv[1],
	     snd_strerror (err));
    exit (1);
  }

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

  if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    fprintf (stderr, "cannot set access type (%s)\n",
	     snd_strerror (err));
    exit (1);
  }
  
  if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
    fprintf (stderr, "cannot set sample format (%s)\n",
	     snd_strerror (err));
    exit (1);
  }


  if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, 0)) < 0) {
    fprintf (stderr, "cannot set sample rate (%s)\n",
	     snd_strerror (err));
    exit (1);
  }
  printf("Rate set to %d\n", rate);
	
  if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
    fprintf (stderr, "cannot set channel count (%s)\n",
	     snd_strerror (err));
    exit (1);
  }
	
  if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
    fprintf (stderr, "cannot set parameters (%s)\n",
	     snd_strerror (err));
    exit (1);
  }
	
  snd_pcm_hw_params_free (hw_params);
  
  if ((fin = fopen(argv[2], "r")) == NULL) {
      fprintf(stderr, "Can't open %s for reading\n", argv[2]);
      exit(1);
  }
  int size=sizeof(int);
  while(1)
  {
	nread = fread(buf, size, 128, fin);
	  
	  if (nread == 0) {
	      fprintf(stderr, "end of file on input\n");
	      break;
	    } else if (nread != size) {
	      fprintf(stderr,
		      "short read: read %d bytes\n", nread);
	    }
	    nread = snd_pcm_writei(playback_handle, buf, nread);
	    if (nread == -EPIPE) {
	      /* EPIPE means underrun */
	      fprintf(stderr, "underrun occurred\n");
	      snd_pcm_prepare(playback_handle);
	    } else if (nread < 0) {
	      fprintf(stderr,
		      "error from writei: %s\n",
		      snd_strerror(nread));
	    }  else if (nread != (int)rate) {
	      fprintf(stderr,
		      "short write, write %d frames\n", nread);
	    }
  }
 
  snd_pcm_drain(playback_handle);	
  snd_pcm_close (playback_handle); 

}
Esempio n. 23
0
int main(int argc,char *argv[])
{
    int i=0;
    int err;
    char buf[128];
    snd_pcm_t *playback_handle;
    int rate=22050;
    int channels=2;
    snd_pcm_hw_params_t *hw_params;
    if((err=snd_pcm_open(&playback_handle,argv[1],SND_PCM_STREAM_PLAYBACK,0))<0){
        fprintf(stderr,"cant 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,"cant open allocate parameter structure  (%s)\n",snd_strerror(err));
        exit(1);
    }
    if((err=snd_pcm_hw_params_any(playback_handle,hw_params))<0){
        fprintf(stderr,"cant open initialize hw 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,"cant set access type  (%s)\n",snd_strerror(err));
        exit(1);
    }
    if((err=snd_pcm_hw_params_set_format(playback_handle,hw_params,SND_PCM_FORMAT_S16_LE))<0){
        fprintf(stderr,"cant open set format (%s)\n",snd_strerror(err));
        exit(1);
    }
    if((err=snd_pcm_hw_params_set_rate_near(playback_handle,hw_params,&rate,0))<0){
        fprintf(stderr,"cant set rate (%s)\n",snd_strerror(err));
        exit(1);
    }
    if((err=snd_pcm_hw_params_set_channels(playback_handle,hw_params,channels))<0){
        fprintf(stderr,"cant set channels  (%s)\n",snd_strerror(err));
        exit(1);
    }
    if((err=snd_pcm_hw_params(playback_handle,hw_params))<0){
        fprintf(stderr,"cant open set parameter (%s)\n",snd_strerror(err));
        exit(1);
    }
    snd_pcm_hw_params_free(hw_params);
    if((err=snd_pcm_prepare(playback_handle))<0){
        fprintf(stderr,"cant prepare audio interface for use  (%s)\n",snd_strerror(err));
        exit(1);
    }
    i=0;
    while(i<256)
	{
		memset(buf,i,128);
		err=snd_pcm_writei(playback_handle,buf,32);
		fprintf(stderr,"write to audio interface %d\n",err);
		if(err<0)
		{
			snd_pcm_prepare(playback_handle);
		}
		i++;
	}
	snd_pcm_close(playback_handle);
    exit(0);
}
Esempio n. 24
0
static int set_hwparams(snd_pcm_t *handle,
                        snd_pcm_hw_params_t *params,
                        snd_pcm_access_t access)
{
        unsigned int rrate;
        snd_pcm_uframes_t size;
        int err, dir;

        /* choose all parameters */
        err = snd_pcm_hw_params_any(handle, params);
        if (err < 0) {
                printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
                return err;
        }
        /* set hardware resampling */
        err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
        if (err < 0) {
                printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* set the interleaved read/write format */
        err = snd_pcm_hw_params_set_access(handle, params, access);
        if (err < 0) {
                printf("Access type not available for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* set the sample format */
        err = snd_pcm_hw_params_set_format(handle, params, format);
        if (err < 0) {
                printf("Sample format not available for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* set the count of channels */
        err = snd_pcm_hw_params_set_channels(handle, params, channels);
        if (err < 0) {
                printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err));
                return err;
        }
        /* set the stream rate */
        rrate = rate;
        err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
        if (err < 0) {
                printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
                return err;
        }
        if (rrate != rate) {
                printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
                return -EINVAL;
        }
        /* set the buffer time */
        err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
        if (err < 0) {
                printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
                return err;
        }
        err = snd_pcm_hw_params_get_buffer_size(params, &size);
        if (err < 0) {
                printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
                return err;
        }
        buffer_size = size;
        /* set the period time */
        err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
        if (err < 0) {
                printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
                return err;
        }
        err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
        if (err < 0) {
                printf("Unable to get period size for playback: %s\n", snd_strerror(err));
                return err;
        }
        period_size = size;
        /* write the parameters to device */
        err = snd_pcm_hw_params(handle, params);
        if (err < 0) {
                printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
                return err;
        }
        return 0;
}
Esempio n. 25
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;
  }
}
Esempio n. 26
0
main (int argc, char *argv[])
{
    int i;
    int err;
    short buf[128];

    //设备句柄
    snd_pcm_t *playback_handle;

    //用来播放 PCM 数据流的硬件信息配置
    //在往音频设备(声卡)写入音频数据之前,必须设置访问类型、采样格式、采样率、声道数等
    snd_pcm_hw_params_t *hw_params;

    //打开PCM音频设备
    if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        fprintf (stderr, "cannot open audio device %s (%s)\n", 
                argv[1],
                snd_strerror (err));
        exit (1);
    }

    //分配snd_pcm_hw_params_t(hw_params)结构空间
    if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
        fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
                snd_strerror (err));
        exit (1);
    }

    //初始化hw_params,即初始化硬件播放参数
    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);
    }

    //设置访问类型,SND_PCM_ACCESS_RW_INTERLEAVED:交错访问,在缓冲区的每个 PCM 帧都包含所有设置的声道的连续的采样数据。
    //比如声卡要播放采样长度是 16-bit 的 PCM 立体声数据,表示每个 PCM 帧中有 16-bit 的左声道数据,
    //然后是 16-bit 右声道数据

    //SND_PCM_ACCESS_RW_NONINTERLEAVED :非交错访问。每个 PCM 帧只是一个声道需要的数据,
    //如果使用多个声道,那么第一帧是第一个声道的数据,第二帧是第二个声道的数据,依此类推
    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);
    }

    //设置数据格式,主要控制输入的音频数据的类型、无符号还是有符号、是 little-endian 还是 bit-endian
    if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
        fprintf (stderr, "cannot set sample format (%s)\n",
                snd_strerror (err));
        exit (1);
    }

    //设置音频数据的最接近目标的采样率
    if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 44100, 0)) < 0) {
        fprintf (stderr, "cannot set sample rate (%s)\n",
                snd_strerror (err));
        exit (1);
    }

    //设置音频设备的声道,常见的就是单声道和立体声,如果是立体声,设置最后一个参数为2
    if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
        fprintf (stderr, "cannot set channel count (%s)\n",
                snd_strerror (err));
        exit (1);
    }

    //从设备配置空间选择一个配置,让函数 snd_pcm_prepare() 准备好 PCM 设备,以便写入 PCM 数据
    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);

    //准备好PCM设备,以便写入PCM数据
    if ((err = snd_pcm_prepare (playback_handle)) < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
                snd_strerror (err));
        exit (1);
    }

    for (i = 0; i < 10; ++i) {
        //把交错的音频数据写入到音频设备
        if ((err = snd_pcm_writei (playback_handle, buf, 128)) != 128) {
            fprintf (stderr, "write to audio interface failed (%s)\n",
                    snd_strerror (err));
            exit (1);
        }
    }

    snd_pcm_close (playback_handle);
    exit (0);
}
Esempio n. 27
0
/**************************************************************************
 * 				wodOpen				[internal]
 */
static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
{
    WINE_WAVEDEV*	        wwo;
    snd_pcm_t *                 pcm = NULL;
    snd_hctl_t *                hctl = NULL;
    snd_pcm_hw_params_t *       hw_params = NULL;
    snd_pcm_sw_params_t *       sw_params;
    snd_pcm_access_t            access;
    snd_pcm_format_t            format = -1;
    unsigned int                rate;
    unsigned int                buffer_time = 120000;
    unsigned int                period_time = 22000;
    snd_pcm_uframes_t           buffer_size;
    snd_pcm_uframes_t           period_size;
    int                         flags;
    int                         err=0;
    int                         dir=0;
    DWORD                       retcode = 0;

    TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags);
    if (lpDesc == NULL) {
	WARN("Invalid Parameter !\n");
	return MMSYSERR_INVALPARAM;
    }
    if (wDevID >= ALSA_WodNumDevs) {
	TRACE("Asked for device %d, but only %d known!\n", wDevID, ALSA_WodNumDevs);
	return MMSYSERR_BADDEVICEID;
    }

    /* only PCM format is supported so far... */
    if (!ALSA_supportedFormat(lpDesc->lpFormat)) {
	WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
	     lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
	     lpDesc->lpFormat->nSamplesPerSec);
	return WAVERR_BADFORMAT;
    }

    if (dwFlags & WAVE_FORMAT_QUERY) {
	TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
	     lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
	     lpDesc->lpFormat->nSamplesPerSec);
	return MMSYSERR_NOERROR;
    }

    wwo = &WOutDev[wDevID];

    if (wwo->pcm != NULL) {
        WARN("%d already allocated\n", wDevID);
        return MMSYSERR_ALLOCATED;
    }

    if (dwFlags & WAVE_DIRECTSOUND)
        FIXME("Why are we called with DirectSound flag? It doesn't use MMSYSTEM any more\n");
        /* not supported, ignore it */
    dwFlags &= ~WAVE_DIRECTSOUND;

    flags = SND_PCM_NONBLOCK;

    if ( (err = snd_pcm_open(&pcm, wwo->pcmname, SND_PCM_STREAM_PLAYBACK, flags)) < 0)
    {
        ERR("Error open: %s\n", snd_strerror(err));
	return MMSYSERR_NOTENABLED;
    }

    if (wwo->ctlname)
    {
        err = snd_hctl_open(&hctl, wwo->ctlname, 0);
        if (err >= 0)
        {
            snd_hctl_load(hctl);
        }
        else
        {
            WARN("Could not open hctl for [%s]: %s\n", wwo->ctlname, snd_strerror(err));
            hctl = NULL;
        }
    }

    wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);

    wwo->waveDesc = *lpDesc;
    ALSA_copyFormat(lpDesc->lpFormat, &wwo->format);

    TRACE("Requested this format: %dx%dx%d %s\n",
          wwo->format.Format.nSamplesPerSec,
          wwo->format.Format.wBitsPerSample,
          wwo->format.Format.nChannels,
          ALSA_getFormat(wwo->format.Format.wFormatTag));

    if (wwo->format.Format.wBitsPerSample == 0) {
	WARN("Resetting zeroed wBitsPerSample\n");
	wwo->format.Format.wBitsPerSample = 8 *
	    (wwo->format.Format.nAvgBytesPerSec /
	     wwo->format.Format.nSamplesPerSec) /
	    wwo->format.Format.nChannels;
    }

#define EXIT_ON_ERROR(f,e,txt) do \
{ \
    int err; \
    if ( (err = (f) ) < 0) \
    { \
	WARN(txt ": %s\n", snd_strerror(err)); \
	retcode=e; \
	goto errexit; \
    } \
} while(0)

    sw_params = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_sw_params_sizeof() );
    snd_pcm_hw_params_malloc(&hw_params);
    if (! hw_params)
    {
        retcode = MMSYSERR_NOMEM;
        goto errexit;
    }
    snd_pcm_hw_params_any(pcm, hw_params);

    access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
    if ( ( err = snd_pcm_hw_params_set_access(pcm, hw_params, access ) ) < 0) {
        WARN("mmap not available. switching to standard write.\n");
        access = SND_PCM_ACCESS_RW_INTERLEAVED;
	EXIT_ON_ERROR( snd_pcm_hw_params_set_access(pcm, hw_params, access ), MMSYSERR_INVALPARAM, "unable to set access for playback");
	wwo->write = snd_pcm_writei;
    }
    else
	wwo->write = snd_pcm_mmap_writei;

    if ((err = snd_pcm_hw_params_set_channels(pcm, hw_params, wwo->format.Format.nChannels)) < 0) {
        WARN("unable to set required channels: %d\n", wwo->format.Format.nChannels);
        EXIT_ON_ERROR( snd_pcm_hw_params_set_channels(pcm, hw_params, wwo->format.Format.nChannels ), WAVERR_BADFORMAT, "unable to set required channels" );
    }

    if ((wwo->format.Format.wFormatTag == WAVE_FORMAT_PCM) ||
        ((wwo->format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
        IsEqualGUID(&wwo->format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) {
        format = (wwo->format.Format.wBitsPerSample == 8) ? SND_PCM_FORMAT_U8 :
                 (wwo->format.Format.wBitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE :
                 (wwo->format.Format.wBitsPerSample == 24) ? SND_PCM_FORMAT_S24_3LE :
                 (wwo->format.Format.wBitsPerSample == 32) ? SND_PCM_FORMAT_S32_LE : -1;
    } else if ((wwo->format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
        IsEqualGUID(&wwo->format.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)){
        format = (wwo->format.Format.wBitsPerSample == 32) ? SND_PCM_FORMAT_FLOAT_LE : -1;
    } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_MULAW) {
        FIXME("unimplemented format: WAVE_FORMAT_MULAW\n");
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_ALAW) {
        FIXME("unimplemented format: WAVE_FORMAT_ALAW\n");
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    } else if (wwo->format.Format.wFormatTag == WAVE_FORMAT_ADPCM) {
        FIXME("unimplemented format: WAVE_FORMAT_ADPCM\n");
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    } else {
        ERR("invalid format: %0x04x\n", wwo->format.Format.wFormatTag);
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    }

    if ((err = snd_pcm_hw_params_set_format(pcm, hw_params, format)) < 0) {
        WARN("unable to set required format: %s\n", snd_pcm_format_name(format));
        EXIT_ON_ERROR( snd_pcm_hw_params_set_format(pcm, hw_params, format), WAVERR_BADFORMAT, "unable to set required format" );
    }

    rate = wwo->format.Format.nSamplesPerSec;
    dir=0;
    err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, &dir);
    if (err < 0) {
	WARN("Rate %d Hz not available for playback: %s\n", wwo->format.Format.nSamplesPerSec, snd_strerror(rate));
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    }
    if (!ALSA_NearMatch(rate, wwo->format.Format.nSamplesPerSec)) {
        WARN("Rate doesn't match (requested %d Hz, got %d Hz)\n", wwo->format.Format.nSamplesPerSec, rate);
        retcode = WAVERR_BADFORMAT;
        goto errexit;
    }

    TRACE("Got this format: %dx%dx%d %s\n",
          wwo->format.Format.nSamplesPerSec,
          wwo->format.Format.wBitsPerSample,
          wwo->format.Format.nChannels,
          ALSA_getFormat(wwo->format.Format.wFormatTag));

    dir=0;
    EXIT_ON_ERROR( snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_time, &dir), MMSYSERR_INVALPARAM, "unable to set buffer time");
    dir=0;
    EXIT_ON_ERROR( snd_pcm_hw_params_set_period_time_near(pcm, hw_params, &period_time, &dir), MMSYSERR_INVALPARAM, "unable to set period time");

    EXIT_ON_ERROR( snd_pcm_hw_params(pcm, hw_params), MMSYSERR_INVALPARAM, "unable to set hw params for playback");

    err = snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
    err = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);

    snd_pcm_sw_params_current(pcm, sw_params);

    EXIT_ON_ERROR( snd_pcm_sw_params_set_start_threshold(pcm, sw_params, 1), MMSYSERR_ERROR, "unable to set start threshold");
    EXIT_ON_ERROR( snd_pcm_sw_params_set_silence_size(pcm, sw_params, 0), MMSYSERR_ERROR, "unable to set silence size");
    EXIT_ON_ERROR( snd_pcm_sw_params_set_avail_min(pcm, sw_params, period_size), MMSYSERR_ERROR, "unable to set avail min");
    EXIT_ON_ERROR( snd_pcm_sw_params_set_silence_threshold(pcm, sw_params, 0), MMSYSERR_ERROR, "unable to set silence threshold");
    EXIT_ON_ERROR( snd_pcm_sw_params(pcm, sw_params), MMSYSERR_ERROR, "unable to set sw params for playback");
#undef EXIT_ON_ERROR

    snd_pcm_prepare(pcm);

    if (TRACE_ON(wave))
	ALSA_TraceParameters(hw_params, sw_params, FALSE);

    /* now, we can save all required data for later use... */

    wwo->dwBufferSize = snd_pcm_frames_to_bytes(pcm, buffer_size);
    wwo->lpQueuePtr = wwo->lpPlayPtr = wwo->lpLoopPtr = NULL;
    wwo->dwPlayedTotal = wwo->dwWrittenTotal = 0;
    wwo->dwPartialOffset = 0;

    ALSA_InitRingMessage(&wwo->msgRing);

    wwo->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD_PTR)wDevID, 0, &(wwo->dwThreadID));
    if (wwo->hThread)
        SetThreadPriority(wwo->hThread, THREAD_PRIORITY_TIME_CRITICAL);
    else
    {
        ERR("Thread creation for the wodPlayer failed!\n");
        CloseHandle(wwo->hStartUpEvent);
        retcode = MMSYSERR_NOMEM;
        goto errexit;
    }
    WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
    CloseHandle(wwo->hStartUpEvent);
    wwo->hStartUpEvent = INVALID_HANDLE_VALUE;

    TRACE("handle=%p\n", pcm);
    TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%u, nSamplesPerSec=%u, nChannels=%u nBlockAlign=%u!\n",
	  wwo->format.Format.wBitsPerSample, wwo->format.Format.nAvgBytesPerSec,
	  wwo->format.Format.nSamplesPerSec, wwo->format.Format.nChannels,
	  wwo->format.Format.nBlockAlign);

    HeapFree( GetProcessHeap(), 0, sw_params );
    wwo->pcm = pcm;
    wwo->hctl = hctl;
    if ( wwo->hw_params )
	snd_pcm_hw_params_free(wwo->hw_params);
    wwo->hw_params = hw_params;

    return wodNotifyClient(wwo, WOM_OPEN, 0L, 0L);

errexit:
    if (pcm)
        snd_pcm_close(pcm);

    if (hctl)
    {
        snd_hctl_free(hctl);
        snd_hctl_close(hctl);
    }

    if ( hw_params )
	snd_pcm_hw_params_free(hw_params);

    HeapFree( GetProcessHeap(), 0, sw_params );
    if (wwo->msgRing.ring_buffer_size > 0)
        ALSA_DestroyRingMessage(&wwo->msgRing);

    return retcode;
}
Esempio n. 28
0
static snd_pcm_t *
alsa_open (int channels, unsigned samplerate, int realtime)
{	const char * device = "default" ;
	snd_pcm_t *alsa_dev = NULL ;
	snd_pcm_hw_params_t *hw_params ;
	snd_pcm_uframes_t buffer_size ;
	snd_pcm_uframes_t alsa_period_size, alsa_buffer_frames ;
	snd_pcm_sw_params_t *sw_params ;

	int err ;

	if (realtime)
	{	alsa_period_size = 256 ;
		alsa_buffer_frames = 3 * alsa_period_size ;
		}
	else
	{	alsa_period_size = 1024 ;
		alsa_buffer_frames = 4 * alsa_period_size ;
		} ;

	if ((err = snd_pcm_open (&alsa_dev, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
	{	fprintf (stderr, "cannot open audio device \"%s\" (%s)\n", device, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	snd_pcm_nonblock (alsa_dev, 0) ;

	if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0)
	{	fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_any (alsa_dev, hw_params)) < 0)
	{	fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_access (alsa_dev, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{	fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_format (alsa_dev, hw_params, SND_PCM_FORMAT_FLOAT)) < 0)
	{	fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_rate_near (alsa_dev, hw_params, &samplerate, 0)) < 0)
	{	fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_channels (alsa_dev, hw_params, channels)) < 0)
	{	fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_buffer_size_near (alsa_dev, hw_params, &alsa_buffer_frames)) < 0)
	{	fprintf (stderr, "cannot set buffer size (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_period_size_near (alsa_dev, hw_params, &alsa_period_size, 0)) < 0)
	{	fprintf (stderr, "cannot set period size (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params (alsa_dev, hw_params)) < 0)
	{	fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	/* extra check: if we have only one period, this code won't work */
	snd_pcm_hw_params_get_period_size (hw_params, &alsa_period_size, 0) ;
	snd_pcm_hw_params_get_buffer_size (hw_params, &buffer_size) ;
	if (alsa_period_size == buffer_size)
	{	fprintf (stderr, "Can't use period equal to buffer size (%lu == %lu)", alsa_period_size, buffer_size) ;
		goto catch_error ;
		} ;

	snd_pcm_hw_params_free (hw_params) ;

	if ((err = snd_pcm_sw_params_malloc (&sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params_malloc: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_sw_params_current (alsa_dev, sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params_current: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	/* note: set start threshold to delay start until the ring buffer is full */
	snd_pcm_sw_params_current (alsa_dev, sw_params) ;

	if ((err = snd_pcm_sw_params_set_start_threshold (alsa_dev, sw_params, buffer_size)) < 0)
	{	fprintf (stderr, "cannot set start threshold (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_sw_params (alsa_dev, sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	snd_pcm_sw_params_free (sw_params) ;

	snd_pcm_reset (alsa_dev) ;

catch_error :

	if (err < 0 && alsa_dev != NULL)
	{	snd_pcm_close (alsa_dev) ;
		return NULL ;
		} ;

	return alsa_dev ;
} /* alsa_open */
Esempio n. 29
0
/*****************************************************************************
 * Open: create a handle and open an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API.
 *
 * Note: the only heap-allocated string is psz_device. All the other pointers
 * are references to psz_device or to stack-allocated data.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    vlc_value_t val;

    char psz_default_iec_device[128]; /* Buffer used to store the default
                                         S/PDIF device */
    char * psz_device, * psz_iec_device; /* device names for PCM and S/PDIF
                                            output */

    int i_vlc_pcm_format; /* Audio format for VLC's data */
    int i_snd_pcm_format; /* Audio format for ALSA's data */

    snd_pcm_uframes_t i_buffer_size = 0;
    snd_pcm_uframes_t i_period_size = 0;
    int i_channels = 0;

    snd_pcm_hw_params_t *p_hw;
    snd_pcm_sw_params_t *p_sw;

    int i_snd_rc = -1;
    unsigned int i_old_rate;
    bool b_retry = true;

    /* Allocate structures */
    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    /* Get device name */
    if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
        dialog_Fatal( p_aout, _("No Audio Device"), "%s",
                        _("No audio device name was given. You might want to " \
                          "enter \"default\".") );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Choose the IEC device for S/PDIF output:
       if the device is overriden by the user then it will be the one
       otherwise we compute the default device based on the output format. */
    if( AOUT_FMT_NON_LINEAR( &p_aout->output.output )
        && !strcmp( psz_device, DEFAULT_ALSA_DEVICE ) )
    {
        snprintf( psz_default_iec_device, sizeof(psz_default_iec_device),
                  "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
                  IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO,
                  IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
                  0,
                  ( p_aout->output.output.i_rate == 48000 ?
                    IEC958_AES3_CON_FS_48000 :
                    ( p_aout->output.output.i_rate == 44100 ?
                      IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000 ) ) );
        psz_iec_device = psz_default_iec_device;
    }
    else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        psz_iec_device = psz_device;
    }
    else
    {
        psz_iec_device = NULL;
    }

    /* Choose the linear PCM format (read the comment above about FPU
       and float32) */
    if( HAVE_FPU )
    {
        i_vlc_pcm_format = VLC_CODEC_FL32;
        i_snd_pcm_format = SND_PCM_FORMAT_FLOAT;
    }
    else
    {
        i_vlc_pcm_format = VLC_CODEC_S16N;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
    }

    /* If the variable doesn't exist then it's the first time we're called
       and we have to probe the available audio formats and channels */
    if ( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout, psz_device, psz_iec_device, &i_snd_pcm_format );
    }

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

    p_aout->output.output.i_format = i_vlc_pcm_format;
    if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
        free( psz_device );
        psz_device = strdup( "surround51" );
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
        free( psz_device );
        psz_device = strdup( "surround40" );
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else if( val.i_int != AOUT_VAR_SPDIF )
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int );
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

#ifdef ALSA_DEBUG
    snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 );
#endif

    /* Open the device */
    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iec_device,
                            SND_PCM_STREAM_PLAYBACK, 0 ) ) < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_iec_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_iec_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }
        i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
        i_channels = 2;

        i_vlc_pcm_format = VLC_CODEC_SPDIFL;
        p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;

        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        int i;

        msg_Dbg( p_aout, "opening ALSA device `%s'", psz_device );

        /* Since it seems snd_pcm_close hasn't really released the device at
          the time it returns, probe if the device is available in loop for 1s.
          We cannot use blocking mode since the we would wait indefinitely when
          switching from a dmx device to surround51. */

        for( i = 10; i >= 0; i-- )
        {
            if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device,
                   SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY )
            {
                if( i ) msleep( 100000 /* 100ms */ );
                else
                {
                    msg_Err( p_aout, "audio device: %s is already in use",
                              psz_device );
                    dialog_Fatal( p_aout, _("Audio output failed"),
                                    _("The audio device \"%s\" is already in use."),
                                    psz_device );
                }
                continue;
            }
            break;
        }
        if( i_snd_rc < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }

        /* We want blocking mode */
        snd_pcm_nonblock( p_sys->p_snd_pcm, 0 );

        i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE;
        i_channels = aout_FormatNbChannels( &p_aout->output.output );

        p_aout->output.i_nb_samples = i_period_size = ALSA_DEFAULT_PERIOD_SIZE;

        aout_VolumeSoftInit( p_aout );
    }

    /* Free psz_device so that all the remaining data is stack-allocated */
    free( psz_device );

    p_aout->output.pf_play = Play;

    snd_pcm_hw_params_alloca(&p_hw);
    snd_pcm_sw_params_alloca(&p_sw);

    /* Due to some bugs in alsa with some drivers, we need to retry in s16l
       if snd_pcm_hw_params fails in fl32 */
    while ( b_retry )
    {
        b_retry = false;

        /* Get Initial hardware parameters */
        if ( ( i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            msg_Err( p_aout, "unable to retrieve initial hardware parameters (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set format. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
                                                    i_snd_pcm_format ) ) < 0 )
        {
            if( i_snd_pcm_format != SND_PCM_FORMAT_S16 )
            {
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
                                                     p_hw, i_snd_pcm_format );
            }
            if ( i_snd_rc < 0 )
            {
                msg_Err( p_aout, "unable to set stream sample size and "
                     "word order (%s)", snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
        if( i_vlc_pcm_format != VLC_CODEC_SPDIFL )
        switch( i_snd_pcm_format )
        {
        case SND_PCM_FORMAT_FLOAT:
            i_vlc_pcm_format = VLC_CODEC_FL32;
            break;
        case SND_PCM_FORMAT_S16:
            i_vlc_pcm_format = VLC_CODEC_S16N;
            break;
        }
        p_aout->output.output.i_format = i_vlc_pcm_format;

        if ( ( i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw,
                                    SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set interleaved stream format (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set channels. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw,
                                                      i_channels ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set number of output channels (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set rate. */
        i_old_rate = p_aout->output.output.i_rate;
        i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw,
                                                &p_aout->output.output.i_rate,
                                                NULL );
        if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate )
        {
            msg_Warn( p_aout, "The rate %d Hz is not supported by your " \
                "hardware. Using %d Hz instead.\n", i_old_rate, \
                p_aout->output.output.i_rate );
        }

        /* Set period size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_period_size, NULL ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set period size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }
        p_aout->output.i_nb_samples = i_period_size;

/* Set buffer size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_buffer_size ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set buffer size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Commit hardware parameters. */
        if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            if ( b_retry == false &&
                                i_snd_pcm_format == SND_PCM_FORMAT_FLOAT)
            {
                b_retry = true;
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                p_aout->output.output.i_format = VLC_CODEC_S16N;
                msg_Warn( p_aout, "unable to commit hardware configuration "
                                  "with fl32 samples. Retrying with s16l (%s)",                                     snd_strerror( i_snd_rc ) );
            }
            else
            {
                msg_Err( p_aout, "unable to commit hardware configuration (%s)",
                         snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
    }

    if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw,
                                    &p_sys->i_period_time, NULL ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get period time (%s)",
                         snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Get Initial software parameters */
    snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw );

    i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 );

    i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw,
                                                p_aout->output.i_nb_samples );
    /* start playing when one period has been written */
    i_snd_rc = snd_pcm_sw_params_set_start_threshold( p_sys->p_snd_pcm, p_sw,
                                                      ALSA_DEFAULT_PERIOD_SIZE);
    if( i_snd_rc < 0 )
    {
        msg_Err( p_aout, "unable to set start threshold (%s)",
                          snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Commit software parameters. */
    if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 )
    {
        msg_Err( p_aout, "unable to set software configuration" );
        goto error;
    }

#ifdef ALSA_DEBUG
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA hardware setup:\n\n" );
    snd_pcm_dump_hw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA software setup:\n\n" );
    snd_pcm_dump_sw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\n" );
#endif

    p_sys->start_date = 0;
    vlc_sem_init( &p_sys->wait, 0 );

    /* Create ALSA thread and wait for its readiness. */
    if( vlc_clone( &p_sys->thread, ALSAThread, p_aout,
                   VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create ALSA thread (%m)" );
        vlc_sem_destroy( &p_sys->wait );
        goto error;
    }

    return 0;

error:
    snd_pcm_close( p_sys->p_snd_pcm );
#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif
    free( p_sys );
    return VLC_EGENERIC;
}
Esempio n. 30
0
int Audio_Initialize(int mod) 
{
#if 0
	capture_handle = NULL;
	int i,err;
	short buf[128];
	char  alsa_device[80];
	snd_pcm_t *capture_handle;
	snd_pcm_hw_params_t *hw_params;
	unsigned int rate = 44100;

	
	sprintf(alsa_device,"plughw:0,0");
	
	//try to open up 
	if ((err = snd_pcm_open (&capture_handle, alsa_device, 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, &rate, 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);
#endif
	return 0;
}