Code Monkey home page Code Monkey logo

Comments (30)

badaix avatar badaix commented on June 18, 2024

What Android version?
What do you mean by "switching the delay"
What is your input sample rate?
Can you check the adb log?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

What Android version?
This happend on 2 devices with Android 9 and 1 device with FireOS7 (Android 9 as well)
What do you mean by "switching the delay"
In the app, adjust the delay in ms for the device to achieve syncronized playback.
What is your input sample rate?
Im using a spotify pipe from librespot.
pipe:///share/snapfifo/librespot?name=SpotifyConnect&sampleformat=44100:16:2
Can you check the adb log?
Just a general adb logcat? I will see what I can do later about that :)

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

EDIT - Seems to be a problem with Battery Optimization. After turning it off for snapcast this seems ok again.
EDIT2 - Same Problem on FireTV Devices. App stops playing at some point.

I just discovered another problem with the new client.
They now stop on their own. I was able to capture the logcat output of it:

03-06 16:21:11.001 12861  9558 D Main    : [Info] (Stream) Chunk: -4    -4      1       0       500     7       -3
03-06 16:21:11.684 12861  9558 W System.err: java.io.InterruptedIOException: read interrupted
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.Linux.readBytes(Native Method)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.Linux.read(Linux.java:184)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.BlockGuardOs.read(BlockGuardOs.java:254)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.IoBridge.read(IoBridge.java:501)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.FileInputStream.read(FileInputStream.java:307)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedInputStream.read(BufferedInputStream.java:347)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.InputStreamReader.read(InputStreamReader.java:184)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.fill(BufferedReader.java:172)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.readLine(BufferedReader.java:335)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.readLine(BufferedReader.java:400)
03-06 16:21:11.684 12861  9558 W System.err:    at de.badaix.snapcast.SnapclientService$1.run(SnapclientService.java:267)
03-06 16:21:11.684 12861  9558 W System.err:    at java.lang.Thread.run(Thread.java:764)
03-06 16:21:11.688 12861 12861 D Main    : onPlayerStop
03-06 16:21:11.688 12861 12861 D Main    : updateStartStopMenuItem: ic_media_play

And here is the logcat output when the error tone happens when muting a device:

03-06 16:57:00.001 12861 14446 D Main    : [Info] (Stream) Chunk: 2     2         -5      -1      500       7       -1
--
03-06   16:57:01.001 12861 14446 D Main    :   [Info] (Stream) Chunk: 0     0       0         0       500     7         4 |  
03-06   16:57:02.001 12861 14446 D Main    :   [Info] (Stream) Chunk: 1     -1      -1        0       500     7         0
03-06   16:57:03.001 12861 14446 D Main    :   [Info] (Stream) Chunk: -1    -1      0         0       500     7         0
03-06   16:57:03.684 12861 14446 D Main    :   [Info] (onMessageReceived) ServerSettings - buffer: 700, latency: 0, volume:   86, muted: 1
03-06   16:57:03.687 12861 11349 D TCP     :   Received Message:   '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"73031233-5f2d-4e91-9179-1987bcfd1fe9","volume":{"muted":true,"percent":86}}}'
03-06   16:57:04.001 12861 14446 D Main    :   [Info] (Stream) Chunk: 1     1       1         0       500     7         0 |  
03-06   16:57:04.253 12861 14446 D Main    :   [Info] (getPlayerChunk) Exception |   |  


FIRETV LOG:
Device keeps playing fine if latency is set to 0. As soon as i increase it to 200 audio is full of errors

03-06 17:18:33.434  7167  8056 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":28}}}'
03-06 17:18:33.649  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       325     0
03-06 17:18:34.016  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       64      310     0
03-06 17:18:35.002  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       227     330     0
03-06 17:18:36.000  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       377     310     0
03-06 17:18:37.024  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       1       0       500     310     0
03-06 17:18:38.002  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     323     -2
03-06 17:18:39.008  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-06 17:18:40.032  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-06 17:18:40.255  7167  7212 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 700, latency: 0, volume: 75, muted: 0
03-06 17:18:40.255  7167  8056 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":75}}}'
03-06 17:18:41.002  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     315     0
03-06 17:18:42.018  7167  7212 D Main    : [Info] (Stream) Chunk: 1     0       0       1       500     308     -2
03-06 17:18:43.002  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       1       1       500     332     0
03-06 17:18:44.000  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       1       1       500     310     -2
03-06 17:18:45.025  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       1       500     310     -2
03-06 17:18:46.002  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       0       0       500     324     0
03-06 17:18:47.009  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       0       0       500     309     0
03-06 17:18:48.002  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       1       1       500     337     0
03-06 17:18:49.002  7167  7212 D Main    : [Info] (Stream) Chunk: 1     1       1       1       500     316     -2
03-06 17:18:49.291  7167  7212 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 700, latency: 200, volume: 75, muted: 0
03-06 17:18:49.293  7167  8056 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnLatencyChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","latency":200}}'
03-06 17:18:49.376  7167  7212 D Main    : [Info] (Stream) pMiniBuffer->full() && (abs(pMiniBuffer->mean()) > 50): 200049
03-06 17:18:49.396  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.466  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.521  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.577  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.649  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.778  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.841  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:49.906  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.016  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       9       310     -1
03-06 17:18:50.039  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.097  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.167  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.282  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.353  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.417  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.481  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.617  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.673  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.745  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.802  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.861  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:50.929  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.003  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.058  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       324     0
03-06 17:18:51.058  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.121  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.185  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.258  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.321  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.376  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.450  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.519  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.578  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.633  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.698  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.761  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.836  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.899  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:51.953  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.017  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       325     0
03-06 17:18:52.028  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.081  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.153  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.209  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.281  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.338  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.401  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.473  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.537  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.602  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.730  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.801  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.857  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.915  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:52.977  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.041  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       325     0
03-06 17:18:53.113  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.177  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.235  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.305  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.377  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.433  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.492  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.561  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.689  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.754  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.817  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:53.881  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.002  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       5       323     0
03-06 17:18:54.009  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.137  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.262  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.393  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.520  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.586  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.697  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.778  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.842  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:54.969  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.017  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       322     0
03-06 17:18:55.033  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.161  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.290  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.401  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.531  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.659  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.720  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.787  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.867  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:55.980  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.044  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       322     0
03-06 17:18:56.058  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.124  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.236  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.316  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.497  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.574  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.702  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.753  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.814  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.881  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:56.942  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.002  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.056  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       310     0
03-06 17:18:57.073  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.151  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.201  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.263  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.329  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.457  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.521  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.586  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.713  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.777  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.841  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:57.977  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:58.024  7167  7212 D Main    : [Info] (Stream) Chunk: 0     0       0       0       1       328     0
03-06 17:18:58.033  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:58.095  7167  7212 D Main    : [Info] (getPlayerChunk) Exception
03-06 17:18:58.128  7167  7212 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 700, latency: 200, volume: 75, muted: 1
03-06 17:18:58.129  7167  8056 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":true,"percent":75}}}'
03-06 17:18:58.153  7167  7212 D Main    : [Info] (getPlayerChunk) Exception

