This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

What may cause audio capture stop in alsa for linux?

HI,TIer.

Now we are using DM8168 DVRRDK to develop video/audio recorder.

However, when we do a 7*24 hours test for our recorder, we encounter a case that audio capture is STOP. XRUN status.

I wanna ask a question:What may cause the audio capture(ALSA) stop?

BR!

  • Hi Young,

    Have you tried with the latest dvr rdk linux kernel code base?
    http://arago-project.org/git/projects/?p=linux-dvr-rdk-dm81xx.git;a=shortlog;h=refs/heads/dvrrdk_kernel_int_branch 

    Usually transmit underruns and receiver overruns due to the system not meeting real-time requirements. It seems MCASP RX FIFO path overflow (overrun). When receiving (capture/record), data must be read from each serializer configured as "active" (active slot in RTDM register) and "receive" (Rx enabled in SCRCTLn register) within each time slot. Failure to do results in a buffer overrun condition. See DM816x TRM, section 14.2.8.4.3 Buffer Overrun Error - Receiver, 14.2.8.4.5 DMA Error - Receiver

    See also DM816x Silicon Errata, Advisory 2.1.107 McASP to EDMA Synchronization Level Event can be Lost

    BR
    Pavel

  • Thanks,we will try that.
  • hi Pavel,

    I want to known if the"XRUN status" is relate to Linux kernel ,could the function "snd_pcm_prepare" recovery alsa to normal;
    and if Linux kernel cause alsa STOP, when I am to readi audio data,could it return error or Blocked(can't return anything)

    I ask this two question because we use alsa function snd_pcm_readi to read audio data and if it return error,we will use snd_pcm_prepare ,but in this case we also encounter “XRUN”,and all the function stop working.

    this is our record code(init & read):

    Int audioCaptureInit(pAudio hdl) {
    	int err;
    	snd_pcm_hw_params_t * hw_params = NULL;
    
    	if (hdl == NULL) {
    		return -1;
    	}
    	if ((err = snd_pcm_open(&hdl->m_audcap_hdl, ALSA_CAPTURE_DEVICE, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
            fprintf (stderr, "AUDIO >>  cannot open audio device %s (%s)\n", ALSA_CAPTURE_DEVICE, snd_strerror (err));
            return  -1;
    	}
    
    	if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    		return  -1;
    	}
    
    	if ((err = snd_pcm_hw_params_any(hdl->m_audcap_hdl, hw_params)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    		return -1;
    	}
    
    	if ((err = snd_pcm_hw_params_set_access(hdl->m_audcap_hdl, hw_params,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	}
    
    	if ((err = snd_pcm_hw_params_set_format(hdl->m_audcap_hdl, hw_params,SND_PCM_FORMAT_S16_LE)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    
    	if ((err = snd_pcm_hw_params_set_rate_near(hdl->m_audcap_hdl, hw_params,&(hdl->audioParames.sampleRate), 0)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    
    	if ((err = snd_pcm_hw_params_set_channels(hdl->m_audcap_hdl, hw_params,hdl->audioParames.channelNums)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    
    	if ((err = snd_pcm_hw_params_set_buffer_size(hdl->m_audcap_hdl, hw_params, AUDIO_CAPTURE_BUFFER_SIZE)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    
    #if 1
    	int dir;
    	snd_pcm_uframes_t size;
    	static snd_pcm_sframes_t buffer_size;
    	static snd_pcm_sframes_t period_size = AUDIO_MAX_IN_FRAMES;
    
    	/* set the period size */
    	err = snd_pcm_hw_params_set_period_size_near(hdl->m_audcap_hdl, hw_params, &period_size, 0);
    	if (err < 0) {
    		printf("Unable to set period size %d for playback: %s\n", period_size, snd_strerror(err));
    		return err;
    	}
    
    	err = snd_pcm_hw_params_get_period_size(hw_params, &size, &dir);
    	if (err < 0) {
    		printf("Unable to get period size for capture: %s\n", snd_strerror(err));
    		return err;
    	}
    	period_size = size;
        OSA_printf("=======================period size====%d====================\n:",size);
    #endif
    
    	if ((err = snd_pcm_hw_params(hdl->m_audcap_hdl, hw_params)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    	snd_pcm_hw_params_free(hw_params);
    	if ((err = snd_pcm_prepare(hdl->m_audcap_hdl)) < 0) {
    		fprintf(stderr,"AUDIO >> audcap_device_init: %s (%s)\n",hdl->m_audcap_hdl,snd_strerror (err));
    	    return -1;
    	}
    	return 0;
    }
    
    Int audioRecord(pAudio hdl, void *buf, Int32 *numFrames) {
    	//return 0 on succeeding
    	int err;
    	Int status = 0;
    
    	err = snd_pcm_readi(hdl->m_audcap_hdl, buf, *numFrames);
    	if (err < 0 || err != *numFrames) {
    		OSA_printf("audio_record: err=%d, Reason: %s\n",err, snd_strerror(err));
    		if (strcmp(snd_strerror(err), "Success")) {
    			OSA_printf("++++++++++++++++FAILED+++++++++++++++++ %s\n");
    		}
                    status = 1;
    		snd_pcm_prepare(hdl->m_audcap_hdl);	
    	}
    	return status;
    }

    look forward to your reply,thanks!

  • Dongmei,

    dongmei ma said:
    I want to known if the"XRUN status" is relate to Linux kernel

    Can you provide me the exact console output/log when you get this "XRUN status" reported?

    dongmei ma said:
    could the function "snd_pcm_prepare" recovery alsa to normal

    ALSA documents states that this function should be called to recover ALSA capture to normal:

    SND_PCM_STATE_XRUN
    The PCM device reached overrun (capture) or underrun (playback). You can use the -EPIPE return code from I/O functions (snd_pcm_writei(), snd_pcm_writen(), snd_pcm_readi(), snd_pcm_readn()) to determine this state without checking the actual state via snd_pcm_state() call. It is recommended to use the helper function snd_pcm_recover() to recover from this state, but you can also use snd_pcm_prepare(), snd_pcm_drop() or snd_pcm_drain() calls.
     
     
     
     

     

    3. PCM capture

    See also if the below wiki pages will be in help:

     
     
    BR
    Pavel
  • hi Pavel,
    Thanks for your reply,the problem we encountered is sporadic,we don't know when it will XRUN,and we don't known what will cause XRUN,and so we can't get any log information.
    we will try to replace Linux kernel firstly,and test it ,thanks