Mark, thanks so much for doing all this stuff to Hijack for this project. It's super helpful.
Initially, I tried to suppress it on a "group of lines" basis. But it quickly became apparent that this wouldn't really work well, or at least not the way I was implementing it. Things just got too complex for too simple a problem.
Yep, I figured it would be like that.
Now, it only outputs a line if the value of the line has changed.
Sensible, but, as you said, makes my detection code more complicated. For something like this, the complexity would have to be either in my code or yours.
Question:
Does your new change which "only outputs if the value changed" include the timestamp lines and the paused/playing lines (the # and S lines)? If so, you probably shouldn't do the special casing for those, and instead just output those as-is.
Because there is a workaround in my interpreter code (see approx line 3678 in the current code) which works around a player bug which depends on the timestamp lines updating normally. The bug was that sometimes the empeg player application would not send an "S1" or "S0" when pausing or unpausing, so my code also keyed off whether or not the timestamps were changing or staying the same in order to update the host stereo on the play/paused state (partly because you suggested that very thing as a workaround).
instead you could trigger on the first '#' or 'S' line after an 'F' line, which gives the same effect.
Not exactly. As mentioned above, waiting for an "S" line might never come thanks to the player application bug, and waiting for a "#" line would delay my output by the amount of time that I had to wait for it, and those only come once per second.. and only if the player is playing; if the player is paused then it will never come (I think).
I'm already dealing with the fact that the track title updates on the host stereo screen are coming slower than I want them to come, and waiting for S or # would cause me to have to wait as much as another 1000 milliseconds before being able to update the host. That's an eternity for this particular thing. I've been using this in my car for the last several days, and in actual practice, slow track title updates are a major pain point that I'm trying very hard to fix right now.
I have to think more about the correct/timely way to do this.
One of the issues is that some stereos query for the entire track metadata all at once on one line, others query for it piecemeal (but still all at the same time) so the data conversation for updating the track metadata is an exchange of several messages back and forth. But the host stereo doesn't even begin the query until I notify it that a track has been changed. The current conversation goes like this:
1. At first connection, host stereo sends me a PDU_REGISTER_NOTIFICATION for TRACK_CHANGED.
2. I respond with "NFY INTERIM" details that say yes, I'll notify you if tracks change.
3. I collect track data change information from the empeg which, on the empeg, comes out one line at a time. Up till now, it would always come out in a predictable block always ending with the Genre tag.
4. Once I'm sure I have all of it, I send a SINGLE message to the host stereo saying "TRACK_CHANGED".
5. Host stereo queries me for track metadata. Sometimes it's asking for all the track data combined in one long message, or sometimes it's several messages in quick succession for different piecemeal parts of it, but either way it all happens together in one message or one group of messages. In other words, if I say to the host stereo "TRACK_CHANGED", I don't get to tell it which piece of the track changed, I can only tell it that the entire track changed. So the host always queries for all the track data all at once.
In other words, the host stereo might say "Send me title. Now send me genre. Now send me artist. Now send me track number. Now send me playlist length. Now send me duration... etc.", or it might say "send me track number, playlist length, and duration all in one line. Now send me title, artist, album, and genre all in one line", or it might say "send me everything all in one line". But because I don't get to tell it which bits changed, it has no way of knowing which parts are new and which parts are the same. So the host stereo always queries for all of the bits all in one group in quick succession, and I must respond to all of its queries immediately or the AVRCP connection will hang.
That's why in step number 4, I have to wait until I know all the track data has gotten to me before notifying the host stereo to start querying more that data. Because if I notify the host stereo too early, say, perhaps I do it only when I get a new Track Title, then the host stereo will query too early and then I will send it a partially messed up set of track metadata, containing the track title from the current track, but other pieces of metadata from the prior track. Maybe the metadata will be re queried again a few moments later when I get another line from the empeg, and then eventually what's displayed on the screen will be correct, but, in the meantime there will be a problem where the touchscreen displays the correct track title but some of the other data will be wrong.
Also in step number 4, I believe that I should make sure to not spam the host stereo with multiple updates about the track metadata. For instance, I should not send the host stereo a new "TRACK_CHANGED" message for every changed line of metadata that I receive from the empeg. I think this would cause too many sequential messages all at once causing too much back and forth between me and the host, and slowing down the responsiveness of the track title update process. Because that means the entire exchange in step 5 would have to be repeated several times for each line of new data that I get from the empeg.
So that's why I wait until I have all track the data before I try sending it up the bluetooth. Also, it is why I was so excited to discover that the empeg player application RELIABLY sent me the genre tag as the last line in the group every time. That made it very easy to key off of, and the updates were "fairly" quick.
However, as it is, there's something like 500-1000ms of delay between the time I press "next track" and the new track appears on the car stereo touchscreen, and that's already too long for my tastes. Having to wait for the next "S" or "#" message (which may never come) will add at least another 1000ms to that. That would be a problem I think.
ON THE OTHER HAND.........
Maybe doing it piecemeal is the correct solution. Maybe sending new TRACK_CHANGED notifications for each line of metadata received from the empeg, and having me and the host stereo re-spam each other several times for each one, is really the correct and most responsive way to get the job done. I'm certainly willing to TRY it. My prediction is that it will be slower and that it will look bad, but maybe it will actually be better. I can certainly give that a try with your current code.
But if it ends up being worse, then I'd prefer to just have you revert that set of Hijack changes you just made, put it back to V522, and then I will find other ways to work around the "player sends four track updates when reshuffling the whole player" bug.
Thanks again for doing all this work on Hijack, it's so massively helpful, and I'm sorry it's getting complicated.