from snapdroid.

badaix avatar badaix commented on June 18, 2024

ok, thanks.
raising the latency will lower the overall available buffer. Your tablet's audio buffer is quite large (~320ms) adding a latency of 200, will result in 520. Then you have a some latency on top for the stream capture, the codec, the network and the resampler (all Android devices I've seen so far have a low latency/native sample rate of 48kHz, snapclient will resample the signal with soxr, because I've seen on a Samsung galaxy that the "non-native" samplerate will produce quite unstable latency reporting, resulting in unstable "Chunk" numbers (Chunk: 0 0 0 0 1 328 0) and thus high jitter.
You should observe the same problems with the 0.17 on your tablet.
What about the other issues? Were they solved when turning of the battery optimization?
Also this shouldn't have changed from the 0.17.

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Ok, if i understand you correct, i need to increase the buffer on the server side?
All this just changed after the update to 0.19. Before none of that had happend so far.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

so is it working without battery optimization? I was just listening for half an hour with battery optimization turned on, not charging and display off.
The latency issue you will have with all versions. Did you update the server also?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

No i did not update the server yet. Only thing i changed is the client.
In the meantime, one of my clients is offline even though battery optimization is turned off.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

When does this stop happen?

I just discovered another problem with the new client.
They now stop on their own. I was able to capture the logcat output of it:

03-06 16:21:11.001 12861  9558 D Main    : [Info] (Stream) Chunk: -4    -4      1       0       500     7       -3
03-06 16:21:11.684 12861  9558 W System.err: java.io.InterruptedIOException: read interrupted
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.Linux.readBytes(Native Method)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.Linux.read(Linux.java:184)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.BlockGuardOs.read(BlockGuardOs.java:254)
03-06 16:21:11.684 12861  9558 W System.err:    at libcore.io.IoBridge.read(IoBridge.java:501)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.FileInputStream.read(FileInputStream.java:307)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedInputStream.read(BufferedInputStream.java:347)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351)
03-06 16:21:11.684 12861  9558 W System.err:    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.InputStreamReader.read(InputStreamReader.java:184)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.fill(BufferedReader.java:172)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.readLine(BufferedReader.java:335)
03-06 16:21:11.684 12861  9558 W System.err:    at java.io.BufferedReader.readLine(BufferedReader.java:400)
03-06 16:21:11.684 12861  9558 W System.err:    at de.badaix.snapcast.SnapclientService$1.run(SnapclientService.java:267)
03-06 16:21:11.684 12861  9558 W System.err:    at java.lang.Thread.run(Thread.java:764)
03-06 16:21:11.688 12861 12861 D Main    : onPlayerStop
03-06 16:21:11.688 12861 12861 D Main    : updateStartStopMenuItem: ic_media_play

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Offline means the client is disconnected or the WiFi is turned off?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Offline means the client is disconnected or the WiFi is turned off?

The Wifi is still on, but the snapcast app is disconnected. (The play button on the top right shows)
If I press it, it starts playing again.

I cannot pinpoint when this happens. The device is playing fine for some minutes, and at some point just disconnects.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Sounds almost like the wakelock is not properly acquired. What version were you using before? The 0.17.1.3?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Sounds almost like the wakelock is not properly acquired. What version were you using before? The 0.17.1.3?

The one that was previously on Playstore. I dont remember the version number.

Yesterday night I was playing on the firetv via snapcast. This morning, there is again no playback via the app. Connecting to logcat shows that the app receives volume changes and mute but doesn't playback anything.

03-07 08:05:12.062  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 0
03-07 08:05:12.062  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":50}}}'
03-07 08:06:01.779  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 1
03-07 08:06:01.780  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":true,"percent":50}}}'
03-07 08:06:03.498  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 0
03-07 08:06:03.498  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":50}}}'

from snapdroid.

badaix avatar badaix commented on June 18, 2024

ok, damn, the last PlayStore version is not in releases on this GitHub page. It must have been the 0.17.0.
Can you please try the 0.17.1.1 from the releases page?
This version is almost the same, except that the binary has been renamed from "snapclient" to "snapclient.so" because of some Android restrictions regarding native binaries.
Also I built a new version where the audio engine can be selected. If you change the engine from "Auto" to "OpenSL" and uncheck "Resample audio stream", then this version should behave like the 0.17.1.1.
Unfortunately, not all file extensions are allowed in the issue tracker, so you have to unzip and push the apk on you device with adb:
Snapcast_0.19.0.1.apk.zip

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Yesterday night I was playing on the firetv via snapcast. This morning, there is again no playback via the app. Connecting to logcat shows that the app receives volume changes and mute but doesn't playback anything.

03-07 08:05:12.062  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 0
03-07 08:05:12.062  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":50}}}'
03-07 08:06:01.779  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 1
03-07 08:06:01.780  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":true,"percent":50}}}'
03-07 08:06:03.498  7167 26334 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 200, volume: 50, muted: 0
03-07 08:06:03.498  7167 26210 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":false,"percent":50}}}'

This control stuff is handled natively in Android Java code, while the playback is done by starting an Android service that spawns a cross compiled Snapclient binary. This service seems to be closed by Android in your case, which is strange, since almost only the binary has changed, not the wrapping service.

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Thank you for releasing a new test version. I just installed the new client on all devices. Selected OpenSL and NoResample.
So far this seems to have fixed the automatic stop on my FireTV device. Also the other devices on Android 9 appear to be fine.

However, i just discovered a new issue that only happens on an older Android Version:

Snapcast installed on Android Tablet (Android 5.1.1)
1. Snapcast client playing
2. Disconnect WiFi on client
3. Reconnect Wifi on Client
4. Snapcast will reconnect, but not continue playing.
5. Turning off and on again the client will resume playback BUT
6. Volume control does not work anymore. Only muting result is as expected. Volume changes either on the client app itself or via other client apps are not working.
7. This only works again after restart of the whole device. Force stop of the app and restarting the app does not help.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Can you please try to find out if resampling was causing the issue or the Oboe player (which will be the default for more recent Android versions, starting with Oreo in the "Auto" setting)?
So test once with "Audio engine" set to "Auto" and resampling turned off, and test once with "OpenSL" and resampling turned on. Maybe resampling uses too much CPU time and is killed by Android. In this case I would set the default engine to "Auto" and turn resampling off by default.

Regarding your Lollipop device: this sounds like some strange Android bug on your phone. On some devices it happened that the Android could not reopen the audio player after connection loss (Issue #14), which is actually solved now by restarting the Snapclient binary.

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

It is the Oboe player.
The issue on the old android device not reconnecting is fixed by choosing OBOE & Resampling.
Now I'm checking if in this config the previous issue will return.

FYI: The resampling also makes the audio output much lower in volume.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

ok, thanks.
I've build another version without LatencyTuner, which might do too much magic. Would be great when you could test this version also (and check if Oboe is working better):
Snapcast_0.19.0.1_wo_latency_tuner.apk.zip

The lowered volume is yet another issue I cannot reproduce :(
When changing the bit depth, this could happen (e.g. 24bit in 32 bit interpreted as 32 bit), but the bit depth will be converted to 16 bit in any case (resampling checked or not).

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

when you could test this version also (and check if Oboe is working better):

I just did. These are the results:

  1. Oboe without resampling: When muting, the error sound is playing for a short time and quickly fading out.
  2. Oboe with resampling: Error sounds just playing the whole time when muting. Same as before.

The lowered volume is yet another issue I cannot reproduce :(

Ok, maybe i was exaggerating a bit. The sound is not MUCH lower in volume. But I can clearly hear the difference. Maybe i only found out, because I was plagued by too low volume in the first place.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Thanks for pointing me to the muting issue again, somehow I managed to miss this out. This one I can actually reproduce, i.e. will be able to fix it.
What I actually wanted to know is if the latest version (w/o latency tuner) still stops playing after a while?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Ok i just tried it on the firetv. Yes the oboe still stops playing. Not sure if its maybe related to some hdmi cec issue though. If i turn off the TV and only the Soundbar is still on, the sound is stopping. The snapcast app still shows as playing ( play button on the top right) but no more sound. With OpenSL this is not a problem

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Thanks for checking this.
I did a test with my FireTV Box (some later generation), running Fire OS 6.2.7.1, which is based on Android 7.1.2. When using "Auto", Snapdroid will use the OpenSL engine, because Oboe would also use OpenSL, since AAudio is supported starting with Android 8 (Oboe is just a wrapper that uses AAudio if available, and falls back to OpenSL, if not), so you can basically choose between the old OpenSL implementation (Auto and OpenSL) and OpenSL (Oboe).
However, the sync statistics are looking not good on the FireTv:

D/Main: [Info] (Stream) Chunk: 126	23	20	16	217	50	-13
D/Main: [Info] (Stream) Chunk: -77	20	20	16	237	50	-13
D/Main: [Info] (Stream) Chunk: 35	16	20	16	257	50	-9
D/Main: [Info] (Stream) Chunk: -182	6	11	12	277	50	-4
D/Main: [Info] (Stream) Chunk: -46	-3	6	11	297	50	-8
D/Main: [Info] (Stream) Chunk: 38	21	-2	11	317	50	-1
D/Main: [Info] (Stream) Chunk: -127	5	0	11	337	50	1
D/Main: [Info] (Stream) Chunk: 19	-12	-3	10	357	50	0
D/Main: [Info] (Stream) Chunk: 104	-5	-5	7	377	50	2
D/Main: [Info] (Stream) Chunk: -24	0	-5	5	397	50	4
D/Main: [Info] (Stream) Chunk: 44	33	-2	6	417	50	0
D/Main: [Info] (Stream) Chunk: -175	2	-5	5	437	50	0
D/Main: [Info] (Stream) Chunk: -38	33	0	5	457	50	2
D/Main: [Info] (Stream) Chunk: 95	19	2	5	477	50	0
D/Main: [Info] (Stream) Chunk: -91	7	7	5	497	50	-1
D/Main: [Info] (Stream) Chunk: 2	2	2	2	500	50	-5
D/Main: [Info] (Stream) Chunk: 119	44	7	6	500	50	-2
D/Main: [Info] (Stream) Chunk: -96	2	2	2	500	50	-9
D/Main: [Info] (Stream) Chunk: 31	-7	2	2	500	50	-1
D/Main: [Info] (Stream) Chunk: -110	-21	2	0	500	50	-1
D/Main: [Info] (Stream) Chunk: -45	-24	-7	-1	500	50	0
D/Main: [Info] (Stream) Chunk: 127	41	-7	-1	500	50	2
D/Main: [Info] (Stream) Chunk: -127	8	0	0	500	50	0
D/Main: [Info] (Stream) Chunk: 39	3	3	0	500	50	0
D/Main: [Info] (Stream) Chunk: 109	6	3	0	500	50	-3
D/Main: [Info] (Stream) Chunk: -94	-28	0	-2	500	50	0

This actually looks like my Galaxy S5 without resampling. With resampling the Galaxy gives quite smooth stats.
In best case it should look like:

D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	50	0

This is the big advantage of AAudio: when it requests an audio chunk, it gives a very precise estimation when this chunk will be audible, resulting in very smooth statistics. OpenSL doesn't give this estimation at all, it's hard coded to "50ms"

For comparison, my cheap Xiaomi mi A2 lite looks almost perfect:

D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	19	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	19	0
D/Main: [Info] (Stream) Chunk: 0	0	-1	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	1
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	19	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	19	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	19	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: -2	0	-1	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	1
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0
D/Main: [Info] (Stream) Chunk: 0	0	0	0	500	20	0

Note that the delay is around 20ms, when resampling is turned off and it plays a 44.1kHz stream (the devices low latency bit rate is 48kHz), the delay is 80ms, i.e. it needs some 60ms more to process the stream. I think that this will be true also for OpenSL (where is delay is not available), so resampling in software should result in some constant device delay, independent of the samplerate.

Also, I could fix the noise when muting the device and some smaller bug related to this.

But I could not reproduce the stopping audio playback, because my ARV is a bit older (w/o HDMI), the FireTV is connected via HDMI to the TV and the TV's audio is connected via TOSLink to the AVR.

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Ok, so i just checked the logs on the new FireTV (Android 9 based) and with OpenSL the Sync Statistic looks very similar to yours:

03-10 17:20:18.022 19338 21858 D Main    : [Info] (Stream) Chunk: 342   2       2       2       12      50      0
03-10 17:20:19.026 19338 21858 D Main    : [Info] (Stream) Chunk: 380   331     297     297     32      50      0
03-10 17:20:20.024 19338 21858 D Main    : [Info] (Stream) Chunk: 360   360     331     331     52      50      0
03-10 17:20:21.024 19338 21858 D Main    : [Info] (Stream) Chunk: 360   360     331     331     72      50      0
03-10 17:20:22.024 19338 21858 D Main    : [Info] (Stream) Chunk: 361   360     341     341     92      50      0
03-10 17:20:22.464 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): 34146
03-10 17:20:23.024 19338 21858 D Main    : [Info] (Stream) Chunk: 0     0       0       0       10      50      0
03-10 17:20:24.007 19338 21858 D Main    : [Info] (Stream) Chunk: -175  0       0       0       30      50      0
03-10 17:20:25.011 19338 21858 D Main    : [Info] (Stream) Chunk: -136  -71     -9      -9      50      50      0
03-10 17:20:26.028 19338 21858 D Main    : [Info] (Stream) Chunk: 39    -70     -23     -23     70      50      0
03-10 17:20:27.005 19338 21858 D Main    : [Info] (Stream) Chunk: -188  -41     -30     -30     90      50      0
03-10 17:20:28.014 19338 21858 D Main    : [Info] (Stream) Chunk: -99   -69     -49     -39     110     50      15
03-10 17:20:29.026 19338 21858 D Main    : [Info] (Stream) Chunk: 24    -29     -69     -39     130     50      16
03-10 17:20:29.061 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): -6945
03-10 17:20:30.018 19338 21858 D Main    : [Info] (Stream) Chunk: 74    74      74      74      18      50      0
03-10 17:20:31.020 19338 21858 D Main    : [Info] (Stream) Chunk: 96    70      71      71      38      50      0
03-10 17:20:32.002 19338 21858 D Main    : [Info] (Stream) Chunk: -90   62      70      70      58      50      0
03-10 17:20:33.010 19338 21858 D Main    : [Info] (Stream) Chunk: -4    70      70      70      78      50      0
03-10 17:20:34.029 19338 21858 D Main    : [Info] (Stream) Chunk: 180   74      70      70      98      50      0
03-10 17:20:34.162 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): 7071
03-10 17:20:35.009 19338 21858 D Main    : [Info] (Stream) Chunk: -124  -9      -9      -9      16      50      0
03-10 17:20:36.014 19338 21858 D Main    : [Info] (Stream) Chunk: -70   -27     -27     -27     36      50      0
03-10 17:20:37.026 19338 21858 D Main    : [Info] (Stream) Chunk: 42    -28     -28     -28     56      50      0
03-10 17:20:38.013 19338 21858 D Main    : [Info] (Stream) Chunk: -82   -61     -36     -36     76      50      0
03-10 17:20:39.019 19338 21858 D Main    : [Info] (Stream) Chunk: -29   -36     -36     -36     96      50      0
03-10 17:20:40.003 19338 21858 D Main    : [Info] (Stream) Chunk: -181  -36     -36     -36     116     50      10
03-10 17:20:41.010 19338 21858 D Main    : [Info] (Stream) Chunk: -108  -34     -36     -36     136     50      14
03-10 17:20:42.029 19338 21858 D Main    : [Info] (Stream) Chunk: 79    -31     -44     -36     156     50      15
03-10 17:20:43.007 19338 21858 D Main    : [Info] (Stream) Chunk: -134  -36     -36     -36     176     50      9
03-10 17:20:44.015 19338 21858 D Main    : [Info] (Stream) Chunk: -57   -57     -40     -40     196     50      13
03-10 17:20:45.034 19338 21858 D Main    : [Info] (Stream) Chunk: 137   -17     -36     -36     216     50      14
03-10 17:20:46.014 19338 21858 D Main    : [Info] (Stream) Chunk: -63   -14     -33     -36     236     50      13
03-10 17:20:47.019 19338 21858 D Main    : [Info] (Stream) Chunk: -5    -11     -33     -36     256     50      14
03-10 17:20:48.005 19338 21858 D Main    : [Info] (Stream) Chunk: -143  -8      -25     -36     276     50      12
03-10 17:20:49.011 19338 21858 D Main    : [Info] (Stream) Chunk: -88   -15     -17     -36     296     50      11
03-10 17:20:50.030 19338 21858 D Main    : [Info] (Stream) Chunk: 102   -28     -23     -34     316     50      12
03-10 17:20:51.008 19338 21858 D Main    : [Info] (Stream) Chunk: -108  -27     -27     -34     336     50      12
03-10 17:20:52.016 19338 21858 D Main    : [Info] (Stream) Chunk: -28   -28     -28     -34     356     50      14
03-10 17:20:53.027 19338 21858 D Main    : [Info] (Stream) Chunk: 78    7       -28     -33     376     50      8
03-10 17:20:54.015 19338 21858 D Main    : [Info] (Stream) Chunk: -35   -19     -28     -33     396     50      8
03-10 17:20:55.020 19338 21858 D Main    : [Info] (Stream) Chunk: 13    -11     -20     -30     416     50      9
03-10 17:20:56.007 19338 21858 D Main    : [Info] (Stream) Chunk: -114  11      -18     -29     436     50      1
03-10 17:20:57.013 19338 21858 D Main    : [Info] (Stream) Chunk: -58   -4      -11     -29     456     50      9
03-10 17:20:58.030 19338 21858 D Main    : [Info] (Stream) Chunk: 117   -7      -12     -28     476     50      11
03-10 17:20:59.009 19338 21858 D Main    : [Info] (Stream) Chunk: -89   -15     -12     -28     496     50      4
03-10 17:20:59.261 19338 21858 D Main    : [Info] (Stream) pBuffer->full() && (abs(median_) > 2): -2849
03-10 17:21:00.017 19338 21858 D Main    : [Info] (Stream) Chunk: 24    27      27      27      14      50      1
03-10 17:21:01.027 19338 21858 D Main    : [Info] (Stream) Chunk: 122   53      46      46      34      50      0
03-10 17:21:02.015 19338 21858 D Main    : [Info] (Stream) Chunk: 0     23      27      27      54      50      0
03-10 17:21:03.020 19338 21858 D Main    : [Info] (Stream) Chunk: 52    28      27      27      74      50      0
03-10 17:21:04.004 19338 21858 D Main    : [Info] (Stream) Chunk: -111  27      27      27      94      50      0
03-10 17:21:05.012 19338 21858 D Main    : [Info] (Stream) Chunk: -35   44      27      27      114     50      -10
03-10 17:21:06.030 19338 21858 D Main    : [Info] (Stream) Chunk: 150   30      23      27      134     50      -13
03-10 17:21:07.010 19338 21858 D Main    : [Info] (Stream) Chunk: -56   2       19      23      154     50      -13
03-10 17:21:08.017 19338 21858 D Main    : [Info] (Stream) Chunk: 6     6       12      21      174     50      -10
03-10 17:21:09.027 19338 21858 D Main    : [Info] (Stream) Chunk: 108   44      12      21      194     50      -11
03-10 17:21:10.015 19338 21858 D Main    : [Info] (Stream) Chunk: -13   10      10      19      214     50      -13
03-10 17:21:11.021 19338 21858 D Main    : [Info] (Stream) Chunk: 37    21      7       19      234     50      -8
03-10 17:21:12.005 19338 21858 D Main    : [Info] (Stream) Chunk: -120  8       8       18      254     50      -7
03-10 17:21:13.017 19338 21858 D Main    : [Info] (Stream) Chunk: -1    16      10      18      274     50      -6
03-10 17:21:14.018 19338 21858 D Main    : [Info] (Stream) Chunk: 5     16      10      16      294     50      -12
03-10 17:21:15.006 19338 21858 D Main    : [Info] (Stream) Chunk: -119  -7      7       13      314     50      -8
03-10 17:21:16.018 19338 21858 D Main    : [Info] (Stream) Chunk: 2     2       5       10      334     50      -2
03-10 17:21:17.028 19338 21858 D Main    : [Info] (Stream) Chunk: 99    33      5       10      354     50      -5
03-10 17:21:18.002 19338 21858 D Main    : [Info] (Stream) Chunk: -153  2       2       10      374     50      -5
03-10 17:21:19.021 19338 21858 D Main    : [Info] (Stream) Chunk: 35    6       2       9       394     50      -1
03-10 17:21:20.006 19338 21858 D Main    : [Info] (Stream) Chunk: -115  -2      2       8       414     50      -1
03-10 17:21:21.013 19338 21858 D Main    : [Info] (Stream) Chunk: -52   -26     0       7       434     50      0
03-10 17:21:22.018 19338 21858 D Main    : [Info] (Stream) Chunk: 2     2       0       7       454     50      0
03-10 17:21:23.006 19338 21858 D Main    : [Info] (Stream) Chunk: -118  -2      -2      7       474     50      0
03-10 17:21:24.021 19338 21858 D Main    : [Info] (Stream) Chunk: 30    20      -2      7       494     50      1
03-10 17:21:25.028 19338 21858 D Main    : [Info] (Stream) Chunk: 104   15      -2      7       500     50      0
03-10 17:21:26.003 19338 21858 D Main    : [Info] (Stream) Chunk: -148  9       2       6       500     50      1
03-10 17:21:27.022 19338 21858 D Main    : [Info] (Stream) Chunk: 37    13      3       6       500     50      -1
03-10 17:21:28.008 19338 21858 D Main    : [Info] (Stream) Chunk: -100  2       3       6       500     50      -3
03-10 17:21:29.013 19338 21858 D Main    : [Info] (Stream) Chunk: -47   -19     2       3       500     50      -2
03-10 17:21:30.019 19338 21858 D Main    : [Info] (Stream) Chunk: 7     7       2       2       500     50      0
03-10 17:21:31.007 19338 21858 D Main    : [Info] (Stream) Chunk: -111  6       2       2       500     50      -3
03-10 17:21:32.020 19338 21858 D Main    : [Info] (Stream) Chunk: 16    0       0       2       500     50      -1
03-10 17:21:33.029 19338 21858 D Main    : [Info] (Stream) Chunk: 106   29      0       2       500     50      0
03-10 17:21:34.004 19338 21858 D Main    : [Info] (Stream) Chunk: -137  -2      0       2       500     50      0
03-10 17:21:35.022 19338 21858 D Main    : [Info] (Stream) Chunk: 44    8       0       2       500     50      0
03-10 17:21:36.009 19338 21858 D Main    : [Info] (Stream) Chunk: -88   4       0       0       500     50      0
03-10 17:21:37.014 19338 21858 D Main    : [Info] (Stream) Chunk: -42   -16     -2      0       500     50      0
03-10 17:21:38.019 19338 21858 D Main    : [Info] (Stream) Chunk: 9     9       -14     0       500     50      0
03-10 17:21:39.007 19338 21858 D Main    : [Info] (Stream) Chunk: -106  14      -10     -2      500     50      6
03-10 17:21:40.021 19338 21858 D Main    : [Info] (Stream) Chunk: 29    2       1       0       500     50      2
03-10 17:21:41.029 19338 21858 D Main    : [Info] (Stream) Chunk: 112   -7      -7      0       500     50      0
03-10 17:21:42.004 19338 21858 D Main    : [Info] (Stream) Chunk: -137  -12     -7      -2      500     50      9
03-10 17:21:43.026 19338 21858 D Main    : [Info] (Stream) Chunk: 71    19      -2      -2      500     50      5
03-10 17:21:44.011 19338 21858 D Main    : [Info] (Stream) Chunk: -67   16      -2      -2      500     50      0
03-10 17:21:45.014 19338 21858 D Main    : [Info] (Stream) Chunk: -32   -7      -3      -2      500     50      1
03-10 17:21:46.019 19338 21858 D Main    : [Info] (Stream) Chunk: 20    1       -3      -2      500     50      2
03-10 17:21:47.007 19338 21858 D Main    : [Info] (Stream) Chunk: -100  27      -2      -2      500     50      0
03-10 17:21:48.021 19338 21858 D Main    : [Info] (Stream) Chunk: 41    9       -2      -2      500     50      1
03-10 17:21:49.034 19338 21858 D Main    : [Info] (Stream) Chunk: 168   5       -2      -2      500     50      0
03-10 17:21:50.004 19338 21858 D Main    : [Info] (Stream) Chunk: -129  -19     -6      -3      500     50      1
03-10 17:21:51.023 19338 21858 D Main    : [Info] (Stream) Chunk: 55    9       -2      -2      500     50      6
03-10 17:21:52.006 19338 21858 D Main    : [Info] (Stream) Chunk: -109  11      -10     -3      500     50      0
03-10 17:21:53.015 19338 21858 D Main    : [Info] (Stream) Chunk: -21   2       -5      -3      500     50      7
03-10 17:21:54.020 19338 21858 D Main    : [Info] (Stream) Chunk: 29    7       -1      -2      500     50      0
03-10 17:21:55.008 19338 21858 D Main    : [Info] (Stream) Chunk: -91   8       2       -2      500     50      0

With resampling enabled it looks worse? (at least further away from 0)

03-10 17:25:13.028 19338 14667 D Main    : [Info] (Stream) Chunk: 6     -7      -21     -36     270     50      14
03-10 17:25:14.042 19338 14667 D Main    : [Info] (Stream) Chunk: 148   -12     -18     -35     290     50      12
03-10 17:25:15.019 19338 14667 D Main    : [Info] (Stream) Chunk: -79   -18     -18     -35     310     50      11
03-10 17:25:16.034 19338 14667 D Main    : [Info] (Stream) Chunk: 74    11      -18     -33     330     50      6
03-10 17:25:17.011 19338 14667 D Main    : [Info] (Stream) Chunk: -158  -17     -13     -32     350     50      3
03-10 17:25:18.026 19338 14667 D Main    : [Info] (Stream) Chunk: -4    -4      -13     -31     370     50      12
03-10 17:25:19.034 19338 14667 D Main    : [Info] (Stream) Chunk: 78    -10     -16     -30     390     50      14
03-10 17:25:20.020 19338 14667 D Main    : [Info] (Stream) Chunk: -56   -24     -16     -30     410     50      7
03-10 17:25:21.026 19338 14667 D Main    : [Info] (Stream) Chunk: 1     1       -16     -27     430     50      1
03-10 17:25:22.042 19338 14667 D Main    : [Info] (Stream) Chunk: 161   4       -10     -27     450     50      2
03-10 17:25:23.021 19338 14667 D Main    : [Info] (Stream) Chunk: -52   5       -10     -26     470     50      3
03-10 17:25:24.035 19338 14667 D Main    : [Info] (Stream) Chunk: 86    -15     -12     -26     490     50      9
03-10 17:25:24.567 19338 14667 D Main    : [Info] (Stream) pBuffer->full() && (abs(median_) > 2): -2651
03-10 17:25:25.015 19338 14667 D Main    : [Info] (Stream) Chunk: -33   97      97      97      8       50      4
03-10 17:25:26.027 19338 14667 D Main    : [Info] (Stream) Chunk: 82    82      82      82      28      50      0
03-10 17:25:27.036 19338 14667 D Main    : [Info] (Stream) Chunk: 179   108     86      86      48      50      0
03-10 17:25:28.019 19338 14667 D Main    : [Info] (Stream) Chunk: 7     60      80      80      68      50      0
03-10 17:25:29.027 19338 14667 D Main    : [Info] (Stream) Chunk: 85    74      79      79      88      50      0
03-10 17:25:29.675 19338 14667 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): 7901
03-10 17:25:30.042 19338 14667 D Main    : [Info] (Stream) Chunk: 114   52      52      52      6       50      0
03-10 17:25:31.018 19338 14667 D Main    : [Info] (Stream) Chunk: -122  -65     -52     -52     26      50      0
03-10 17:25:32.034 19338 14667 D Main    : [Info] (Stream) Chunk: 36    -28     -44     -44     46      50      0
03-10 17:25:33.011 19338 14667 D Main    : [Info] (Stream) Chunk: -198  -52     -52     -52     66      50      0
03-10 17:25:34.029 19338 14667 D Main    : [Info] (Stream) Chunk: -20   -26     -45     -45     86      50      0
03-10 17:25:35.034 19338 14667 D Main    : [Info] (Stream) Chunk: 36    -60     -52     -52     106     50      4
03-10 17:25:35.061 19338 14667 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): -5237
03-10 17:25:36.020 19338 14667 D Main    : [Info] (Stream) Chunk: -22   46      46      46      18      50      0
03-10 17:25:37.026 19338 14667 D Main    : [Info] (Stream) Chunk: 38    55      46      46      38      50      0
03-10 17:25:38.042 19338 14667 D Main    : [Info] (Stream) Chunk: 195   77      46      46      58      50      0
03-10 17:25:39.024 19338 14667 D Main    : [Info] (Stream) Chunk: 21    43      43      43      78      50      0
03-10 17:25:40.035 19338 14667 D Main    : [Info] (Stream) Chunk: 127   24      42      42      98      50      0
03-10 17:25:41.014 19338 14667 D Main    : [Info] (Stream) Chunk: -80   40      40      40      118     50      -10

