Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Alsa,无法按顺序播放同一曲目两次_C_Alsa_Libsndfile - Fatal编程技术网

C Alsa,无法按顺序播放同一曲目两次

C Alsa,无法按顺序播放同一曲目两次,c,alsa,libsndfile,C,Alsa,Libsndfile,我开发了一些代码来播放音频(波形文件)。当我尝试播放同一个文件两次时,第一次播放效果很好,但第二次调用时总是失败 下面是一次性音频初始化功能 /* PCM interface objects */ static snd_pcm_t *pcm_handle; static snd_pcm_uframes_t frames; static int rate = 44100, channels = 2; void audio_init(void) { snd_pcm_hw_params_t

我开发了一些代码来播放音频(波形文件)。当我尝试播放同一个文件两次时,第一次播放效果很好,但第二次调用时总是失败

下面是一次性音频初始化功能

/* PCM interface objects */
static snd_pcm_t *pcm_handle;
static snd_pcm_uframes_t frames;
static int rate = 44100, channels = 2;

void audio_init(void)
{
    snd_pcm_hw_params_t *params;
    unsigned int pcm = 0;

    /* 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(&params);
    snd_pcm_hw_params_any(pcm_handle, params);

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

    /* Signed 16 bit little-endian format */
    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));

    /* Two channels, stereo */
    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));

    /* 44100 bits/second sampling rate (CD quality) */
    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 to the driver */
    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)));

    int tmp = 0;
    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 large enough buffer to hold single period (No. of samples) */
    snd_pcm_hw_params_get_period_size(params, &frames, 0);
    printf("period size = %d frames\n", (int)frames);

    /* Get the period time */
    snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
    printf("period time = %d us\n", tmp);

    audio_playTrack(AUDIO_HOMING_TRACK);
    sleep(1);
    printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));
    audio_playTrack(AUDIO_ARRIVE_TRACK);
    sleep(1);
    printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));
}


编辑:从音频播放曲目()中删除snd_pcm_drain(),并将snd_pcm_hw_参数设置为音频初始化的本地参数()

文件对象
infle
对于两个调用都是相同的。因此,您第一次到达文件末尾,然后第二次尝试播放时,您仍然处于文件末尾。您需要关闭并重新打开文件,或者在尝试再次播放之前倒带到开头。

文件对象
infle
对于两个调用都是相同的。因此,您第一次到达文件末尾,然后第二次尝试播放时,您仍然处于文件末尾。您需要关闭并重新打开文件,或者在尝试再次播放之前倒带到开头。

在音频播放曲目()中,在空闲后的结尾(buf),我添加了sf_seek(infle,0,seek_SET)以将指针定位回第一个数据样本。但是在添加这一行之后,snd_pcm_writei()失败,出现错误“写入pcm设备时出错:文件描述符处于错误状态”,这可能是因为我猜您已经耗尽了pcm。拆下
snd\u pcm\u排水管
线路,看看会发生什么情况。但总体来说,您使用的是一堆全局变量,我不喜欢这样。此外,我尝试在audio_playTrack()开头打开文件,然后在结尾关闭,但仍然会出现“错误描述符错误”。你对造成这种情况的原因有什么见解吗?你试过我上面说的吗?描述符错误不是关于音频文件,而是关于PCM设备请让我更好地编写代码,通过删除snd_PCM_drain并返回更新和测试。在audio_playTrack()中,在释放后的末尾(buf),我添加了sf_seek(infle,0,seek_SET)以将指针定位回第一个数据样本。但是在添加这一行之后,snd_pcm_writei()失败,出现错误“写入pcm设备时出错:文件描述符处于错误状态”,这可能是因为我猜您已经耗尽了pcm。拆下
snd\u pcm\u排水管
线路,看看会发生什么情况。但总体来说,您使用的是一堆全局变量,我不喜欢这样。此外,我尝试在audio_playTrack()开头打开文件,然后在结尾关闭,但仍然会出现“错误描述符错误”。你对造成这种情况的原因有什么见解吗?你试过我上面说的吗?坏描述符错误不是关于音频文件,而是关于PCM设备请让我更好地编写代码,通过删除snd_PCM_drain进行更新和测试,然后返回。似乎有很多静态错误。此外,有没有任何方法可以避免在audio_playTrack()函数中使用malloc?关于所有全局变量:您知道如何使用函数参数吗?是的,我愿意。从一开始就包括了这些变化。看起来有很多静态的。还有,有没有什么方法可以避免在audio_playTrack()函数中使用malloc?关于所有全局变量:你知道如何使用函数参数吗?是的,我知道。积极地包括这些变化。
void audio_playTrack(char *audioFile)
{
    short int* buf = NULL;
    int readcount = 0;
    int pcmrc;
    SNDFILE *infile = NULL;
    SF_INFO sfinfo;

    infile = sf_open(audioFile, SFM_READ, &sfinfo);

    printf("\r\n");
    printf("[FILE]Channels      : %d\n", sfinfo.channels);
    printf("[FILE]Sample rate   : %d\n", sfinfo.samplerate);
    printf("[FILE]Sections      : %d\n", sfinfo.sections);
    printf("[FILE]Format        : %d\n", sfinfo.format);
    printf("\r\n");

    printf("+------------------\n");
    printf("### AUDIO BEGIN ###\n");
    printf("+------------------\n\n");
    buf = malloc(frames * sfinfo.channels * sizeof(int));
    while ((readcount = sf_readf_short(infile, buf, frames))>0)
    {
        pcmrc = snd_pcm_writei(pcm_handle, buf, readcount);
        if (pcmrc == -EPIPE)
        {
            printf("Underrun!\n");
            snd_pcm_prepare(pcm_handle);
        }
        else if (pcmrc < 0)
        {
            printf("Error writing to PCM device: %s\n", snd_strerror(pcmrc));
        }
        else if (pcmrc != readcount)
        {
            printf("PCM write differs from PCM read.\n");
        }
    }
    printf("+------------------\n");
    printf("### AUDIO END ###\n");
    printf("+------------------\n\n");
    free(buf);
    sf_close (infile);
}
PCM name: 'default'
PCM state: PREPARED
channels: 2 (stereo)
rate: 44100 bps
period size = 940 frames
period time = 21333 us

[FILE]Channels          : 2
[FILE]Sample rate       : 44100
[FILE]Sections          : 1
[FILE]Format            : 65538

+------------------
### AUDIO BEGIN ###
+------------------

+------------------
### AUDIO END ###
+------------------

PCM state: RUNNING

[FILE]Channels          : 2
[FILE]Sample rate       : 44100
[FILE]Sections          : 1
[FILE]Format            : 65538

+------------------
### AUDIO BEGIN ###
+------------------

Underrun!
+------------------
### AUDIO END ###
+------------------