<p><br>
>>>>>>><br>
>>>>>>> 5) The pulseaudio sink code takes the first 10ms of audio out of the<br>
>>>>>>> loopback buffer,<br>
>>>>>>> writes it to the alsa buffer and calls snd_pcm_start().<br>
>>>>>><br>
>>>>>> If the sink takes something from the loopback buffer, this means that<br>
>>>>>> the first pop() call has been made. Assuming no time has passed since<br>
>>>>>> the previous step, the USB bus is still full, and so is the ring<br>
>>>>>> buffer. Expected delay: 20 ms.<br>
>>>>><br>
>>>>> Reported delay is exactly the amount of audio that was written to<br>
>>>>> the buffer.<br>
>>>><br>
>>>> That's the bug that I think should be fixed in alsa if possible (and if<br>
>>>> it's impossible, I don't see how it could be fixed in pulseaudio<br>
>>>> either).<br>
>>><br>
>>> It can be fixed (or at least be worked around). If you take a time stamp<br>
>>> at the moment when snd_pcm_start() is called and another when<br>
>>> the first audio has definitely been played (delay < write_count), then<br>
>>> the difference between the time stamps corrected by the amount<br>
>>> of audio that has already been played, gives you exactly that<br>
>>> missing bit of latency.<br>
>><br>
>> I can't follow that line of reasoning. In the beginning the ring buffer<br>
>> is filled to max, and once you call snd_pcm_start(), data starts to<br>
>> move from the ring buffer to other buffers (I'll call the other buffers<br>
>> the "not-ring-buffer"). Apparently the driver "sees" the not-ring-<br>
>> buffer only partially, since it reports a larger latency than just the<br>
>> ring buffer fill level, but it still doesn't report the full latency.<br>
>> The time between snd_pcm_start() and the point where the reported delay<br>
>> does not any more equal the written amount tells the size of the<br>
>> visible part of the not-ring-buffer - it's the time it took for the<br>
>> first sample to travel from the ring buffer to the invisible part of<br>
>> the not-ring-buffer. I don't understand how the time could say anything<br>
>> about the size of the invisible part of the not-ring-buffer. Your logic<br>
>> "works" only if the visible and invisible parts happen to be of the<br>
>> same size.<br>
>><br>
>> You should get the same results by calculating<br>
>><br>
>>    adjusted delay = ring buffer fill level + 2 * (reported delay - ring buffer fill level)<br>
>><br>
>> That formula doesn't make sense, but that's how I understand your logic<br>
>> works, with the difference that your fix is based on one measurement<br>
>> only, so it's constant over time, while my formula recalculates the<br>
>> adjustment every time the delay is queried, so the adjustment size<br>
>> varies somewhat depending on the granularity at which audio moves to<br>
>> and from the visible part of the not-ring-buffer.<br>
>><br>
>> In any case, even if your logic actually makes sense and I'm just<br>
>> misunderstanding something, I don't see why the correction should be<br>
>> done in pulseaudio instead of the alsa driver.<br>
><br>
><br>
> Well, now I don't understand what you mean. The logic is very simple:<br>
> If there is a not reported delay between the time snd_pcm_start() is<br>
> called and the time when the first sample is delivered to the DAC, then<br>
> this delay will persist and become part of the continuous latency.<br>
> That's all, what causes the delay is completely irrelevant.<br>
><br>
> Maybe what I said above was not complete. At the point in time when<br>
> the first audio is played, there are two delays: First the one that is reported<br>
> by alsa and the other is the difference between the time stamps minus<br>
> the played audio. If these two delays don't match, then there is an<br>
> "extra delay" that has to be taken into account.<br>
> Trying to fix up that delay on every iteration does not make any sense<br>
> at all, it is there from the start and it is constant.<br>
><br>
> You are actually right - the problem should be fixed in the alsa driver,<br>
> but that should not hinder pulseaudio to work around the issue for<br>
> multiple reasons:<br>
> 1) It is relatively easy to work around<br>
> 2) If the problem is fixed in the alsa driver, the delay would just be<br>
> 0 and so have no impact anymore. This means there is no need<br>
> to change the code after the bug has been fixed in alsa.<br>
> 3) If there is another driver out there with the same or a similar bug,<br>
> (which I think is not unlikely) pulseaudio would do the right thing and<br>
> fix it up.<br>
> 4) When it is fixed in the alsa driver pulseaudio should still be able to<br>
> deliver the right values with a not fixed driver - at least for some time<br>
> until old versions of the alsa driver have died out.</p>
<p>The capture device may already started by other application (e.g. mic peak of pavucontrol), there is some audio already captured by driver but not read by server</p>
<p>At low latency, usb pointer incremented by number of frames in urb packet but hda intel increment by frames in dma brust</p>
<p>Do the result different when you use hda-intel as source and usb audio for playback?</p>
<p>It is unlikey module loopback can achieve lowest latency when you cannot control start,  capture and playback of alsa sink and source</p>
<p>It should have latency higher than snd-aloop,  alsaloop or latency.c<br></p>
<p>How can I query those values? Input delay seems to be 0 for HDA, the source starts<br>
> capturing samples immediately after snd_pcm_start().</p>
<p>Only some hda codec provide this delay, do this delay still exist if band EQ or hardware filters is not enabled? </p>
<p><a href="http://git.kernel.org/cgit/linux/kernel/git/tiwai/hda-emu.git/tree/codecs/idt92hd73e1x5-intel-dg45id?id=HEAD">http://git.kernel.org/cgit/linux/kernel/git/tiwai/hda-emu.git/tree/codecs/idt92hd73e1x5-intel-dg45id?id=HEAD</a></p>
<p>Node 0x17 [Audio Output] wcaps 0xd0c05: Stereo Amp-Out R/L <br>
Amp-Out caps: N/A <br>
Amp-Out vals: [0x78 0x78] <br>
Converter: stream=0, channel=0 <br>
Power: setting=D0, actual=D0 <br>
Delay: 13 samples</p>
<p>Node 0x1a [Audio Input] wcaps 0x1d0541: Stereo <br>
Converter: stream=0, channel=0 SDI-Select: 0 <br>
Power: setting=D0, actual=D0 <br>
Delay: 13 samples <br>
Connection: 1 <br>
0x20 <br>
Processing caps: benign=0, ncoeff=0<br>
</p>