With OBOE (No Resampling):

03-10 17:27:18.458 19338 15073 D Main    : [Info] (Stream) pBuffer->full() && (abs(median_) > 2): -3154
03-10 17:27:19.035 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       93      309     9
03-10 17:27:20.003 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       248     317     0
03-10 17:27:21.018 19338 15073 D Main    : [Info] (Stream) Chunk: -1    -1      -1      0       418     310     0
03-10 17:27:22.004 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     330     2
03-10 17:27:23.002 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:24.026 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:25.003 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     325     0
03-10 17:27:26.010 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:27.005 19338 15073 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     338     0
03-10 17:27:28.002 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     315     -1
03-10 17:27:29.018 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:30.003 19338 15073 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     333     0
03-10 17:27:31.002 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     -2
03-10 17:27:32.026 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:33.003 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     323     0
03-10 17:27:34.010 19338 15073 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:27:35.001 19338 15073 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     336     0
03-10 17:27:36.003 19338 15073 D Main    : [Info] (Stream) Chunk: 1     1       2       1       500     301     -3

With OBOE & resampling:

03-10 17:28:38.266 19338 15324 D Main    : [Info] (Stream) pBuffer->full() && (abs(median_) > 2): -4294
03-10 17:28:39.004 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       132     338     7
03-10 17:28:40.000 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       292     315     0
03-10 17:28:41.019 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       471     310     0
03-10 17:28:42.004 19338 15324 D Main    : [Info] (Stream) Chunk: 1     1       0       0       500     330     0
03-10 17:28:43.003 19338 15324 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     310     0
03-10 17:28:44.027 19338 15324 D Main    : [Info] (Stream) Chunk: 1     1       1       1       500     310     -2
03-10 17:28:45.004 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       1       500     323     -2
03-10 17:28:46.011 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 17:28:47.035 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     309     0
03-10 17:28:48.005 19338 15324 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     315     0
03-10 17:28:49.019 19338 15324 D Main    : [Info] (Stream) Chunk: 1     0       0       0       500     310     0
03-10 17:28:50.004 19338 15324 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     333     0

FYI.. i didnt test it before, but with OBOE & RESAMPLING both enabled, the FireTV plays even when the TV goes off. However, it stopped as before after some time playing.

Once it stops playing, and i turn off and on again on the local client app (while being muted) the log gets spammed by this:

03-10 17:45:03.398 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.423 19338 18851 I chatty  : uid=10177(de.badaix.snapcast) Thread-12 identical 8 lines
03-10 17:45:03.432 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.462 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.487 19338 18851 I chatty  : uid=10177(de.badaix.snapcast) Thread-12 identical 9 lines
03-10 17:45:03.496 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.526 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.551 19338 18851 I chatty  : uid=10177(de.badaix.snapcast) Thread-12 identical 8 lines
03-10 17:45:03.559 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.590 19338 18851 D Main    : [Info] (Stream) no chunks available
03-10 17:45:03.615 19338 18851 I chatty  : uid=10177(de.badaix.snapcast) Thread-12 identical 9 lines
03-10 17:45:03.624 19338 18851 D Main    : [Info] (Stream) no chunks available

I tried capturing the exact point of stop playing with the logcat. But so far i have not been able to do so. However, not taking the logcat and muting it for some minutes, then trying to unmute it is showing this problem quite well.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

This spam should also happen directly when muting, not only after mute/stop/start. This is the "smaller fix" I mentioned yesterday. To not spam the log buffer too much, I've limited the message to show up only once per second.
Seems that your fireTV is quite unimpressed of the used sample rate. These messages will cause audible audio drops:

03-10 17:20:22.464 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): 34146
03-10 17:20:29.061 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): -6945
03-10 17:20:34.162 19338 21858 D Main    : [Info] (Stream) pShortBuffer->full() && (abs(shortMedian_) > 5): 7071

This is why Oboe should be preferred by Snapdroid (I don't want to implement a pure AAudio player, as Oboe is according to Google the recommended "one size fits all" solution, and it's dead simple to use (but if I would completely trust in Oboe, I would have removed the OpenSL player...).

from snapdroid.

badaix avatar badaix commented on June 18, 2024

I found this on developer.amazon.com:

Requirement 6.1: Keeping the Device Awake
You must keep the device awake while playback is expected. This usually means your application sets the Activity flag FLAG_KEEP_SCREEN_ON or implements dynamic wake lock management by acquiring FULL_WAKE_LOCK.

Note: When using FLAG_KEEP_SCREEN_ON, you must unset the flag when playback is paused.

The attached APK will aquire a FULL_WAKE_LOCK (which is deprecated, but since audio is played from a service, and a PARTIAL_WAKE_LOCK is already aquired there, it's now simply using the full or the partial lock, depending on the device type it's running on):
Snapcast_0.19.0.1_1903_full_wake_lock.apk.zip

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Thank you. I am trying the new version. FYI just found a new bug. In the new app (on FireTV) when the Play/Stop Symbol is selected: Click once left and twice right and the app will crash.

The new app stops playing as soon as i turn off the Soundbar. When OBOE is selected.

I took the log of the libsnapclient.so

03-10 23:19:42.138 11320 11320 W libsnapclient.s: type=1400 audit(0.0:8417): avc: denied { ioctl } for path="socket:[4155738]" dev="sockfs" ino=4155738 ioctlcmd=0x8927 scontext=u:r:untrusted_app:s0:c177,c256,c512,c768 tcontext=u:r:untrusted_app:s0:c177,c256,c512,c768 tclass=tcp_socket permissive=0
03-10 23:19:42.138 11320 11320 W libsnapclient.s: type=1400 audit(0.0:8418): avc: denied { search } for name="net" dev="sysfs" ino=10143 scontext=u:r:untrusted_app:s0:c177,c256,c512,c768 tcontext=u:object_r:sysfs_net:s0 tclass=dir permissive=0
03-10 23:19:42.148 11320 11323 D AAudio  : AAudioStreamBuilder_openStream() called ----------------------------------------
03-10 23:19:42.148 11320 11323 D AudioStreamBuilder: build() EXCLUSIVE sharing mode not supported. Use SHARED.
03-10 23:19:42.148 11320 11323 D         : PlayerBase::PlayerBase()
03-10 23:19:42.148 11320 11323 I AAudioStream: open() rate   = 44100, channels    = 2, format   = 1, sharing = SH, dir = OUTPUT
03-10 23:19:42.148 11320 11323 I AAudioStream: open() device = 0, sessionId   = 0, perfMode = 12, callback: ON with frames = 0
03-10 23:19:42.148 11320 11323 I AAudioStream: open() usage  = 1, contentType = 2, inputPreset = 6
03-10 23:19:42.148 11320 11323 D AudioStreamTrack: open(), request notificationFrames = -8, frameCount = 0
03-10 23:19:42.151 11320 11323 W AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount 0 -> 1418
03-10 23:19:42.154 11320 11323 W AudioStreamTrack: open() flags changed from 0x00000104 to 0x00000000
03-10 23:19:42.154 11320 11323 W AudioStreamTrack: open() perfMode changed from 12 to 10
03-10 23:19:42.154 11320 11323 D AAudio  : AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for (0xe4fde000) ----------------
03-10 23:19:42.154 11320 11323 D AAudio  : AAudioStream_requestStart(0xe4fde000) called --------------
03-10 23:19:42.154 11320 11323 D         : PlayerBase::start() from IPlayer
03-10 23:19:42.155 11320 11323 D AAudio  : AAudioStream_requestStart(0xe4fde000) returned 0 ---------
03-10 23:21:49.826 11320 11324 W AudioTrack: dead IAudioTrack, PCM, creating a new one from processAudioBuffer()
03-10 23:21:49.826 11320 11325 W AudioSystem: ioConfigChanged() closing unknown output 5565
03-10 23:21:49.861 11320 11324 W AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount 1418 -> 1772
03-10 23:21:49.893 11320 11324 D AudioStreamLegacy: processCallbackCommon() stream disconnected
03-10 23:21:49.893 11320 11324 W AudioStreamLegacy: processCallbackCommon() data, stream disconnected
03-10 23:21:49.893 11320 11324 E AudioTrack: EVENT_MORE_DATA requested 2360 bytes but callback returned -1 bytes
03-10 23:21:49.895 11320 11685 D AAudio  : AAudioStream_requestStop(0xe4fde000)
03-10 23:21:49.895 11320 11685 D         : PlayerBase::stop() from IPlayer
03-10 23:21:49.895 11320 11685 E AAudioStream: setState(0xe4fde000) tried to set to 9 but already DISCONNECTED
03-10 23:21:49.895 11320 11685 D AudioTrack: stop() called with 5631904 frames delivered
03-10 23:21:49.897 11320 11685 D AAudio  : AAudioStream_close(0xe4fde000) called ---------------
03-10 23:21:49.898 11320 11320 W AudioTrack: type=1400 audit(0.0:8424): avc: denied { read } for name="u:object_r:media_prop:s0" dev="tmpfs" ino=14226 scontext=u:r:untrusted_app:s0:c177,c256,c512,c768 tcontext=u:object_r:media_prop:s0 tclass=file permissive=0
03-10 23:21:49.899 11320 11685 E libc    : Access denied finding property "media.metrics.enabled"
03-10 23:21:49.901 11320 11685 D AAudioStream: destroying 0xe4fde000, state = AAUDIO_STREAM_STATE_CLOSED
03-10 23:21:49.901 11320 11685 D AAudio  : AAudioStream_close(0xe4fde000) returned 0 ---------

Taking the normal log shows nothing. When i turn off the soundbar, the log just stops. No more music is being played. Only new entries when i change the volume:

03-10 23:24:56.003 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     336     -2
03-10 23:24:57.002 11251 12179 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     318     0
03-10 23:24:58.018 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       1       0       500     310     -2
03-10 23:24:59.007 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     328     -1
03-10 23:25:00.002 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     310     0
03-10 23:25:01.026 11251 12179 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     310     0
03-10 23:25:02.000 11251 12179 D Main    : [Info] (Stream) Chunk: 2     2       2       1       500     321     -2
03-10 23:25:03.010 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       1       1       500     310     -5
03-10 23:25:04.034 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       1       500     310     0
03-10 23:25:05.003 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     315     0
03-10 23:25:06.018 11251 12179 D Main    : [Info] (Stream) Chunk: 1     1       1       0       500     310     0
03-10 23:25:07.002 11251 12179 D Main    : [Info] (Stream) Chunk: 0     0       0       0       500     328     -2
03-10 23:25:08.002 11251 12179 D Main    : [Info] (Stream) Chunk: 1     1       0       1       500     310     0
03-10 23:25:43.594 11251 12179 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 440, volume: 26, muted: 1
03-10 23:25:43.595 11251 11274 D TCP     : Received Message: '{"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"7d90ab52-887e-4145-92bb-c8384d7422b5","volume":{"muted":true,"percent":26}}}'
03-10 23:25:44.667 11251 12179 D Main    : [Info] (onMessageReceived) ServerSettings - buffer: 1000, latency: 440, volume: 26, muted: 0

from snapdroid.

badaix avatar badaix commented on June 18, 2024

What soundbar?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

My FireTV is connected to a soundbar which then goes into the TV via HDMI. Samsung Brand Soundbar.

from snapdroid.

badaix avatar badaix commented on June 18, 2024

Until now it was about switching off the TV?

from snapdroid.

almostserious avatar almostserious commented on June 18, 2024

Previously when I turned off the TV but let the Soundbar on, the stream stopped playing after some time. Now, i realized that the stream stops playing immediately when I turn off the Soundbar. In any case, i wonder if this might be some CEC related issue. The device connected to the FireTV turns off and that kills the stream? Ill have to check if there is some CEC settings on FireTV and disable that.

EDIT

So, i played around a bit more.
I installed an old version again to see if there are differences.
Turned off CEC completely.
Connected the FireTV to the TV directly.

Changing App Version makes no difference.
Turning off CEC makes no difference.
Turning off the direct HDMI connected device (Both Soundbar & TV) stops playback. Even just switching the source stops the playback.

from snapdroid.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.