-
-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
set_volume does not change the volume until the music is paused (on iPhone iOS >= 15.7.9) #493
Comments
In the light that this is working perfectly with the provided default implementation, I tend to assume that you messed something up! What are you doing in the loop ? |
The loop is nothing:
The reason for providing my own implementation, was only to determine why the volume wasn't working 😆. I have trimmed down to basically just the default implementation. When I activate the verbose logging, there is a huge delay in the volume being changed. Also, the music is skipping because the controller seems like it is logging too much to also be able to stream correctly. However, the volume does change without me pressing pause, it just is like a 10 second delay. With "Info" logging i'd say there's a mix of the last two problems.... |
Did you double check that you are not starving the A2DP task with your loop ? Maybe you better use some callbacks instead of polling the states in your loop.... |
I thought that was going to fix it but even using Here is some of the log from when I press "play" and tap "volume up" about once per second. Unfortunately I can't paste the full log because I am choosing to work in the IDE instead of linux terminal, and IDEs in general are trash (https://forum.arduino.cc/t/copy-paste-data-from-the-serial-monitor/1041585/36)
The volume change is about 10 seconds late |
Yes: an empty loop is equally bad! |
Right true, I got that from the homepage, but i also just tried I will try a different ESP32 board... |
Did you check the log it you get the events in time from the IPhone ? |
Well, I don't know how to check the timing of those events, but I just tried it, and it works on my android tablet, also the audio quality is much better..... My iphone is fairly old too (iphone 6S) but it's not surprising knowing Apple that it would make up a problem like this for non-Apple bluetooth.... I will try that class. I tried setting the bluetooth to type "Headphone" in apple settings, and surprisingly, the device rebooted after a few seconds of streaming (may be due to "Queued" class though):
|
The problem persists when using Apple Music (perhaps not related to #485, i used it on files that I added from my computer, not the streaming service) and YouTube Music. Probably the music app is not making a difference. The problem persists in iOS 16.6 (iPhone SE, newer-ish iphone compared to my iphone 6S).... |
This issue is likely related to the last few detailed comments in #87, as the behaviors are quite similar |
I committed a new version of BluetoothA2DPSinkQueued which might resolve your issues... Since I don't have any recent IPhone, please let me know if this help ? |
I will do some more investigation, but I wanted to paste this log after doing what you suggested, in case there is an easy fix. Edit: Though it's 11:08 in Sweden, so hopefully i can have some more info by morning there.... You must understand, it was highly inconvenient to copy and paste these, because the arduino-ide is total trash, and doesn't enable copying and pasting more than ~30 lines at a time from the serial monitor.
The last few lines repeat... until:
There is audio, but there is no instant volume changes.... |
Strange: I tested it on Android and there it was working. It seems that the I2S writes are not working, so the queue is never consumed. After i2s_start() is_i2s_active, should be true! I will compare your log with mine tomorrow... |
The last log was using the PCM5102 breakout board from the wiki. I actually am not getting audio from that board. But this is what happens using a different external DAC (NAU8402) where i am getting audio (still i2s_write_data failed).
The last few lines repeat... I am pretty concerned based on your last message that there is some kind of hardware error here. Almost like the breadboards that I'm using are flawed, or the jumper wires are too thin, or something like that. So many potential variables... However perhaps this is unlikely... Since it does play audio outside the Queued class, just the volume changes don't work immediately...
|
I guess the access to is_i2s_active needs to by synchronized. But it is strange: the in the above log the entry for i2s_start is missing... |
I tried that here. This is the full log:
--- repeats endlessly
If a line is missing from the log, may be due to arduino ide maintainers closing discussion for a huge issue, then having its assignee leave, without being replaced arduino/arduino-ide#2262 arduino/arduino-ide#812 It's a huge chore to copy and paste only 20-30 log lines at a time and oftenthe scroll window slips and i have to try again ----By the way, Arduino doesn't cache the libraries somewhere does it? Because I just went into the Arduino libraries folder and changed the variable from "bool is_i2s_active" to "volatile bool is_i2s_active". But there's no way to know if it updated in the next flash |
That should be good enough. I am still confused from what I see: some critical events seem to be missing. I really need the confirmation that the audio state (which will activate and deactivate i2s) is working.... Maybe it will give less issues to use the connection state instead of the audio state for this scenario. |
Here is the log from the code you requested. Hopefully the issue was not that I had "Info" logging instead of "Debug". Debug is active now..:
The above logs are from just the page you linked to. In the next Github comment, I will provide logs for some code that has some more of my code integrated (will be show the code there) |
So in the last comment, I just used the code that you linked to. But this is with some more of my code integrated. The code:
The log:
|
I could not really reproduce your issue on my Android or old IPhones: All were playing the audio. Were/Are you getting no audio at all with BluetoothA2DPSinkQueued but with BluetoothA2DPSink ? A couple of comments:
|
Queued class I do have audio with the queued class after those changes, and I don't think I did before. The volume changes are still delayed. When music is played, this is output constantly (almost like it's taking up the full processor):
If I pause the music, I get:
For only 10-20 seconds!!! Then it may go back to "PREFETCHING" repeating over and over. The volume changes work instantly when it is paused. But again, it goes back to "PREFETCHING" even when paused for a while especially after volume changes. Btw, I'm assuming your last bullet point meant me changing the config values to this:
which I did also btw. Non-Queued Class For the regular a2dp sink class, the audio works, but I get no ringbuffer results. The volume requires play / pauses to update. One more important thing I should've mentioned this earlier, as I now realize that it may be very significant. When I set the volume to 0.0, the controller receives this one instantly. So any value between 1 and 100 requires pausing the music for the volume to update. But volume 0 is immediately received, for some reason. This makes me think you may need an iPhone 6S or newer to debug this further. Or you can tell me what to do to try to see what the iPhone is communicating here. |
This is very strange: You would get some underflow when the audio is not coming in fast enough which is virtually impossible. You can also try to play around with some parameters.
Maybe it's time to go back to the Espressif example to try to reproduce the issue and file a bug report. |
Lol, this did something. Delay of "1" was constant "underflow". Delay of "25" was constant "overflow". Delay of "7" was a little bit of underflow, with volume changes only coming at about a 1 second delay. "This is fine", I thought, "good enough". Then the device rebooted itself! Can you tell me which of these buffers will affect the value I should put in this delay?
Which of these are most affecting that delay value? Some logs....:
Any ideas on how I could debug why this is happening? Technically, it is receiving "item_size==0" worth of data.
I am using my brain now and will try these two next. If you have any comments or suggestions, please share them. For some reason your last suggestions made me understand a bit more about what is going on |
Not sure if this makes a difference, but I was testing with ESP32 2.0.14. I am also not sure in which task the audio data is written, so it might make sense to try to add some delays to the BluetoothA2DPSinkQueued::write_audio() |
I upgraded to ESP32 2.0.14, but nothing seemed to change
Just want to add this comment, that my Android tablet works perfectly with the queued and non-queued classes, but it does enter an underflow repeater when the music is paused too under the queued class. Its underflows and semphore gives (whatever that is) are more like hiccups than constant conditions....
Okay I did that and got the volume to change consistently. See the code below... ---> I think something common to both the Queued and Non-Queued class could be the issue here. Reason is, with the Queued class, I get an underflow condition, like not enough data is being sent. And with the non-queued class, while the logs don't say anything like that, the audio quality is choppy too, almost like it is not receiving enough data, in the exact same way. Both classes result in very "choppy" audio, seemingly identical audio, but the queued class gives the hint that maybe the iphone or some part of the protocol isn't receiving audio data fast enough.... But theoretically a queue's purpose would be to fix that issue.... so idk --> Not sure if this would be unexpected, but when I disable ---> The audio quality is consistently bad. Even if I time the delays correctly, so that there's very few underflow / overflow, the audio quality is still bad (queued and non-queued, with the iphone only) ---> I just found your suggestion from the discussion 2 days ago (#495 (comment)), to increase "event queue size"! I thought this would help, and maybe 20 to 30 did, but it did not seem to help it as much as the delays. When i set it back to 20, i couldn't lower "defaultDelay" below 3 still in the below code. I did get the volume to change consistently with only a few overflows:
But the audio quality is still quite bad, i do not know why. it is too bad to really use for anything. With two separate DACs tested.... (And the audio quality is much better on Android) |
I think to solve this issue, @pschatzmann, even though the above code works, I have to know why it sounds like the singer is gargling water when he talks? It's not a "bass" issue, it's like the whole audio file is choppy. this happens in both the queued and non-queued classes, before and after the above changes were made. I do not think it is a "bass" issue, it happens like more like choppy and gargly throughout all frequencies (but could be wrong). Also, this happens on iPhone with earbuds, but not on Android with earbuds! When going line-in to my PC (instead of earbuds), they both sound like this. With Android and earbuds the sound quality is much better!!! |
I noticed that the original design from Espressif was working with different task priorities. I changed the approach and made sure that all tasks are running with the same priority and I am forcing a task switch with yield(). I have also added some more debug log statements which print the size of the audio data. This should make it possible to find if there are any differences between Apple and Android (in debug level). See A2DP_DEBUG_AUDIO in config.h This changes have been committed in the issue-apple branch. I am wondering if this helps even when using the BluetoothA2DPSink class. I am getting the same audio effect like you when I use the debug log level, so when testing the audio quality I recommend to use the Warning or Info log level. I have also updated the Optimizations Chapter in the Wiki.... |
First pass, the audio is still the same as before, but....
See below logs.. IPhone:
Android:
It seems like iPhone is keeping the write_data at 4096, while Android has it go up and down, 3584 or 3072... Does this mean anything to you conceptually on what I should change? I'm using default values from the iphone branch.
This was useful... Let me know if you think I should change any of these values based on that log.... I'm tempted to try setting MAX_PRIORITIES higher... but I should be addressing something with that changing data callback I read what you wrote about newer versions of Espressif using more RAM. I should probably test with an older version of Espressif at some point... |
I tend to think that in this case the i2s buffer should be at least 4096 bytes or more. |
I committed the change of making max 1k i2s writes... |
Not sure why these didn't throw as errors before, but a couple typos: Typo on line 1414 of BluetoothA2DPSink.cpp: Should be "BT_TAG" not "BTe_TAG" - said BTe_TAG not declared in scope On 1399: Should be printing "size" not "item_size" for this log statement (?) - said item_size not declared in scope I made those changes and... On iPhone:
On Android:
Audio qualities are pretty similar. Without debugging enabled, some pops on Android that are noticeable but come maybe once every 5 seconds. On iOS, a lot more pops, still slightly choppy audio. With debugging enabled, both sound choppy and poppy. You don't think iOS is padding their data with zeros do you? (Imagine how dumb that would be lol). How can I use ESP_LOGD to look at the value of *data? (Sorry, my cpp is pretty bad). |
My mistake, I did not compile with log level Debug For me the audio quality is perfect using my Android phone with log level Info! |
Here's a look at the raw data (from the same point in the same song).... Based on the fact that the values are mostly similar at the end of one array and the beginning of the next array, I wouldn't expect the data stream to be causing the pops (it's good). Much more likely some kind of RAM issue like we've been trying to figure out.... On iPhone:
On Android:
Wondering if it's some knockoff boards now.... |
If you have some SD drive you could save the raw data in a file and analyze it e.g. in Audacity. With my sketch you can also try to analyze it in the Serial Plotter in Arduino Did you check if the BluetoothA2DPSinkQueued makes a difference ? |
I have since tested with a second brand (HiLetGo) and the result is the same, functional (very good) audio for Android, and staticy / delayed volume controls for iOS.
I got an SD card module but the pins were mislabeled and it didn't function, so I will test with another one soon...
I think I will try the SD card instead since I don't know how to do this
Yes many times |
If you are interested, the cheapest phone to test with is the iPhone SE (2020 version). this one goes for about $88: https://www.ebay.com/itm/126111383313?hash=item1d5cd2ff11:g:jM0AAOSwyWdlEzKj&amdata=enc%3AAQAIAAAAwGf3wQcU9TdfnyVYhi6Dl2pmBVlartaIW%2BX%2BJ0V3ZVmaiIJ1XmDmygY1rc7ldXkwIKdtUi1pB5Z6%2B%2BmSK%2Fd31FOpWtFIb%2BuShO87gpLKDGJHAKmt1tbdf5QcVxuosaymsgWSK8vXMypu8l5TwHthQMj%2BoyjCjvNqik1%2F68%2FZaTDCrjgIlF8KKy1YyUM1Yn9GO25IgdyLOv9RtHzIMHrAdJGLwH%2BK1pLLmiPdxRTLK5hj1Oeb25HAw87xqEwaE4c1CA%3D%3D%7Ctkp%3ABk9SR9LuwKfyYg You may be able to find it for cheaper, but this is the cheapest one that I could find that doesn't appear to have a problem (bad screen, missing home button, etc) I stand by my offer that I would donate the money for it!! |
Sorry for this not being directly related to the issue but what iphone are you using and does the audio work otherwise since i cant get audio to work right |
Problem Description
Volume changes are received by the device, but the actual volume doesn't change until the music is paused then played. It doesn't update the volume during streaming.
Based on serial logs, the set_volume inside A2DPVolumeControl doesn't fire when music is playing. Only when you pause the song, will "set_volume" function be fired.
Device Description
ESP32 Wroom https://www.amazon.com/gp/product/B0C7C2HQ7P/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
Sketch
./data/mrhemVolumeControl.h:
Other Steps to Reproduce
I monitored the serial output in the Arduino IDE's Serial Monitor. I press the volume change buttons on the iphone, but "mrhem default Volume is now" does not output. It only outputs much later with the newest value when I pause the stream.
Provide your Version of the EP32 Arduino Core (or the IDF Version)
esp32 by Espressif: 2.0.11
I have checked existing issues, discussions and online documentation
The text was updated successfully, but these errors were encountered: