Re: Getting a strange error code with Behringer UMC1820

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 14, 2023 at 11:41:55PM +0100, Sebastien Alaiwan wrote:
> Hi,
> 
> I've been running some experiments on the Behringer UMC1820, which is a USB audio interface, supposedly class-compliant.
> I wrote a tiny program "alsa-sine" that simply plays silence on a given ALSA device ( please find the source for it at the bottom of this message ).
> This tiny program allows to specify the buffer size, and the period size ( Here, I'll always be using a buffer size of 256 ).
> 
> Here, i'm testing 5 values for the period size (the last command line argument). All period sizes work, except ... 127.

Hi Sebastien,

See https://www.alsa-project.org/wiki/FramesPeriods

Common period sizes are 2 or 3 since this is the number of times
the hardware will interrupt per buffer. It's curious behavior you have
found but I don't think it's a bug.

Regards,
Geraldo Nascimento

> See below:
> 
>      $ ./alsa_sine 'hw:CARD=UMC1820,DEV=0' 256 125
>      buffer_size=256 (asked 256), period_size=125 (asked 125), channels=12, format=S24_3LE (24 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=UMC1820,DEV=0' 256 126
>      buffer_size=256 (asked 256), period_size=126 (asked 126), channels=12, format=S24_3LE (24 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=UMC1820,DEV=0' 256 127
>      buffer_size=256 (asked 256), period_size=127 (asked 127), channels=12, format=S24_3LE (24 bpp)
>      [alsa_sine.c:66] error: snd_pcm_drain(pcm) : Input/output error
>      Aborting.
> 
>      $ ./alsa_sine 'hw:CARD=UMC1820,DEV=0' 256 128
>      buffer_size=256 (asked 256), period_size=128 (asked 128), channels=12, format=S24_3LE (24 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=UMC1820,DEV=0' 256 129
>      buffer_size=256 (asked 256), period_size=128 (asked 129), channels=12, format=S24_3LE (24 bpp)
>      OK
> 
> I also own a Virus TI, which also implements an USB audio interface, also supposedly class-compliant.
> So I ran the same test on it, and interestingly, there's no error:
> 
>      $ ./alsa_sine 'hw:CARD=TI,DEV=0' 256 125
>      buffer_size=256 (asked 256), period_size=125 (asked 125), channels=2, format=S16_LE (16 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=TI,DEV=0' 256 126
>      buffer_size=256 (asked 256), period_size=126 (asked 126), channels=2, format=S16_LE (16 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=TI,DEV=0' 256 127
>      buffer_size=256 (asked 256), period_size=127 (asked 127), channels=2, format=S16_LE (16 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=TI,DEV=0' 256 128
>      buffer_size=256 (asked 256), period_size=128 (asked 128), channels=2, format=S16_LE (16 bpp)
>      OK
> 
>      $ ./alsa_sine 'hw:CARD=TI,DEV=0' 256 129
>      buffer_size=256 (asked 256), period_size=128 (asked 129), channels=2, format=S16_LE (16 bpp)
>      OK
> 
> So at this point, I'm wondering if I might be doing something wrong. I'm not trying to achieve anything here other than trying to understand what's going on.
> Maybe the UMC1820 doesn't support a period size of 127 ? ( does it even make sense to say this? ) If so, how is it possible for an application to know about this limitation?
> Maybe my test program is simply incorrect, and it's behavior is undefined? But then, how can we explain the difference in behavior between the UMC1820 and the Virus TI ?
> 
> My kernel version is: Linux ANTEC 6.5.0-5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.5.13-1 (2023-11-29) x86_64 GNU/Linux
> Also, Debian tells me I'm using the package: libasound 1.2.10-1
> 
> BTW, please let me know if this is not the proper mailing list to talk about such things!
> 
> Thanks,
> Sebastien Alaiwan
> 
> 
> 
> 
> 
> 
> //---------------------------------------------------------------
> // gcc alsa_sine.c -lasound
> #include <alsa/asoundlib.h>
> #include <stdio.h>
> 
> const int SampleRate = 48000;
> 
> void checkCall(int ret, const char* expr, const char* file, int line)
> {
>    if(ret < 0)
>    {
>      fprintf(stderr, "[%s:%d] error: %s : %s\nAborting.\n", file, line, expr, snd_strerror(ret));
>      exit(1);
>    }
> }
> 
> #define CHECK_CALL(a) checkCall(a, # a, __FILE__, __LINE__)
> 
> int main(int argc, char* argv[])
> {
>    if(argc != 4)
>    {
>      fprintf(stderr, "Usage: %s <device> <buffer_size> <period_size>\n", argv[0]);
>      return 1;
>    }
> 
>    const char* devName = argv[1];
>    const snd_pcm_uframes_t asked_buffer_size = atoi(argv[2]);
>    const snd_pcm_uframes_t asked_period_size = atoi(argv[3]);
> 
>    snd_pcm_t* pcm = NULL;
>    CHECK_CALL(snd_pcm_open(&pcm, devName, SND_PCM_STREAM_PLAYBACK, 0));
> 
>    snd_pcm_hw_params_t* hw_params = NULL;
>    CHECK_CALL(snd_pcm_hw_params_malloc(&hw_params));
>    CHECK_CALL(snd_pcm_hw_params_any(pcm, hw_params));
> 
>    snd_pcm_format_t fmt;
>    unsigned int channels = 0;
>    CHECK_CALL(snd_pcm_hw_params_get_format(hw_params, &fmt));
>    CHECK_CALL(snd_pcm_hw_params_get_channels_min(hw_params, &channels));
> 
>    snd_pcm_uframes_t buffer_size = asked_buffer_size;
>    snd_pcm_uframes_t period_size = asked_period_size;
>    CHECK_CALL(snd_pcm_hw_params_set_rate(pcm, hw_params, SampleRate, 0));
>    CHECK_CALL(snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED));
>    CHECK_CALL(snd_pcm_hw_params_set_buffer_size_near(pcm, hw_params, &buffer_size));
>    CHECK_CALL(snd_pcm_hw_params_set_period_size_near(pcm, hw_params, &period_size, NULL));
>    CHECK_CALL(snd_pcm_hw_params(pcm, hw_params));
>    snd_pcm_hw_params_free(hw_params);
> 
>    printf("buffer_size=%d (asked %d), ", (int)buffer_size, (int)asked_buffer_size);
>    printf("period_size=%d (asked %d), ", (int)period_size, (int)asked_period_size);
>    printf("channels=%d, ", channels);
>    printf("format=%s (%d bpp)\n", snd_pcm_format_name(fmt), snd_pcm_format_width(fmt));
> 
>    const int totalSamples = SampleRate * 1.0;
> 
>    int bitsPerSample = snd_pcm_format_width(fmt);
>    assert(bitsPerSample % 8 == 0);
>    int size = totalSamples * channels * bitsPerSample / 8;
>    uint8_t* buffer = (uint8_t*)malloc(size);
>    memset(buffer, 0, size);
>    CHECK_CALL(snd_pcm_writei(pcm, buffer, totalSamples));
>    free(buffer);
> 
>    CHECK_CALL(snd_pcm_drain(pcm));
>    snd_pcm_close(pcm);
> 
>    printf("OK\n");
>    return 0;
> }
> //---------------------------------------------------------------
> 
> 






[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux