Created
December 6, 2014 18:57
-
-
Save soundlake/6855382657218535daf8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <alsa/asoundlib.h> | |
#include <stdio.h> | |
#define PCM_DEVICE "hw:0,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; | |
FILE* fp; | |
if (argc != 2) { | |
printf("Usage: %s <filename>\n", argv[0]); | |
return -1; | |
} | |
rate = 44100; | |
channels = 2; | |
// file open | |
fp = fopen(argv[1], "r"); | |
if(!fp) { | |
printf("ERROR: Can't open \"%s\"\n", argv[1]); | |
return -1; | |
} | |
/* Open the PCM device in playback mode */ | |
if (pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, | |
SND_PCM_STREAM_PLAYBACK, 0) < 0) | |
printf("ERROR: Can't open \"%s\" PCM device. %s\n", | |
PCM_DEVICE, snd_strerror(pcm)); | |
/* Allocate parameters object and fill it with default values*/ | |
snd_pcm_hw_params_alloca(¶ms); | |
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_S16_LE) < 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); | |
/* 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); | |
snd_pcm_hw_params_get_period_time(params, &tmp, NULL); | |
while(!feof(fp)) { | |
if(pcm = fread(buff, buff_size, 1, fp) == 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); | |
fclose(fp); | |
return 0; | |
} |
Author
soundlake
commented
Dec 6, 2014
- playback 모드로 열고 (snd_pcm_open)
- 세팅
- 열기 (snd_pcm_hw_params_alloca, snd_pcm_hw_params_any)
- 세팅에 r/w 알려주구요 (snd_pcm_hw_params_set_access)
- 세팅에 비트레이트 (snd_pcm_hw_params_set_format)
- 샘플레이트 (snd_pcm_hw_params_set_rate_near)
- 채널 수 알려준다음 (snd_pcm_hw_params_set_channels)
- 설정된 거 적용 (snd_pcm_hw_params)
- 설정 잘 적용됬는지 확인도 해보구요 (snd_pcm_hw_params_get_period_size, snd_pcm_hw_params_get_period_time)
- 음원 재생 (snd_pcm_writei)
- 끝나면 뒷정리 (snd_pcm_hw_params_free, snd_pcm_drain, snd_pcm_close)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment