Exemplo n.º 1
0
internal
void hhxcb_init_alsa(hhxcb_context *context, hhxcb_sound_output *sound_output)
{
    // NOTE: "hw:0,0" doesn't seem to work with alsa running on top of pulseaudio
    char *device = (char *)"default";
    // char *device = (char *)"hw:0,0";

    int err;
    snd_pcm_sframes_t frames;
    err = snd_output_stdio_attach(&context->alsa_log, stderr, 0);

    if ((err = snd_pcm_open(&context->handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
    {
            printf("Playback open error: %s\n", snd_strerror(err));
            exit(EXIT_FAILURE);
    }

    snd_pcm_hw_params_t *hwparams;
    snd_pcm_hw_params_alloca(&hwparams);

    snd_pcm_hw_params_any(context->handle, hwparams);
    snd_pcm_hw_params_set_rate_resample(context->handle, hwparams, 0);
    snd_pcm_hw_params_set_access(context->handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(context->handle, hwparams, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_channels(context->handle, hwparams, 2);
    snd_pcm_hw_params_set_rate(context->handle, hwparams, sound_output->samples_per_second, 0);
    snd_pcm_hw_params_set_period_size(context->handle, hwparams, sound_output->samples_per_second / 60, 0);
    // NOTE: restricting this buffer size too much seems to crash the game
    sound_output->secondary_buffer_size = 48000 / 2;
    snd_pcm_hw_params_set_buffer_size(context->handle, hwparams, sound_output->secondary_buffer_size);
    snd_pcm_hw_params(context->handle, hwparams);
    snd_pcm_dump(context->handle, context->alsa_log);
}
Exemplo n.º 2
0
snd_pcm_t *open_pcm(char *pcm_name) {

    snd_pcm_t *playback_handle;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
            
    if (snd_pcm_open (&playback_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        fprintf (stderr, "cannot open audio device %s\n", pcm_name);
        exit (1);
    }
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(playback_handle, hw_params);
    snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, 44100, 0);
    snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
    snd_pcm_hw_params_set_periods(playback_handle, hw_params, 2, 0);
    snd_pcm_hw_params_set_period_size(playback_handle, hw_params, BUFSIZE, 0);
    snd_pcm_hw_params(playback_handle, hw_params);
    snd_pcm_sw_params_alloca(&sw_params);
    snd_pcm_sw_params_current(playback_handle, sw_params);
    snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, BUFSIZE);
    snd_pcm_sw_params(playback_handle, sw_params);
    return(playback_handle);
}
Exemplo n.º 3
0
void mixer_open()
{
	memset(&channels, 0, sizeof(channels));
	int err = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if (err < 0)
	{
		printf("Failed to open pcm device: %s\n", snd_strerror(err));
		exit(1);
	}
	
	unsigned int rate = 44100;
	snd_pcm_hw_params_t *hw_params = 0;
	snd_pcm_hw_params_alloca(&hw_params);
	snd_pcm_hw_params_any(pcm, hw_params);
	snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
	snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16_LE);
	snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, 0);
	snd_pcm_hw_params_set_channels(pcm, hw_params, 2);
	snd_pcm_hw_params_set_period_size(pcm, hw_params, BUFFER_SIZE, 0);
	snd_pcm_hw_params_set_buffer_size(pcm, hw_params, BUFFER_SIZE * 4);
	
	err = snd_pcm_hw_params(pcm, hw_params);
	if (err < 0)
	{
		printf("Failed to apply pcm hardware settings: %s\n", snd_strerror(err));
		exit(1);
	}
	
	snd_pcm_sw_params_t *sw_params = 0;
	snd_pcm_sw_params_alloca(&sw_params);
	snd_pcm_sw_params_current(pcm, sw_params);
	snd_pcm_sw_params_set_avail_min(pcm, sw_params, BUFFER_SIZE * 4);
	err = snd_pcm_sw_params(pcm, sw_params);
	if (err < 0)
	{
		printf("Failed to apply pcm software settings: %s\n", snd_strerror(err));
		exit(1);
	}
	
	err = snd_pcm_prepare(pcm);
	if (err < 0)
	{
		printf("Failed to prepare pcm interface: %s\n", snd_strerror(err));
		exit(1);
	}
	
	memset(delay_left, 0, sizeof(delay_left));
	memset(delay_right, 0, sizeof(delay_right));
}
Exemplo n.º 4
0
static int setup_params(void)
{
	snd_pcm_hw_params_t *hw;

	/* FIXME: more finer error checks */
	snd_pcm_hw_params_alloca(&hw);
	snd_pcm_hw_params_any(pcm, hw);
	snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(pcm, hw, format);
	snd_pcm_hw_params_set_channels(pcm, hw, channels);
	snd_pcm_hw_params_set_rate(pcm, hw, rate, 0);
	snd_pcm_hw_params_set_period_size(pcm, hw, periodsize, 0);
	snd_pcm_hw_params_set_buffer_size(pcm, hw, bufsize);
	if (snd_pcm_hw_params(pcm, hw) < 0) {
		fprintf(stderr, "snd_pcm_hw_params error\n");
		return 1;
	}
	return 0;
}
Exemplo n.º 5
0
int audio_drv_init(void)
{
	unsigned int rate = 44100;
	int err;
	snd_pcm_hw_params_t *hw_params;

	if ((err = snd_pcm_open(&playback_handle, "hw", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
		return -1;

	if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
		return -2;

	if ((err = snd_pcm_hw_params_any(playback_handle, hw_params)) < 0)
		return -3;

	if ((err = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
		return -4;

	if ((err = snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0)
		return -5;

	if ((err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &rate, 0)) < 0)
		return -6;

	if ((err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2)) < 0)
		return -7;

	if ((err = snd_pcm_hw_params_set_period_size(playback_handle, hw_params, 4096, 0)) < 0)
		return -8;

	if ((err = snd_pcm_hw_params_set_periods(playback_handle, hw_params, 4, 0)) < 0)
		return -9;

	if ((err = snd_pcm_hw_params(playback_handle, hw_params)) < 0)
		return -10;

	snd_pcm_hw_params_free(hw_params);

	if ((err = snd_pcm_prepare(playback_handle)) < 0)
		return -11;

	return 0;
}
Exemplo n.º 6
0
snd_pcm_t *open_pcm(char *pcm_name) {
    snd_pcm_t *playback_handle;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
    if (snd_pcm_open (&playback_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        fprintf (stderr, "cannot open audio device %s\n", pcm_name);
      return NULL;//it seems greedy and wants exclusive control?!
    }
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(playback_handle, hw_params);
    snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &rate, 0);
    snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
    snd_pcm_hw_params_set_periods(playback_handle, hw_params, 2, 0);
    snd_pcm_hw_params_set_period_size(playback_handle, hw_params, BUFSAMPS, 0);
    snd_pcm_hw_params(playback_handle, hw_params);
    snd_pcm_sw_params_alloca(&sw_params);
    snd_pcm_sw_params_current(playback_handle, sw_params);
    snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, BUFSAMPS);
    snd_pcm_sw_params(playback_handle, sw_params);
    return(playback_handle);
}
Exemplo n.º 7
0
static int capture(lua_State *lstate) {
	char *card;
	snd_pcm_sw_params_t *sparams;
	int ret, dir, i;
	snd_pcm_format_t f, format;
	unsigned int rate, buffer_time;
	if (rbuf == NULL) {
		rbuf = new_ringbuf(jack_sr, CHANNELS, BUFSECS,
					0.333, 0.667);
		}
	getstring(lstate, "card", &card);
	lua_pop(lstate, 1);
	for (i = 0; i < 20; i++) {
		ret = snd_pcm_open(&handle, card, SND_PCM_STREAM_CAPTURE, 0);
		if (ret < 0) {
			logmsg("can't open %s (%s)\n", card, snd_strerror(ret));
			}
		else {
			break;
			}
		}
	free(card);
	if (ret < 0) return 0;
	if (hparams != NULL) snd_pcm_hw_params_free(hparams);
	snd_pcm_hw_params_malloc(&hparams);
	snd_pcm_hw_params_any(handle, hparams);
	for (f = format = 0; f < SND_PCM_FORMAT_LAST; f++) {
		ret = snd_pcm_hw_params_test_format(handle, hparams, f);
		if (ret == 0) {
			logmsg("- %s\n", snd_pcm_format_name(f));
			format = f;
			}
		}
	ret = snd_pcm_hw_params_set_access(handle, hparams,
				SND_PCM_ACCESS_RW_INTERLEAVED);
	if (ret < 0) {
		logmsg("access %s\n", snd_strerror(ret));
		}
	ret = snd_pcm_hw_params_set_format(handle, hparams, format);
	logmsg("format: %s\n", snd_pcm_format_description(format));
	if (ret < 0) {
		logmsg("format error %s\n", snd_strerror(ret));
		}
	snd_pcm_hw_params_get_buffer_time_max(hparams, &buffer_time, 0);
	rate = jack_sr;
	ret = snd_pcm_hw_params_set_rate(handle, hparams, rate, 0);
logmsg("rate %d\n", rate);
	if (ret < 0) logmsg("rate error %s\n", snd_strerror(ret));
	snd_pcm_hw_params_set_channels(handle, hparams, CHANNELS);
	blocksize = BLOCKSIZE;
	snd_pcm_hw_params_set_period_size(handle, hparams, blocksize, 0);
logmsg("period %ld\n", blocksize);
	snd_pcm_hw_params_set_buffer_time_near(handle, hparams, &buffer_time, &dir);
logmsg("buffer time %u\n", buffer_time);
	if ((ret = snd_pcm_hw_params(handle, hparams)) < 0) {
		logmsg("can't set hardware: %s\n",
			snd_strerror(ret));
		return 0;
		}
	else logmsg("hardware configd\n");
	snd_pcm_sw_params_malloc(&sparams);
	snd_pcm_sw_params_current(handle, sparams);
	snd_pcm_sw_params_set_avail_min(handle, sparams, blocksize);
	snd_pcm_sw_params_set_start_threshold(handle, sparams, 0U);
	if ((ret = snd_pcm_sw_params(handle, sparams)) < 0) {
		logmsg("can't set software: %s\n",
			snd_strerror(ret));
		}
	else logmsg("software configd\n");
	snd_pcm_sw_params_free(sparams);
	pthread_create(&thread_id, NULL, dev_thread, NULL);
	return 0;
	}
Exemplo n.º 8
0
pcm_player *pcm_player_init(int framerate, int nchannels, int sampwidth)
{
    pcm_player *player;
    int retval, format, buffsz;
    char *buff, *devname;
    snd_pcm_t *pcm_handle;
    snd_pcm_stream_t stream;
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_uframes_t periodsize;

    // check parameters
    if(nchannels != 1 && nchannels != 2) {
        fprintf(stderr, "error: unsupported channels: %d\n", nchannels);
        return NULL;
    }

    if(sampwidth == 1)
        format = SND_PCM_FORMAT_U8;
    else if(sampwidth == 2)
        format = SND_PCM_FORMAT_S16_LE;
    else if(sampwidth == 3)
        format = SND_PCM_FORMAT_S24_LE;
    else if(sampwidth == 4)
        format = SND_PCM_FORMAT_S32_LE;
    else {
        fprintf(stderr, "error: unsupported sample width: %d\n", sampwidth);
        return NULL;
    }

    // allocate the structure
    player = (pcm_player*)malloc(sizeof(pcm_player));
    if(player == NULL)
        return NULL;


    // open the PCM device in playback mode
    devname = "default";
    stream = SND_PCM_STREAM_PLAYBACK;
    if((retval = snd_pcm_open(&pcm_handle, devname, stream, 0)) < 0) {
        fprintf(stderr, "error: can't PCM device: %s\n", snd_strerror(retval));
        free(player);
        return NULL;
    }

    // allocate parameters object and fill it with default values
    snd_pcm_hw_params_alloca(&hwparams);
    snd_pcm_hw_params_any(pcm_handle, hwparams);

    // set parameters
    if((retval = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf(stderr, "error: can't set interleaved mode: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)) < 0) {
        fprintf(stderr, "error: can't set format: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, nchannels)) < 0) {
        fprintf(stderr, "error: can't set channels: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &framerate, 0)) < 0) {
        fprintf(stderr, "error: can't set rate: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    periodsize = framerate / 10;
    if((retval = snd_pcm_hw_params_set_period_size(pcm_handle, hwparams, periodsize, 0)) < 0) {
        fprintf(stderr, "error: can't set period size: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    // write parameters
    if ((retval = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
        fprintf(stderr, "error: can't set hardware parameters: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

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

    snd_pcm_hw_params_get_channels(hwparams, &nchannels);
    printf("channels: %i ", nchannels);
    if (nchannels == 1)
        printf("(mono)\n");
    else if (nchannels == 2)
        printf("(stereo)\n");

    snd_pcm_hw_params_get_rate(hwparams, &framerate, 0);
    printf("framerate: %d Hz\n", framerate);

    // allocate buffer to hold single period
    snd_pcm_hw_params_get_period_size(hwparams, &periodsize, 0);
    printf("period size: %d\n", periodsize);

    buffsz = sampwidth * nchannels * periodsize;
    printf("buffer size: %d\n", buffsz);

    buff = (char*)malloc(buffsz);
    if(buff == NULL) {
        fprintf(stderr, "error: can't allocate pcm buffer\n");
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    // set player attributes
    player->pcm_handle = pcm_handle;
    player->framerate = framerate;
    player->nchannels = nchannels;
    player->sampwidth = sampwidth;
    player->periodsize = periodsize;
    player->buffersize = buffsz;
    player->buffer = buff;

    return player;
}
Exemplo n.º 9
0
void Float32ToNativeInt32( const float *src, int *dst, unsigned int numToConvert )
{
	const float *src0 = src;
	int *dst0 = dst;
	unsigned int count = numToConvert;
	
	if (count >= 4) {
		// vector -- requires 4+ samples
		ROUNDMODE_NEG_INF
		const __m128 vround = (const __m128) { 0.5f, 0.5f, 0.5f, 0.5f };
		const __m128 vmin = (const __m128) { -2147483648.0f, -2147483648.0f, -2147483648.0f, -2147483648.0f };
		const __m128 vmax = (const __m128) { kMaxFloat32, kMaxFloat32, kMaxFloat32, kMaxFloat32  };
		const __m128 vscale = (const __m128) { 2147483648.0f, 2147483648.0f, 2147483648.0f, 2147483648.0f  };
		__m128 vf0;
		__m128i vi0;
	
#define F32TOLE32(x) \
		vf##x = _mm_mul_ps(vf##x, vscale);			\
		vf##x = _mm_add_ps(vf##x, vround);			\
		vf##x = _mm_max_ps(vf##x, vmin);			\
		vf##x = _mm_min_ps(vf##x, vmax);			\
		vi##x = _mm_cvtps_epi32(vf##x);			\

		int falign = (uintptr_t)src & 0xF;
		int ialign = (uintptr_t)dst & 0xF;
	
		if (falign != 0 || ialign != 0) {
			// do one unaligned conversion
			vf0 = _mm_loadu_ps(src);
			F32TOLE32(0)
			_mm_storeu_si128((__m128i *)dst, vi0);
			
			// and advance such that the destination ints are aligned
			unsigned int n = (16 - ialign) / 4;
			src += n;
			dst += n;
			count -= n;

			falign = (uintptr_t)src & 0xF;
			if (falign != 0) {
				// unaligned loads, aligned stores
				while (count >= 4) {
					vf0 = _mm_loadu_ps(src);
					F32TOLE32(0)
					_mm_store_si128((__m128i *)dst, vi0);
					src += 4;
					dst += 4;
					count -= 4;
				}
				goto VectorCleanup;
			}
		}
	
		while (count >= 4) {
			vf0 = _mm_load_ps(src);
			F32TOLE32(0)
			_mm_store_si128((__m128i *)dst, vi0);
			
			src += 4;
			dst += 4;
			count -= 4;
		}
VectorCleanup:
		if (count > 0) {
			// unaligned cleanup -- just do one unaligned vector at the end
			src = src0 + numToConvert - 4;
			dst = dst0 + numToConvert - 4;
			vf0 = _mm_loadu_ps(src);
			F32TOLE32(0)
			_mm_storeu_si128((__m128i *)dst, vi0);
		}
		RESTORE_ROUNDMODE
		return;
	}
	
	// scalar for small numbers of samples
	if (count > 0) {
		double scale = 2147483648.0, round = 0.5, max32 = 2147483648.0 - 1.0 - 0.5, min32 = 0.;
		ROUNDMODE_NEG_INF
		
		while (count-- > 0) {
			double f0 = *src++;
			f0 = f0 * scale + round;
			int i0 = FloatToInt(f0, min32, max32);
			*dst++ = i0;
		}
		RESTORE_ROUNDMODE
	}
}


void NativeInt32ToFloat32( const int *src, float *dst, unsigned int numToConvert )
{
	const int *src0 = src;
	float *dst0 = dst;
	unsigned int count = numToConvert;

	if (count >= 4) {
		// vector -- requires 4+ samples
#define LEI32TOF32(x) \
	vf##x = _mm_cvtepi32_ps(vi##x); \
	vf##x = _mm_mul_ps(vf##x, vscale); \
		
		const __m128 vscale = (const __m128) { 1.0/2147483648.0f, 1.0/2147483648.0f, 1.0/2147483648.0f, 1.0/2147483648.0f  };
		__m128 vf0;
		__m128i vi0;

		int ialign = (uintptr_t)src & 0xF;
		int falign = (uintptr_t)dst & 0xF;
	
		if (falign != 0 || ialign != 0) {
			// do one unaligned conversion
			vi0 = _mm_loadu_si128((__m128i const *)src);
			LEI32TOF32(0)
			_mm_storeu_ps(dst, vf0);
			
			// and advance such that the destination floats are aligned
			unsigned int n = (16 - falign) / 4;
			src += n;
			dst += n;
			count -= n;

			ialign = (uintptr_t)src & 0xF;
			if (ialign != 0) {
				// unaligned loads, aligned stores
				while (count >= 4) {
					vi0 = _mm_loadu_si128((__m128i const *)src);
					LEI32TOF32(0)
					_mm_store_ps(dst, vf0);
					src += 4;
					dst += 4;
					count -= 4;
				}
				goto VectorCleanup;
			}
		}
	
		// aligned loads, aligned stores
		while (count >= 4) {
			vi0 = _mm_load_si128((__m128i const *)src);
			LEI32TOF32(0)
			_mm_store_ps(dst, vf0);
			src += 4;
			dst += 4;
			count -= 4;
		}
		
VectorCleanup:
		if (count > 0) {
			// unaligned cleanup -- just do one unaligned vector at the end
			src = src0 + numToConvert - 4;
			dst = dst0 + numToConvert - 4;
			vi0 = _mm_loadu_si128((__m128i const *)src);
			LEI32TOF32(0)
			_mm_storeu_ps(dst, vf0);
		}
		return;
	}
	// scalar for small numbers of samples
	if (count > 0) {
		double scale = 1./2147483648.0f;
		while (count-- > 0) {
			int i = *src++;
			double f = (double)i * scale;
			*dst++ = f;
		}
	}
}

int alsa_set_hwparams(alsa_dev_t *dev, 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 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, dev->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, dev->channels);
  if (err < 0) {
    printf("Channels count (%d) not available for playbacks: %s\n", dev->channels, snd_strerror(err));
    return err;
  }
  /* set the stream rate */
  rrate = dev->rate;
  err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
  if (err < 0) {
    printf("Rate %d Hz not available for playback: %s\n", dev->rate, snd_strerror(err));
    return err;
  }
  if (rrate != dev->rate) {
    printf("Rate doesn't match (requested %dHz, get %dHz)\n", dev->rate, rrate);
    return -EINVAL;
  }
  
  /* set the period size */
  err = snd_pcm_hw_params_set_period_size(handle, params, dev->period_size, 0);
  if (err < 0) {
    printf("Unable to set period size %d for playback: %s\n", (int)dev->period_size, 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;
  }
  
  if (dev->period_size != size) {
    printf("Period size doesn't match (requested %d, got %d)\n", (int)dev->period_size, (int)size);
    return -EINVAL;
  }
  
    /* set the buffer size */
  err = snd_pcm_hw_params_set_buffer_size(handle, params, dev->buffer_size);
  if (err < 0) {
    printf("Unable to set buffer size %d for playback: %s\n", (int)dev->buffer_size, 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;
  }
  
  if (size != (snd_pcm_uframes_t)dev->buffer_size) {
    printf("Buffer size doesn't match (requested %d, got %d)\n", (int)dev->buffer_size, (int)size);
    return -EINVAL;
  }

  /* 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;
}

int alsa_set_swparams(alsa_dev_t *dev, snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
{
  int err;
  
  /* get the current swparams */
  err = snd_pcm_sw_params_current(handle, swparams);
  if (err < 0) {
    printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
    return err;
  }
  /* allow the transfer when at least period_size samples can be processed */
  /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
  err = snd_pcm_sw_params_set_avail_min(handle, swparams, dev->period_size);
  if (err < 0) {
    printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
    return err;
  }
  /* enable period events */
  err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
  if (err < 0) {
    printf("Unable to set period event: %s\n", snd_strerror(err));
    return err;
  }

  /* write the parameters to the playback device */
  err = snd_pcm_sw_params(handle, swparams);
  if (err < 0) {
    printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
    return err;
  }
  return 0;
}
Exemplo n.º 10
0
static int audio_configure(snd_pcm_t *device) {
  snd_pcm_hw_params_t *hw_params;
  int err;
  unsigned int sr = SAMPLE_RATE;

  err = snd_pcm_hw_params_malloc(&hw_params);
  if (err) {
    fprintf(stderr, "can't allocate hw_params: %s\n", snd_strerror(err));
    return err;
  }

  err = snd_pcm_hw_params_any(device, hw_params);
  if (err) {
    fprintf(stderr, "can't initialize hw_params: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params_set_access(device, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err) {
    fprintf(stderr, "can't set access mode: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params_set_format(device, hw_params, SND_PCM_FORMAT_S16_LE);
  if (err) {
    fprintf(stderr, "can't set format: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params_set_rate_near(device, hw_params, &sr, 0);
  if (err) {
    fprintf(stderr, "can't set samplerate: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params_set_channels(device, hw_params, 1);
  if (err) {
    fprintf(stderr, "can't set channels: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }
  
  err = snd_pcm_hw_params_set_buffer_size(device, hw_params, BUFFER_SIZE);
  if (err) {
    fprintf(stderr, "can't set buffer size: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params_set_period_size(device, hw_params, PERIOD_SIZE, 0);
  if (err) {
    fprintf(stderr, "can't set period size: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  err = snd_pcm_hw_params(device, hw_params);
  if (err) {
    fprintf(stderr, "can't set hw params: %s\n", snd_strerror(err));
    snd_pcm_hw_params_free(hw_params);
    return err;
  }

  snd_pcm_hw_params_free(hw_params);
  return 0;
}
Exemplo n.º 11
0
static int set_hwparams(snd_pcm_t *handle,
snd_pcm_hw_params_t *params,
snd_pcm_access_t access)
{
    unsigned int rrate;
    int err;
    /* 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, 0);
    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(handle, params, rate, 0);
    if (err < 0) {
        printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
        return err;
    }


    err = snd_pcm_hw_params_set_buffer_size(handle, params, BUFFER_SIZE);
    if (err < 0) {
        printf("Unable to set buffer size %lu for playback: %s\n", PERIOD_SIZE, snd_strerror(err));
        return err;
    }

    int dir;
    err = snd_pcm_hw_params_set_period_size(handle, params, PERIOD_SIZE, 0);
    if (err < 0) {
        printf("Unable to set period size %lu for playback: %s\n", PERIOD_SIZE, snd_strerror(err));
        return err;
    }

    /* 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;
}
Exemplo n.º 12
0
static SCM open_card(SCM device) {
	// soundcard acquisition and configuration
	char *dname;
	snd_pcm_t *handle;
	ALSA_CARD *card;
	snd_pcm_sw_params_t *sparams;
	SOURCE_HANDLE *src;
	snd_pcm_format_t f, format;
	SCM smob;
	int i, ret, dir;
	unsigned int rate, buffer_time;
	dname = scm_to_locale_string(device);
	for (i = 0; i < 10; i++) {
		ret = snd_pcm_open(&handle, dname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
		if (ret >= 0) break;
		}
	if (ret < 0) {
		log_msg("ALSA: can't open %s (%s)\n", dname, snd_strerror(ret));
		free(dname);
		return SCM_BOOL_F;
		}
	card = (ALSA_CARD *)my_malloc(sizeof(ALSA_CARD), "alsa card");
	card->device = dname;
	card->name = card_name(card->device);
	card->ringbuf = NULL;
	init_source(&card->base);
	card->handle = handle;
	card->running = 0;
	snd_pcm_hw_params_malloc(&card->hparams);
	snd_pcm_hw_params_any(card->handle, card->hparams);
	for (f = format = 0; f < SND_PCM_FORMAT_LAST; f++) {
		ret = snd_pcm_hw_params_test_format(card->handle, card->hparams, f);
		if (ret == 0) {
			log_msg("ALSA: - %s\n", snd_pcm_format_name(f));
			format = f;
			}
		}
	ret = snd_pcm_hw_params_set_access(card->handle, card->hparams,
				SND_PCM_ACCESS_RW_INTERLEAVED);
	if (ret < 0) log_msg("ALSA: access %s\n", snd_strerror(ret));
	ret = snd_pcm_hw_params_set_format(card->handle, card->hparams, format);
	log_msg("ALSA: format: %s\n", snd_pcm_format_description(format));
	if (ret < 0) log_msg("ALSA: format error %s\n", snd_strerror(ret));
	snd_pcm_hw_params_get_buffer_time_max(card->hparams, &buffer_time, 0);
	rate = sampling_rate;
	ret = snd_pcm_hw_params_set_rate(card->handle, card->hparams, rate, 0);
	log_msg("ALSA: rate %d\n", rate);
	if (ret < 0) log_msg("ALSA: rate error %s\n", snd_strerror(ret));
	snd_pcm_hw_params_set_channels(card->handle, card->hparams,
						QMX_CHANNELS);
	card->blocksize = BLOCKSIZE;
	snd_pcm_hw_params_set_period_size(card->handle, card->hparams,
					card->blocksize, 0);
	log_msg("ALSA: period %ld\n", card->blocksize);
	snd_pcm_hw_params_set_buffer_time_near(card->handle, card->hparams,
					&buffer_time, &dir);
	log_msg("ALSA: buffer time %u\n", buffer_time);
	if ((ret = snd_pcm_hw_params(card->handle, card->hparams)) < 0) {
		log_msg("ALSA: can't set hardware: %s\n", snd_strerror(ret));
		close_card(card);
		return SCM_BOOL_F;
		}
	else log_msg("ALSA: hardware configd\n");
	snd_pcm_sw_params_malloc(&sparams);
	snd_pcm_sw_params_current(card->handle, sparams);
	snd_pcm_sw_params_set_avail_min(card->handle, sparams, card->blocksize);
	snd_pcm_sw_params_set_start_threshold(card->handle, sparams, 0U);
	if ((ret = snd_pcm_sw_params(card->handle, sparams)) < 0) {
		log_msg("ALSA: can't set software: %s\n", snd_strerror(ret));
		}
	else log_msg("ALSA: software configd\n");
	snd_pcm_sw_params_free(sparams);
	card->link = cards;
	cards = card;
	src = (SOURCE_HANDLE *)my_gc_malloc(sizeof(SOURCE_HANDLE), "alsa_card",
				"alsa card handle");
	src->body = (void *)card;
	src->src = &card->base;
	log_msg("ALSA: opened %s '%s'\n", card->device, card->name);
	SCM_NEWSMOB(smob, alsa_card_tag, src);
	return smob;
	}
Exemplo n.º 13
0
int VPOutPluginAlsa::init(VPlayer *v, VPBuffer *in)
{
    DBG("Alsa:init");
    owner = v;
    bin = in;
    if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE) < 0){
        DBG("Alsa:init: failed to open pcm");
        exit(0);
        return -1;
    }
    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_malloc(&swparams);
    snd_pcm_sw_params_current (handle, swparams);
    snd_pcm_sw_params_set_start_threshold (handle, swparams, VPBUFFER_FRAMES - PERIOD_SIZE);
    snd_pcm_sw_params (handle, swparams);
    snd_pcm_sw_params_free(swparams);

    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(handle, params);
    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_format_mask_t *mask;
    snd_pcm_format_mask_alloca(&mask);
    snd_pcm_hw_params_get_format_mask(params, mask);
    if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S32))
    {
        DBG("bit depth is 32");
        snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S32);
        multiplier = (1<<31) -1 ;
        DBG(multiplier);
    }
    else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S24))
    {
        DBG("bit depth is 24");
        snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S24);
        multiplier = (1<<23) -1;
    }
    else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S16))
    {
        DBG("bit depth is 16");
        snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16);
        multiplier = (1<<15) -1;
    }
    else if (snd_pcm_format_mask_test(mask, SND_PCM_FORMAT_S8))
    {
        DBG("bit depth is 8");
        snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S8);
        multiplier = (1<<7) -1;;
    }

    snd_pcm_hw_params_set_channels(handle, params, bin->chans);

    snd_pcm_hw_params_set_period_size(handle, params, PERIOD_SIZE, 0);

    if (snd_pcm_hw_params(handle, params) < 0) {
        DBG("Alsa:init: failed to set pcm params");
       return -1;
    }

    snd_pcm_hw_params_current(handle, params);
    int dir;
    snd_pcm_hw_params_get_rate(params, &out_srate, &dir);
    in_srate = bin->srate;
    int rerr;
    rs = src_new(SRC_SINC_FASTEST, bin->chans, &rerr);
    if (!rs){
        DBG("SRC error"<<rerr);
        return -1;
    }

    rd.src_ratio = (out_srate*1.0)/(in_srate*1.0);
    out_frames = (VPBUFFER_FRAMES*rd.src_ratio)*2;

    out_buf = (float *)ALIGNED_ALLOC(sizeof(float)*out_frames*bin->chans);
    out_buf_i = (int *)ALIGNED_ALLOC(sizeof(int)*out_frames*bin->chans);

    DBG("target rate "<<out_srate);
    work = true;
    paused = false;
    pause_check = false;

    FULL_MEMORY_BARRIER;
    in_fd = inotify_init();
    if ( in_fd < 0 ) {
        DBG("error initializing inotify, auto pause won't work");
    } else {
        in_wd[0]=inotify_add_watch( in_fd, "/dev/snd/pcmC0D0p", IN_OPEN | IN_CLOSE );
    }
    fcntl(in_fd, F_SETFL, O_NONBLOCK);

    worker = new std::thread((void(*)(void*))worker_run, this);
    worker->high_priority();
    DBG("alsa thread made");
    DBG((void *)VPOutPluginAlsa::check_contention);
    VPEvents::getSingleton()->schedulerAddJob((VPEvents::VPJob) VPOutPluginAlsa::check_contention, this,0);
    return 0;
}
Exemplo n.º 14
0
static int init_recording(rec_ctx *ctx) {

    int err;
    snd_pcm_hw_params_t *hw_params = 0;
    snd_pcm_uframes_t frames = 512;
    struct stat st;

	if(stat(alsa_config_file, &st) == 0) {
	     if(strstr(alsa_config_file, ".conf")) {	
		char *cmd = malloc(strlen(alsa_config_file)+strlen(ALSA_CTL_CMD)+32);	
		sprintf(cmd, "%s -f %s restore", ALSA_CTL_CMD, alsa_config_file);	
		if(system(cmd) == -1) log_err("failed to execute alsa_ctl");
		else log_info("live recording configuration loaded");
		free(cmd);
	     } else {
		FILE *file = fopen(alsa_config_file, "r");
		if(file) {
		    do_mixer_settings(file);
		    fclose(file);
		} else log_err("failed to open %s", alsa_config_file);
	     }	
	} else log_info("%s not found, skipped loading live config", alsa_config_file);

	if((err = snd_pcm_open(&ctx->snd, alsa_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
	     log_err("cannot open audio device %s (%s)", alsa_device, snd_strerror(err));
	     return 0;
	}
	if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
	     log_err("cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_any(ctx->snd, hw_params)) < 0) {
	     log_err("cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_set_access(ctx->snd, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
	     log_err("cannot set access type (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_set_format(ctx->snd, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
	     log_err("cannot set sample format (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_set_rate(ctx->snd, hw_params, 8000, 0)) < 0) {
	     log_err("cannot set sample rate (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_set_channels(ctx->snd, hw_params, 1)) < 0) {
	     log_err("cannot set channel count (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	if((err = snd_pcm_hw_params_set_period_size(ctx->snd, hw_params, frames, 0)) < 0) {
	     log_err("cannot set period size (%s)\n", snd_strerror(err));
#if 0
	     goto fail;
#endif		     	
	}
	if((err = snd_pcm_hw_params(ctx->snd, hw_params)) < 0) {
	     log_err("cannot set parameters (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	snd_pcm_hw_params_free(hw_params);
	hw_params = 0;
	ctx->frames = frames;
	ctx->buff = (char *) malloc(frames * 2);
	if(!ctx->buff) {
	     log_err("out of memory, size requested = %ld", frames*2);
	     goto fail;		
	}	
	if((err = snd_pcm_prepare(ctx->snd)) < 0) {
	     log_err("cannot prepare audio interface for use (%s)\n", snd_strerror(err));
	     goto fail;		     	
	}
	ctx->fd_out = open(ctx->cur_file,O_CREAT|O_TRUNC|O_WRONLY, 0666);
	if(ctx->fd_out < 0) {
	    log_err("cannot open output file \'%s\'", ctx->cur_file); 
	    goto fail;
	}
	return 1;

   fail:
	if(hw_params) snd_pcm_hw_params_free(hw_params);
	if(ctx->snd) snd_pcm_close(ctx->snd);
	return 0;
}