Exiting arecord in shell script?

So I'm utilizing dancyPi in sync with Raspotify / Librespot. Librespot has hooks so I'm using the follow script:
#!/bin/bash
if [ "$PLAYER_EVENT" = "start" ]; then
  sudo python3 home/pi/dancyPi-audio-reactive-led/python/visualization.py scroll
elif [ "$PLAYER_EVENT" = "stop" ]; then
  sudo python3 home/pi/dancyPi-audio-reactive-led/python/off.py
else
  :
fi

However, I did not realize that the "off.py" script did not kill the mic recording. What would be the best way of freeing up the mic after Spotify stops?

  Let me know if this helps.

I'd create a systemd unit file to run the python scripts as system services. Stopping the service should kill the script. Something like this might do the trick:
#/etc/systemd/system/led-visualization.service
[Unit]
Description=LED visualization
After=network.target

[Service]
Restart=always
RestartSec=10
PermissionsStartOnly=true
ExecStart=/path/to/script/dancyPi-audio-reactive-led/python/visualization.py scroll
ExecStopPost=/path/to/script/dancyPi-audio-reactive-led/python/off.py

[Install]
WantedBy=multi-user.target

And then your event script becomes:
#!/bin/bash
if [ "$PLAYER_EVENT" = "start" ]; then
  sudo systemctl start led-visualization.service
elif [ "$PLAYER_EVENT" = "stop" ]; then
  sudo systemctl stop led-visualization.service
else
  :
fi

You'll ofc have to test it and probably tweak it to make it actually work correctly. The above is just an idea.

@farhandsome you might wait for the libresot update in raspotify it has blocking sink events. They might be more useful because player events are asynchronously emitted in librespot. blocking sink open and close events are probability better in this case.

Not to mention the fact that every time you get an play event you'd be starting another instance of visualization.py if there's nothing preventing multiple instances. The events are basically fire and forget. With the systemd service you'd only ever have one instance, trying to start an already running service in this case doesn't do anything. It just exits. Stopping an already stopped service does the same.

@JasonLG1979 - That's a great idea!

That's a great idea!

To me anything like this that has a good chance of being ran unattended on a headless system screams system service.

@JasonLG1979, @naztronaut
Once again, awesome work! Big shoutout to you both for helping me with this. That's exactly the issue I was having -
Looking at the Raspotify logs, it seems like whenever a new song plays, it actually runs the [ "$PLAYER_EVENT" = "playing" ] twice - this created a problem since the visualization.py script fired twice in quick succession which really screwed with my LEDs.
That's why I limited myself to only using the start and stop events. But with this code from @JasonLG1979 , it looks like I can fine-tune it a little bit more and run the visuals when Spotify plays a song or when Spotify pauses/stops.
If I'm getting this correctly -if visualization.py is already running and a new event comes with value playing, it won't run the visual script again? Because that would be ideal.
I'll run these scripts when I get a chance and debug!

If I'm getting this correctly -if visualization.py is already running and a new event comes with value playing, it won't run the visual script again? Because that would be ideal.

Yes. There will only ever be one instance of  visualization.py.

It would be better though if the LED controller could be pointed at an output instead of a mic input. Or at least able to point to a mic other than default. If we can point it to a arbitrary input we can use snd-aloop to split the output and loop it to an input.

@naztronaut, is it possible to send the audio output to some file, and use that rather than a mic input?

is it possible to send the audio output to some file, and use that rather than a mic input?

I'll look at the script and see if we can't just listen to a different capture device besides default. If we can (I don't really see why not?) a loopback device would be much better than a pipe file.

If you used a loopback you wouldn't have to worry about starting and stopping it. It could just always run and it would only react to what's playing.
Basically:
Whatever makes noise ---> duplicate the audio ---> one copy goes to the sound card / copy goes to our virtual mic that the LED controller is listening to. The LED controller would have nothing to do with your actual real mic.

    # Start listening to live audio stream
    microphone.start_stream(microphone_update)

This is at the end of the visualization code - it looks like this stream is what feeds into the GUI curve? Feedback into the led.
Also @naztronaut, sorry for hijacking a thread!! Hope it's ok that we're dissecting your code.

No worries! I wish I could take credit for all that code but only a few customizations are mine :) Most of the original code is by Scott Lawson.

https://sysplay.in/blog/linux/2019/06/playing-with-alsa-loopback-devices/
This may be of use. An example of how to create a virtual card to capture audio from a different output.
Perhaps we can clone the USB DAC audio output and use that file for visualization?

snd-aloop is the kernel module for setting up virtual audio loopback devices.

$ sudo modprobe snd-aloop
creates two devices 0 & 1 under a new “Loopback” card for both playback & capturing, as shown below, respectively:

``

If we can use the "capture" loopback, it could replace the mic input for the `visualization.py` structure?

After some time of researching I finally managed to get it work. I'm running shairport-sync and the visualizer (besides a homebridge server) on my raspberry pi 2 model b feeding the audio from shairport in the visualizer and also my speaker using alsa. The visualization runs at 25 fps smoothly (oddly tho it stutters at lower or higher framerates). I have to say, that I don't power the LEDs by the raspberry pi itself, but let it do the computing and then sent the commands to an ESP-01 to light up the LEDs. So the visualizer is running in the ESP8266 configuration.
Here is what I did to use the audio output as an input (from a fresh raspbian buster install):
First set up your usb-audio card as the default device in Alsa as described in the readme. Check whether you can play sound from it.
Set up the alsa loopback device:
sudo modprobe snd-aloop
it will show up in
aplay -l
as "Loopback"
Then edit your /etc/asound.conf (and maybe .asoundrc although I think it gets overridden by the global asound.conf) and add:
#this will set your default output to a virtual virtual multi-channel device named CardAndLoop, which outputs to your USB-Card as well as the Loopback device
#Furthermore it sets the second Loopback device as your standard input
pcm.!default {
  type asym
  playback.pcm "CardAndLoop"
  capture.pcm "hw:Loopback,1"
}

# This is the interface you use for sound output
# It will send the output to the soundcard and loopback device
pcm.CardAndLoop {
  type plug
  slave.pcm MultiCh
  route_policy "duplicate"
}

ctl.!default {
        type hw
        card 0 #set it to your Audio-Card
}

# Virtual multichannel device with four channels
# two the for the soundcard, two for the loopback
pcm.MultiCh {
  type multi
  slaves.a.pcm pcm.MixCard
  slaves.a.channels 2
  slaves.b.pcm pcm.MixLoopback
  slaves.b.channels 2
  bindings.0.slave a
  bindings.0.channel 0
  bindings.1.slave a
  bindings.1.channel 1
  bindings.2.slave b
  bindings.2.channel 0
  bindings.3.slave b
  bindings.3.channel 1
}

# Mixer for the soundcard
pcm.MixCard {
  type dmix
  ipc_key 1024
  slave {
    pcm "hw:PCH,0" #edit to set it to your Audio Card
#    rate 48000
    rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

# Mixer for the loopback
pcm.MixLoopback {
  type dmix
  ipc_key 1025
  slave {
    pcm "hw:Loopback,0"
#    rate 48000
    rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

Remember to set your USB-Audio-Card as the pcm device in the Mixer for the soundcard. Read the first article below to learn how to address audio devices in Alsa.
As everything sent to hw:Loopback,0 is also played on hw:Loopback,1, you will now have your audio output also available as an input (and on the speaker).
You can check if everything is working by opening a second terminal window and playing sound to the default output while recording audio from the default input in the other window.
speaker-test -c2 in window 1
arecord -f S16_LE -c 2 -r 44000 audio.wav in window 2
If everything works, make the Loopback device persistent:
sudo echo 'snd-aloop' >> /etc/modules
Now you can install shairport-sync (or use your desired audio input).
Don't hesitate if pyaudio throws some errors. Most of them are only informative and everything should work nevertheless.
These articles helped a lot:
https://sysplay.in/blog/linux/2019/06/playing-with-alsa-loopback-devices/
https://unix.stackexchange.com/questions/175649/send-sound-output-to-application-and-speaker
https://www.alsa-project.org/wiki/Asoundrc
Good luck!

#

After some time of researching I finally managed to get it work. I'm running shairport-sync and the visualizer (besides a homebridge server) on my raspberry pi 2 model b feeding the audio from shairport in the visualizer and also my speaker using alsa. The visualization runs at 25 fps smoothly (oddly tho it stutters at lower or higher framerates). I have to say, that I don't power the LEDs by the raspberry pi itself, but let it do the computing and then sent the commands to an ESP-01 to light up the LEDs. So the visualizer is running in the ESP8266 configuration.
Here is what I did to use the audio output as an input (from a fresh raspbian buster install):
First set up your usb-audio card as the default device in Alsa as described in the readme. Check whether you can play sound from it.
Set up the alsa loopback device:
sudo modprobe snd-aloop
it will show up in
aplay -l
as "Loopback"
Then edit your /etc/asound.conf (and maybe .asoundrc although I think it gets overridden by the global asound.conf) and add:
#this will set your default output to a virtual virtual multi-channel device named CardAndLoop, which outputs to your USB-Card as well as the Loopback device
#Furthermore it sets the second Loopback device as your standard input
pcm.!default {
  type asym
  playback.pcm "CardAndLoop"
  capture.pcm "hw:Loopback,1"
}

# This is the interface you use for sound output
# It will send the output to the soundcard and loopback device
pcm.CardAndLoop {
  type plug
  slave.pcm MultiCh
  route_policy "duplicate"
}

ctl.!default {
        type hw
        card 0 #set it to your Audio-Card
}

# Virtual multichannel device with four channels
# two the for the soundcard, two for the loopback
pcm.MultiCh {
  type multi
  slaves.a.pcm pcm.MixCard
  slaves.a.channels 2
  slaves.b.pcm pcm.MixLoopback
  slaves.b.channels 2
  bindings.0.slave a
  bindings.0.channel 0
  bindings.1.slave a
  bindings.1.channel 1
  bindings.2.slave b
  bindings.2.channel 0
  bindings.3.slave b
  bindings.3.channel 1
}

# Mixer for the soundcard
pcm.MixCard {
  type dmix
  ipc_key 1024
  slave {
    pcm "hw:PCH,0" #edit to set it to your Audio Card
#    rate 48000
    rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

# Mixer for the loopback
pcm.MixLoopback {
  type dmix
  ipc_key 1025
  slave {
    pcm "hw:Loopback,0"
#    rate 48000
    rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

Remember to set your USB-Audio-Card as the pcm device in the Mixer for the soundcard. Read the first article below to learn how to address audio devices in Alsa.
As everything sent to hw:Loopback,0 is also played on hw:Loopback,1, you will now have your audio output also available as an input (and on the speaker).
You can check if everything is working by opening a second terminal window and playing sound to the default output while recording audio from the default input in the other window.
speaker-test -c2 in window 1
arecord -f S16_LE -c 2 -r 44000 audio.wav in window 2
If everything works, make the Loopback device persistent:
sudo echo 'snd-aloop' >> /etc/modules
Now you can install shairport-sync (or use your desired audio input).
Don't hesitate if pyaudio throws some errors. Most of them are only informative and everything should work nevertheless.
These articles helped a lot:
https://sysplay.in/blog/linux/2019/06/playing-with-alsa-loopback-devices/
https://unix.stackexchange.com/questions/175649/send-sound-output-to-application-and-speaker
https://www.alsa-project.org/wiki/Asoundrc
Good luck!

@farhandsome Are you quoting someone with that last post because it's all inside block quotes, or did you end up getting it to work?

@JasonLG1979,
Nope just quoting someone. I'll be trying this out, but I may need some help in reconfiguring the asound.conf file so I can integrate this stuff with all the custom stuff that you've put into the file.

Nope just quoting someone. I'll be trying this out, but I may need some help in reconfiguring the asound.conf file so I can integrate this stuff with all the custom stuff that you've put into the file.

I'll give it a shot. I played with it a little last night but so far no luck. I'll figure it out. But yes the general idea is for the loopback to replace the real mic so the LED listens to what comes out of your speakers not what comes in the mic. that way alexa is really the only thing that needs the mic.

It's not simple. There has to be 2 instances of dmix. One for the real sound card so you can hear stuff and one for the loopback. And then 2 instances of dsnoop one for the real mic and one for the lookback if you want more than one thing to be able to access the loopback. The idea too is to skip the output splitter for the alexa output so that it's not feed back it's own voice. There's also going to be LoopbackCapture and LoopbackPCM volume controls so you can adjust the loopback levels as to not saturate (distort) the loopback.

There's also going to be LoopbackCapture and LoopbackPCM volume controls so you can adjust the loopback levels as to not saturate (distort) the loopback.<

Is there a way to utilize the Raspotify hooks to only capture onto the virtual card while Raspotify is playing?

Is there a way to utilize the Raspotify hooks to only capture onto the virtual card while Raspotify is playing?

It's easier to just have alexa not go though the loopback at all.

ExecStart=/path/to/script/dancyPi-audio-reactive-led/python/visualization.py scroll
ExecStopPost=/path/to/script/dancyPi-audio-reactive-led/python/off.py<

Do I need to run this as python3 ?

Nevermind. But for some reason the code isn't running... I get this error:
● led-visualization.service - LED visualization
   Loaded: loaded (/etc/systemd/system/led-visualization.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Thu 2020-11-05 17:16:59 CST; 5s ago
  Process: 1273 ExecStart=/home/pi/dancyPi-audio-reactive-led/python/visualization.py scroll -c (code=exited, status=203/EXEC)
  Process: 1274 ExecStopPost=/home/pi/dancyPi-audio-reactive-led/python/off.py (code=exited, status=203/EXEC)
 Main PID: 1273 (code=exited, status=203/EXEC)

@farhandsome I haven't forgot about you, getting all this loopback stuff to work was a PITA,lol!!!. I've finally got it working so that what comes out the speakers is duplicated as the default capture device so that the LED controls won't be going off your mic but what's playing, and alexa will be listening to the mic.
I have a couple questions for you:
Does anything else need access to the mic?
Does anything else need access to the loopback?

Wow awesome! Can’t wait to test it out.
No I don’t think so. Alexa is the only voice service I’ll be using and Spotify is the only audio I want to record.

I ask because in particular with the loopback that the LED controls are listening to we can get rid of the dsnoop plugin that wraps it and drop the latency of the LEDs if nothing else is going to use it. I can get down to about a 125ms buffer size at 48k (so a latency of about 1/8 of a sec) before I get dropouts and audible glitches on my pi zero so you should have no problems getting down to that but ofc the less the better. You want the lights moving to the music not after the music,lol!!! I have no idea what kind of latency controller scripts add?

If it makes any difference, the mic is also a webcam which I’d like to mess with in the future.

If it makes any difference, the mic is also a webcam which I’d like to mess with in the future.

No problem I can keep the dsnoop on the mic and just name the pcm webcam so you remember which input is the webcam. The input latency isn't a huge deal it's more an issue with the loopback so the lights are more in sync to the audio.
Give me just a sec to modify and test out the script and I'll post it.

Ok 1st if you've tested out any other my asound.conf's You have to jump though a hoop to get ALSA to forget the old software volume controls before you use this one.
sudo rm /var/lib/alsa/asound.state
sudo rm /etc/asound.conf
sudo chmod -x /usr/sbin/alsactl

Reboot
sudo chmod +x /usr/sbin/alsactl

Reboot again
And then copy and paste this into  /etc/asound.conf:
# /etc/asound.conf

# use aplay -l to determine the below.

# Change to the card number or name that you want to be the default control card.
# Default: 0
defaults.ctl.card 1

# Change to the card number or name that you want to be the default playback card.
# It should usually be the same as defaults.ctl.card.
# Default: 0
defaults.pcm.card 1

# Change to the device number that you want to be the default device on the default card.
# 0 or 1 is usually the correct device number.
# Default: 0
defaults.pcm.device 0

# Change to the subdevice number that you want to be the default subdevice on the default device.
# Should rarely need to be changed.
# Default: -1
defaults.pcm.subdevice -1

# To install high quality samplerate converters on Debian based systems:
# sudo apt install -y --no-install-recommends libasound2-plugins

# To list available rate converters:
# echo "$(ls /usr/lib/*/alsa-lib | grep "libasound_module_rate_")" | sed -e "s/^libasound_module_rate_//" -e "s/.so$//"

# Uncomment and replace speexrate_medium with the rate_converter of your choice. (speexrate and speexrate_medium offer the best "bang for your buck")
# defaults.pcm.rate_converter speexrate_medium

pcm.playback {
    type hw
    nonblock {
        @func refer
        name defaults.pcm.nonblock
    }
    card {
        @func refer
        name defaults.pcm.card
    }
    device {
        @func refer
        name defaults.pcm.device
    }
    subdevice {
        @func refer
        name defaults.pcm.subdevice
    }
}

pcm.capture {
    type hw
    nonblock {
        @func refer
        name defaults.pcm.nonblock
    }
    card 2
    device 0
    subdevice -1
}

pcm.loopback0 {
    type hw
    nonblock {
        @func refer
        name defaults.pcm.nonblock
    }
    card Loopback
    device 0
    subdevice -1
}

pcm.loopback1 {
    type hw
    nonblock {
        @func refer
        name defaults.pcm.nonblock
    }
    card Loopback
    device 1
    subdevice -1
}

pcm.playbackdmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1024
    slave {
        pcm playback
        channels 2
        rate 48000
        format S16_LE
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 31250
        periods 4
    }
    bindings {
        0 0
        1 1
    }
}

pcm.loopbackdmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1025
    slave {
        pcm loopback0
        channels 1
        rate 48000
        format S16_LE
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 31250
        periods 4
    }
    bindings {
        0 0
    }
}

pcm.webcam {
    type plug
    slave.pcm {
        type softvol
        # up to 20dB of mic boost.
        max_dB 20.0
        control {
            name Capture
            card {
                @func refer
                name defaults.ctl.card
            }
        }
        slave.pcm {
            type dsnoop
            ipc_key_add_uid false
            ipc_perm 0666
            ipc_key 1026
            slave {
                pcm capture
                channels 1
                rate 16000
                format S16_LE
                period_size 0
                buffer_size 0
                buffer_time 0
                period_time 31250
                periods 4
            }
            bindings {
                0 0
            }
        }
    }
}

pcm.loopbackdsnooper {
    type plug
    slave.pcm {
        type dsnoop
        ipc_key_add_uid false
        ipc_perm 0666
        ipc_key 1027
        slave {
            pcm loopback1
            channels 1
            rate 48000
            format S16_LE
            period_size 0
            buffer_size 0
            buffer_time 0
            period_time 31250
            periods 4
        }
        bindings {
            0 0
        }
    }
}

pcm.playbacksplitter {
    type plug
    slave.pcm {
        type multi
        slaves.playback.pcm playbackdmixer
        slaves.playback.channels 2
        slaves.loopback.pcm loopbackdmixer
        slaves.loopback.channels 1
        bindings.0.slave playback
        bindings.0.channel 0
        bindings.1.slave playback
        bindings.1.channel 1
        bindings.2.slave loopback
        bindings.2.channel 0
    }
    ttable {
        0.0 1
        1.1 1
        0.2 0.5
        1.2 0.5
    }
}

# Default input and output.
pcm.!default {
    type asym
    playback.pcm playbacksplitter
    capture.pcm loopback1
}

ctl.!default {
    type hw
    card {
        @func refer
        name defaults.ctl.card
    }
}

# Output only.
pcm.bluetooth {
    type softvol
    slave.pcm playbacksplitter
    control {
        name bluetooth
        card {
            @func refer
            name defaults.ctl.card
        }
    }
}

# Output only.
pcm.spotify {
    type softvol
    slave.pcm playbacksplitter
    control {
        name spotify
        card {
            @func refer
            name defaults.ctl.card
        }
    }
}

# Output and input.
pcm.alexa {
    type asym
    capture.pcm webcam
    playback.pcm {
        type softvol
        slave.pcm playbacksplitter
        control {
            name alexa
            card {
                @func refer
                name defaults.ctl.card
            }
        }
    }
}

As usual to get the software volume controls to show up on the inputs and outputs you have to use them at least once (aplay/arecord).
All the inputs will play whatever you throw at them and as many things as you'd like can listen to the webcam and alexa mic (they're the same thing) and they will output whatever they're asked for for as far as format and sampling rate. But the default default loopback mic can only be used by on thing at a time (the LED controls) and only outputs 1 channel mono (50% of the left and 50% of the right of what's playing over the speakers) at 16 bit 48k.
You'll need to add snd-aloop to /etc/modules to make sure the loopback module is loaded at boot. You'll also need to check to make sure to use the right card and device numbers. The config above assumes that loopback is 0 (it's named so you shouldn't need to change it) your sound card is 1 and your webcam is 2. that just happened to be the way they landed on my system.

Alrighty I got some work on my hands!!
I actually just did a fresh install this morning so I’m gonna try this out from scratch. I’ll start with reinstalling the LED modules and working my way down.

You can experiment with the buffer size by changing the number next to every place you see  period_time I'd keep it multiples of the current value so basically divide the current value by 2 until you get drop outs and use the last good value. They all have to be the same though. I found that out the hard way. That's what took me so long.

What’s the benefit of a lower buffer size?

What’s the benefit of a lower buffer size?

Buffers introduce latency. Latency is a delay. The difference between when the audio program sends the sound and when it is heard. It's not a big deal when you're just listening to music but it is if you're recording. So if the webcam's audio has to be in sync with the video you want to match their latency. If you're just using the audio from the webcam for now I'd go for a big buffer something like 1 sec so 250000 for a period_time. A higher buffer means smoother audio and less CPU usage. Since the LED controls doesn't have a buffer on the loopback the only latency there is whatever the python script introduces.

I mean ofc there will be latency between when the sound is generated and heard and seen but since both dmixers have the same buffer size they'll more or less be in sync.

@JasonLG1979, am I needed to enable snd-aloop with sudo modprobe snd-aloop?

@JasonLG1979,
Nevermind, got it up and running and persisted the modules file. So going off this - the LED visualization won't go off the microphone anymore right? Cause I tried running the LED visualization again and it gives me an error that there's no audio output.
I'm assuming I have to have Raspotify running now to actually utilize the LED visualization?

am I needed to enable snd-aloop with sudo modprobe snd-aloop?

You have to add snd-aloop to a new line in /etc/modules and then reboot.

I'm assuming I have to have Raspotify running now to actually utilize the LED visualization?

It should be. Try this one I wrapped the default capture in a plug so it shouldn't matter what an app asks for as far as sample rate format or channel count. Read the file and follow the instructions in the comments you may need to change the card numbers to make it work. You can test it by playing some audio and using arecord -d10 -fdat -twav test.wav  and then playback the test with aplay test.wav it should be a recording of what was played while it was recorded:
# /etc/asound.conf

# add snd-aloop to /etc/modules
# use aplay -l to determine the below.

# Change to the card number or name that you want to be the default control card.
# Default: 0
defaults.ctl.card 1

# Change to the card number or name that you want to be the default playback card.
# It should usually be the same as defaults.ctl.card.
# Default: 0
defaults.pcm.card 1

# Change to the device number that you want to be the default device on the default card.
# 0 or 1 is usually the correct device number.
# Default: 0
defaults.pcm.device 0

# Change to the subdevice number that you want to be the default subdevice on the default device.
# Should rarely need to be changed.
# Default: -1
defaults.pcm.subdevice -1

# To install high quality samplerate converters on Debian based systems:
# sudo apt install -y --no-install-recommends libasound2-plugins

# To list available rate converters:
# echo "$(ls /usr/lib/*/alsa-lib | grep "libasound_module_rate_")" | sed -e "s/^libasound_module_rate_//" -e "s/.so$//"

# Uncomment and replace speexrate_medium with the rate_converter of your choice. (speexrate and speexrate_medium offer the best "bang for your buck")
# defaults.pcm.rate_converter speexrate_medium

pcm.playback {
    type hw
    card {
        @func refer
        name defaults.pcm.card
    }
    device {
        @func refer
        name defaults.pcm.device
    }
    subdevice {
        @func refer
        name defaults.pcm.subdevice
    }
}

pcm.capture {
    type hw
    # Change this to the mic
    # you want to use based on arecord -l
    card 2
    device 0
    subdevice -1
}

pcm.loopback0 {
    type hw
    card Loopback
    device 0
    subdevice -1
}

pcm.loopback1 {
    type hw
    card Loopback
    device 1
    subdevice -1
}

pcm.playbackdmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1024
    slave {
        pcm playback
        channels 2
        rate 48000
        format S16_LE
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 250000
        periods 4
    }
    bindings {
        0 0
        1 1
    }
}

pcm.loopbackdmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1025
    slave {
        pcm loopback0
        channels 2
        rate 48000
        format S16_LE
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 250000
        periods 4
    }
    bindings {
        0 0
        1 1
    }
}

pcm.webcam {
    type plug
    slave.pcm {
        type softvol
        # up to 20dB of mic boost.
        max_dB 20.0
        control {
            name Capture
            card {
                @func refer
                name defaults.ctl.card
            }
        }
        slave.pcm {
            type dsnoop
            ipc_key_add_uid false
            ipc_perm 0666
            ipc_key 1026
            slave {
                pcm capture
                channels 1
                rate 16000
                format S16_LE
                period_size 0
                buffer_size 0
                buffer_time 0
                period_time 250000
                periods 4
            }
            bindings {
                0 0
            }
        }
    }
}

pcm.loopbackdsnooper {
    type plug
    slave.pcm {
        type dsnoop
        ipc_key_add_uid false
        ipc_perm 0666
        ipc_key 1027
        slave {
            pcm loopback1
            channels 1
            rate 48000
            format S16_LE
            period_size 0
            buffer_size 0
            buffer_time 0
            period_time 250000
            periods 4
        }
        bindings {
            0 0
        }
    }
}

pcm.playbacksplitter {
    type plug
    slave.pcm {
        type multi
        slaves.playback.pcm playbackdmixer
        slaves.playback.channels 2
        slaves.loopback.pcm loopbackdmixer
        slaves.loopback.channels 2
        bindings.0.slave playback
        bindings.0.channel 0
        bindings.1.slave playback
        bindings.1.channel 1
        bindings.2.slave loopback
        bindings.2.channel 0
        bindings.3.slave loopback
        bindings.3.channel 1
    }
    ttable {
        0.0 1
        1.1 1
        0.2 1
        1.3 1
    }
}

# Default input and output.
pcm.!default {
    type asym
    playback.pcm playbacksplitter
    capture.pcm {
        type plug
        slave.pcm loopback1
    }
}

ctl.!default {
    type hw
    card {
        @func refer
        name defaults.ctl.card
    }
}

# Output only.
pcm.bluetooth {
    type softvol
    slave.pcm playbacksplitter
    control {
        name bluetooth
        card {
            @func refer
            name defaults.ctl.card
        }
    }
}

# Output only.
pcm.spotify {
    type softvol
    slave.pcm playbacksplitter
    control {
        name spotify
        card {
            @func refer
            name defaults.ctl.card
        }
    }
}

# Output and input.
pcm.alexa {
    type asym
    capture.pcm webcam
    playback.pcm {
        type softvol
        slave.pcm playbacksplitter
        control {
            name alexa
            card {
                @func refer
                name defaults.ctl.card
            }
        }
    }
}

Gotcha! I haven't tried out the latest sound.config, but here's a status report:

Successfully installed LED visuals
Overwrote /etc/asound.conf
LED visualizations work successfully with loopback audio (I do get some warning messages about bluealsa(? - weird since I haven't configured bluetooth after doing a refresh install), but nothing breaks it
I finally got the system service unit files to fire (@naztronaut - the visualization.py code is missing a shebang line at the very beginning. Adding this allowed the python script to be ran as a service)

So far so good! No roadblocks yet. Next step is reinstalling and configuring Alexa with the LED indicator scripts. I am not sure if we ever discussed this -
How do I go about pausing Raspotify from the command line? I'd like to add this into the Alexa hooks so once Alexa is triggered, it pauses Spotify and then replays once Alexa has gone through her sequence.

Alexa with the LED indicator scripts. I am not sure if we ever discussed this

We have not. Alexa's output is already routed though to the LEDs so you'll already get a Knight Rider like effect when Alexa speaks.

How do I go about pausing Raspotify from the command line? I'd like to add this into the Alexa hooks so once Alexa is triggered, it pauses Spotify and then replays once Alexa has gone through her sequence.

You can't. It's not designed to be able to be controlled. You'd have to find or create your own way to interact with the Spotify web api. In the meantime the best you can do is mute the volume while alexa speakers. amixer sset 'spotify' 0 and then unmute it when it's done amixer sset 'spotify' 255 provided you route raspotify/librespot though the spotify output. Bluetooth would work the same way.

You might see if you can get an early notification as to when alexa is going to speak so you can fade the volume and/or have a little gap of silence between the music and when it speaks so it's not so much of an abrupt change.

@JasonLG1979
Running into an error now - Alexa not recognizing any mic input. I went through the default install of Alexa outlined here: https://developer.amazon.com/en-US/docs/alexa/avs-device-sdk/raspberry-pi.html#run-and-authorize-the-sample-app
Unsure what I need to get it to get it to use the devices laid out in /etc/asound.conf.
The instructions include an edit for asoundrc but I didn't do that step cause I was thinking the global config would take care of it.

Unsure what I need to get it to get it to use the devices laid out in /etc/asound.conf.
The instructions include an edit for asoundrc but I didn't do that step cause I was thinking the global config would take care of it.

If you're running alexa as a user you may be able to define default for that user as the alexa pcm from the system wide config.
Try this in your asoundrc:
pcm.!default {
    type plug
    slave.pcm alexa
}

Going back to to the led controls could you make sure they're getting a mono signal from the loopback and not just the right or left channel by running speaker-test -c2 -l2 and make sure you get lights for both left and right tests. If not I can change the channel routing in pcm.playbacksplitter to fix it.

I kinda want to get some of these LEDs for my self now to add some bling to my stereo,lol!!! I'd just have to figure out what pins my dac hat uses so I could make sure to use different ones to control the LEDs. I'm fair at python so I could help with the coding bit. It would also be cool to be able to control 2 sets of LEDs for a stereo effect.

We have not. Alexa's output is already routed though to the LEDs so you'll already get a Knight Rider like effect when Alexa speaks.

Very tempting lol, but I'm actually going to kill the visualization script when Alexa comes on and run my own modified version of it. I'm looking to simulate the those cyan-colored Alexa device lights for her "listening", "thinking" and "speaking" stages. Once she's done, I'll resume Spotify and restart up the lights. I suppose this will all have to be wrapped in an if-statement to see if Raspotify is even running or not. As far as the amixer sset 'spotify' 0 command - can I just run that in a timed loop to get more of a "fade" effect?

Going back to to the led controls could you make sure they're getting a mono signal from the loopback

Yeah sure, I'll run that tonight and let you know the results.

It would also be cool to be able to control 2 sets of LEDs for a stereo effect.

Check out: https://github.com/jgarff/rpi_ws281x
One of the examples in the Python folder is labelled multistrandtest.py for controlling two LED strips at once. You could probably use a modified version of this to control multiple LED's to your liking!

Very tempting lol, but I'm actually going to kill the visualization script when Alexa comes on and run my own modified version of it. I'm looking to simulate the those cyan-colored Alexa device lights for her "listening", "thinking" and "speaking" stages. Once she's done, I'll resume Spotify and restart up the lights. I suppose this will all have to be wrapped in an if-statement to see if Raspotify is even running or not. As far as the amixer sset 'spotify' 0 command - can I just run that in a timed loop to get more of a "fade" effect?

Sure I don't see why you couldn't fade the volume with a loop in a bash or python.

One of the examples in the Python folder is labelled multistrandtest.py for controlling two LED strips at once. You could probably use a modified version of this to control multiple LED's to your liking!

As soon as I get some disposable income again I'm going to get me some,lol!!! Maybe if congress EVER passes another economic relief package (I live in the US) or maybe tax refund time?

Lol I hope so. I'm down in Texas. Another stim package could convince me to get a nice glass mirror rather than acrylic for this project haha.

Lol I hope so. I'm down in Texas. Another stim package could convince me to get a nice glass mirror rather than acrylic for this project haha.

Right on my mom was born in Texas and I got a lot of family in Oklahoma and Mississippi. I'm in Iowa.

@naztronaut if you're interested this is a simplified version of the asound.conf I wrote for @farhandsome. It allows your scripts to work without a microphone but instead whatever is being played on the Pi controls the LEDs. The output is plug'd and dmix'd so it should play whatever you throw at it and as many sources simultaneously as you'd like. The "mic" (loopback) is dual mono and plug'd so it will give you whatever you like as far sampling rate, and whatnot all that a user would need to do is walk though the steps.
# /etc/asound.conf

# add:
# snd-aloop
# to a new line in /etc/modules
# reboot.

# use aplay -l to determine the below.

# Change to the card number or name that you want to be the default control card.
# Default: 0
defaults.ctl.card 0

# Change to the card number or name that you want to be the default playback card.
# It should usually be the same as defaults.ctl.card.
# Default: 0
defaults.pcm.card 0

# Change to the device number that you want to be the default device on the default card.
# 0 or 1 is usually the correct device number.
# Default: 0
defaults.pcm.device 0

# Change to the subdevice number that you want to be the default subdevice on the default device.
# Should rarely need to be changed.
# Default: -1
defaults.pcm.subdevice -1

# To install high quality samplerate converters on Debian based systems:
# sudo apt install -y --no-install-recommends libasound2-plugins

# To list available rate converters:
# echo "$(ls /usr/lib/*/alsa-lib | grep "libasound_module_rate_")" | sed -e "s/^libasound_module_rate_//" -e "s/.so$//"

# Uncomment and replace speexrate_medium with the rate_converter of your choice. (speexrate and speexrate_medium offer the best "bang for your buck")
# defaults.pcm.rate_converter speexrate_medium

# Find your card's supported format(s) and sampling rate(s) While no other audio is being played:
# aplay -Dhw:<card #>,<device #> --dump-hw-params /usr/share/sounds/alsa/Front_Right.wav
# For example:
# aplay -Dhw:0,0 --dump-hw-params /usr/share/sounds/alsa/Front_Right.wav

# The output should look something like this if the card and device combination is correct:

# ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
# FORMAT:  S16_LE S24_LE S32_LE
# SUBFORMAT:  STD
# SAMPLE_BITS: [16 32]
# FRAME_BITS: [32 64]
# CHANNELS: 2
# RATE: [8000 192000]
# ...

# The above card supports formats S16_LE, S24_LE, and S32_LE, at up to a sampling rate of 192000.

# Change to desired sampling rate and format.
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format S16_LE

pcm.playback {
    type hw
    card {
        @func refer
        name defaults.pcm.card
    }
    device {
        @func refer
        name defaults.pcm.device
    }
    subdevice {
        @func refer
        name defaults.pcm.subdevice
    }
}

pcm.loopback0 {
    type hw
    card Loopback
    device 0
    subdevice -1
}

pcm.loopback1 {
    type hw
    card Loopback
    device 1
    subdevice -1
}

pcm.dmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1024
    slave {
        pcm playback
        channels 2
        rate {
            @func refer
            name defaults.pcm.dmix.rate
        }
        format {
            @func refer
            name defaults.pcm.dmix.format
        }
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 250000
        periods 4
    }
    bindings {
        0 0
        1 1
    }
}

pcm.loopbackdmixer {
    type dmix
    ipc_key_add_uid false
    ipc_perm 0666
    ipc_key 1025
    slave {
        pcm loopback0
        channels 2
        rate {
            @func refer
            name defaults.pcm.dmix.rate
        }
        format {
            @func refer
            name defaults.pcm.dmix.format
        }
        period_size 0
        buffer_size 0
        buffer_time 0
        period_time 250000
        periods 4
    }
    bindings {
        0 0
        1 1
    }
}

pcm.playbacksplitter {
    type plug
    slave.pcm {
        type multi
        slaves.playback.pcm playbackdmixer
        slaves.playback.channels 2
        slaves.loopback.pcm loopbackdmixer
        slaves.loopback.channels 2
        bindings.0.slave playback
        bindings.0.channel 0
        bindings.1.slave playback
        bindings.1.channel 1
        bindings.2.slave loopback
        bindings.2.channel 0
        bindings.3.slave loopback
        bindings.3.channel 1
    }
    ttable {
        # stereo for playback
        0.0 1
        1.1 1
        # dual mono for loopback
        0.2 0.5
        1.2 0.5
        0.3 0.5
        1.3 0.5
    }
}

pcm.!default {
    type asym
    playback.pcm playbacksplitter
    capture.pcm {
        type plug
        slave.pcm loopback1
    }
}

ctl.!default {
    type hw
    card {
        @func refer
        name defaults.ctl.card
    }
}

@JasonLG1979
Not too many updates on my end yet,
I changed the .asoundrc file and Alexa works now which is good! Next step is to integrate those LED’s, create the mute Spotify script, and then should be good to go on fleshing out the Magic Mirror!
Since Raspotify is a Spotify Connect device, will Alexa recognize it as such? As in, I can use Alexa to play/pause music, etc

I changed the .asoundrc file and Alexa works now which is good! Next step is to integrate those LED’s, create the mute Spotify script, and then should be good to go on fleshing out the Magic Mirror!

Awesome!!! When you're done you'll have to post a howto walking though your project so that other's can duplicate it if they'd like.

Since Raspotify is a Spotify Connect device, will Alexa recognize it as such? As in, I can use Alexa to play/pause music, etc

It might? I'm not sure. It's worth a shot though.
So left and right speaker tests worked as far as you got lights for both channels in the test?

Ahh right, I forgot to try that. Will update tonight!

Ahh right, I forgot to try that. Will update tonight!

I'm thinking the plug in front of the loopback should take care of of it but otherwise I can make the loopback dual mono in the playbacksplitter so it doesn't even matter:
    ttable {
        # stereo for playback
        0.0 1
        1.1 1
        # dual mono for loopback
        0.2 0.5 # left to left of loopback at 50% volume
        1.2 0.5 # right to left of loopback at 50% volume
        0.3 0.5 # left to right of loopback at 50% volume
        1.3 0.5 # right to right of loopback at 50% volume
    }

@JasonLG1979 Still haven't gotten a chance to try out a majority of these changes yet... haven't forgotten though! Will update over the next week.

@JasonLG1979 - awesome! Thanks for the modifications to asound.conf - definitely will try it out and probably merge it into a branch for others to use.
Loving the collaboration in this thread! I learned a lot just reading through the conversation.

Loving the collaboration in this thread! I learned a lot just reading through the conversation.

Collaboration is the name of the game when it comes to open source software.
As far as the config in your script I'd set the sampling rate to match defaults.pcm.dmix.rate in the asound.conf to avoid any further resampling in ALSA. If someone were to want to use a different sampling rate (plug will give you whatever you want pretty much) I'd stick to multiples of  defaults.pcm.dmix.rate and change the rate_converter in that instance of plug to something easier on the CPU. Something like this:
pcm.!default {
    type asym
    playback.pcm playbacksplitter
    capture.pcm {
        type plug
        rate_converter samplerate_linear
        slave.pcm loopback1
    }
}

But really a user should probably just stick to the sampling rate specified with defaults.pcm.dmix.rate I would think.

You can also add a software volume control to possibly lower the intensity of the LED effects since it will be looped back from the output and could potentially be a lot hotter then a mic. Something like this should do it:
pcm.!default {
    type asym
    playback.pcm playbacksplitter
    capture.pcm {
        type softvol
        slave.pcm {
            type plug
            slave.pcm loopback1
        }
        control {
            name LEDs
            card {
                @func refer
                name defaults.ctl.card
            }
        }
    }
}

That would give you a slider named 'LEDs' you could use a volume control for the loopback 'mic'.

@JasonLG1979
Finally picking this back up again.

Going back to to the led controls could you make sure they're getting a mono signal from the loopback

Yep, both right and left speakers are working!
Now, onto Alexa. Strangely enough, if I run the code manually, Alexa works fine. But if I stick it in a bash script, she can't hear me. I wonder if it's a permissions issue? I'm creating some scripts to fade in/out the volume from Spotify so once I activate the wake word, Spotify will fade out.
I suppose I need to check whether Spotify was running or not before I turn back on the led-visualizations from Alexa. I don't want to turn on the LED's if Spotify wasn't running in the first place.

provided you route raspotify/librespot though the spotify output

Sorry if I missed how to do this earlier, but it doesn't look like raspotify is routed through spotify output. How can I do that?

Yep, both right and left speakers are working!

Cool.

Now, onto Alexa. Strangely enough, if I run the code manually, Alexa works fine. But if I stick it in a bash script, she can't hear me. I wonder if it's a permissions issue?

It depends on who is running the script pi should see the alexa pcm as default. .asoundrc is user specific so if you're running alexa as anyone else (root for example) it won't work. Once you get everything prototyped so we can see if the plumping works after which we can work on converting everything to systemd units, set up least privileges necessary system users for the different services and what not to make everything neat, clean and proper. We can set the default audio pcm in each service via environment variables.

I suppose I need to check whether Spotify was running or not before I turn back on the led-visualizations from Alexa. I don't want to turn on the LED's if Spotify wasn't running in the first place.

If you don't route alexa's output though the playbacksplitter but just send it straight to playbackdmixer though a plug alexa's audio output won't trigger the led-visualizations so you can just leave it on all the time and not worry about it.
Change the alexa pcm. This should do the trick:
# Output and input.
pcm.alexa {
    type asym
    capture.pcm webcam
    playback.pcm {
        type softvol
        slave.pcm {
            type plug
            slave.pcm playbackdmixer
        }
        control {
            name alexa
            card {
                @func refer
                name defaults.ctl.card
            }
        }
    }
}

Sorry if I missed how to do this earlier, but it doesn't look like raspotify is routed through spotify output. How can I do that?

Add --device spotify in the OPTIONS sections in /etc/default/raspotify

@JasonLG1979
Hmm... will my custom Alexa scripts interfere with the led-visualization script if they are both simultaneously activated?
for i in {255..-10..0}
  do
     amixer sset 'spotify' i
  done

Also oddly enough, this simple loop doesn't do anything.. not sure where I see error logs for bash

Also oddly enough, this simple loop doesn't do anything.. not sure where I see error logs for bash

spotify is a softvol. You have to use use it at least once for it to show up. So do speaker-test -Dspotify -c2 -l1 to make it shows up and make sure it works.

I am no bash wizard so take my advice with that in mind but I do know that amixer will return almost instantly so unless you put some sleeps in there so the fade is even noticeable. Try this:

#!/bin/bash
for i in {255..0}
  do
     amixer sset 'spotify' $i >/dev/null 2>&1
     sleep 0.004
  done

It should take about 1 second-ish for the volume to fade out. you can play with the sleep value to get it the way you like.

Hmm... will my custom Alexa scripts interfere with the led-visualization script if they are both simultaneously activated?

I have no idea?

You could also try this?:
#!/bin/bash
for i in {100..0}
    do
        amixer --quiet sset 'spotify' "$i%"
    done

@JasonLG1979
Finally getting some time to sit down and do this again. What is the purpose of the --quiet syntax?

@JasonLG1979
So close to finishing...
One more roadblock - the Alexa runs through normally unless Spotify is playing. If it is, Alexa will error out on the "speaking" phase. The error code looks like this:
2020-11-24 00:34:36.239 [ 17] I DirectiveSequencer:onDirective:directive=namespace\:SpeechRecognizer\,name\:StopCapture\,messageId\:6125729d-a439-4436-ad2f-68abf48a3346\,dialogRequestId\:38e767d8-c7bb-4120-804b-4135275c7ada\,correlationToken\:\,eventCorrelationToken\:\,payloadVersion\:\,instance\:
2020-11-24 00:34:36.240 [ 1c] I DirectiveRouter:preHandleDirective:messageId=6125729d-a439-4436-ad2f-68abf48a3346,action=calling
2020-11-24 00:34:36.240 [ 1d] I DirectiveRouter:handleDirective:messageId=6125729d-a439-4436-ad2f-68abf48a3346,action=calling
2020-11-24 00:34:36.250 [ 17] I DirectiveSequencer:onDirective:directive=namespace\:SpeechRecognizer\,name\:SetEndOfSpeechOffset\,messageId\:c97ab42e-27d9-492d-aaaa-f0388fa65b75\,dialogRequestId\:38e767d8-c7bb-4120-804b-4135275c7ada\,correlationToken\:\,eventCorrelationToken\:\,payloadVersion\:\,instance\:
2020-11-24 00:34:36.250 [ 17] I DirectiveSequencer:onDirective:directive=namespace\:InteractionModel\,name\:RequestProcessingStarted\,messageId\:516d6160-78dd-4ace-a35a-a59a6b31a1ca\,dialogRequestId\:38e767d8-c7bb-4120-804b-4135275c7ada\,correlationToken\:\,eventCorrelationToken\:\,payloadVersion\:\,instance\:
2020-11-24 00:34:36.250 [ 1c] I DirectiveRouter:preHandleDirective:messageId=c97ab42e-27d9-492d-aaaa-f0388fa65b75,action=calling
2020-11-24 00:34:36.250 [ 1c] I DirectiveRouter:preHandleDirective:messageId=516d6160-78dd-4ace-a35a-a59a6b31a1ca,action=calling
2020-11-24 00:34:36.251 [ 1d] I DirectiveRouter:handleDirective:messageId=c97ab42e-27d9-492d-aaaa-f0388fa65b75,action=calling
2020-11-24 00:34:36.252 [ 1d] I DirectiveRouter:handleDirective:messageId=516d6160-78dd-4ace-a35a-a59a6b31a1ca,action=calling
###########################
#       Thinking...       #
###########################

2020-11-24 00:34:36.592 [ 17] I DirectiveSequencer:onDirective:directive=namespace\:SpeechSynthesizer\,name\:Speak\,messageId\:f0cb2ad6-667f-473f-98a4-ffe3fc6f84cf\,dialogRequestId\:38e767d8-c7bb-4120-804b-4135275c7ada\,correlationToken\:\,eventCorrelationToken\:\,payloadVersion\:\,instance\:
2020-11-24 00:34:36.592 [ 1c] I DirectiveRouter:preHandleDirective:messageId=f0cb2ad6-667f-473f-98a4-ffe3fc6f84cf,action=calling
2020-11-24 00:34:36.593 [ 1d] I DirectiveRouter:handleDirective:messageId=f0cb2ad6-667f-473f-98a4-ffe3fc6f84cf,action=calling
2020-11-24 00:34:36.599 [ 1e] E MediaPlayer:handlePlayFailed:name=SpeakMediaPlayer:reason=gstElementSetStateFailure
2020-11-24 00:34:36.599 [ 1e] E MediaPlayer:getCurrentStreamOffsetFailed:name=SpeakMediaPlayer,reason=getElementGetStateFailure
2020-11-24 00:34:36.599 [ 1e] E MediaPlayer:getCurrentStreamOffsetFailed:name=SpeakMediaPlayer,reason=getElementGetStateFailure
2020-11-24 00:34:36.599 [ 1e] E MediaPlayer:handleBusMessageError:name=SpeakMediaPlayer,source=audio_sink,error=Could not open audio device for playback.,debug=gstalsasink.c(865)\: gst_alsasink_open ()\: /GstPipeline\:audio-pipeline/GstAlsaSink\:audio_sink\:
Playback open error on device 'default'\: Invalid argument
2020-11-24 00:34:36.600 [ 1b] W UUIDGeneration:low entropy on call to generate UUID:current entropy=32
2020-11-24 00:34:37.131 [ 17] I DirectiveSequencer:onDirective:directive=namespace\:InteractionModel\,name\:RequestProcessingCompleted\,messageId\:3e94f324-9b93-47da-a548-6b2ba95b6c77\,dialogRequestId\:38e767d8-c7bb-4120-804b-4135275c7ada\,correlationToken\:\,eventCorrelationToken\:\,payloadVersion\:\,instance\:
2020-11-24 00:34:37.131 [ 1c] I DirectiveProcessor:onDirective:messageId=3e94f324-9b93-47da-a548-6b2ba95b6c77,action=dropped,reason=dialogRequestIdDoesNotMatch,namespace=InteractionModel,name=RequestProcessingCompleted,directivesDialogRequestId=38e767d8-c7bb-4120-804b-4135275c7ada,dialogRequestId=

I have no idea what the issue could be.... maybe because Raspotify is using the speaker still (just turned down to 0 volume), Alexa can't access it?

Sorry about the delay...

I have no idea what the issue could be.... maybe because Raspotify is using the speaker still (just turned down to 0 volume), Alexa can't access it?

Playback is dmix'd so multiple apps should be able to play audio at the same time.

Finally moving forward on this! I've actually been working on more of the hardware side of things. Working on compiling some pictures and build instructions.
The volume control works as far as Alexa turning down Spotify once the wake word is activated, but still trying to debug why I can't hear her. I am not using the most recent asound config file so maybe once I change it to that, it might help.

Hey @JasonLG1979,
Thanks again for the asound.conf earlier. I got it working this weekend after a bit of fudging around with the Pi. The loopback devices work as expected and I can output audio on a bluetooth speaker while the lights work.
I spent all of Friday and Saturday trying to get the hardware audio jack to work with the loopback devices and failed miserably. It seems that there's an issue with that audio jack on the Pi. I can play sound on it if it's the only device being outputted to but it plays either nothing or static when using it with the loopback.
So I tried a bluetooth speaker and it works. The only thing is that I can only run it in the RPi GUI and have to turn on Jack server using qjackctl. Then I can play any audio on my bluetooth and the loopback mic picks it up (which in turn is picked up by PyAudio in the project). Can't get it to work on CLI right now, I'll poke at it again later.
Cool stuff! I'm going to create a new branch and put your asound.conf in it (I'll add your name and link to your GitHub as the original author if you're okay with it) and have the installer script put that in its proper place. I'm gonna work on a video to show this off at some point this week.
I learned a whole lot about alsa, pulseaudio, and jack this weekend. Opens up so many more possibilities. Cheers!

@naztronaut They introduced pulseaudio as default on the desktop version of Raspberry Pi OS so that's going to throw a wrench in anything you do audio wise from now on. Pulseaudio is great 99.9% of the time for normal use cases but for stuff like this it complicates things.
I'm not bad at python. One of these days money permitting I'd like to get some of the LED's and other necessary hardware and combine them with a couple 3 or 4 inch full range drivers a Raspberry Pi 4 and a HIFIBERRY AMP2 hat and maybe a small screen and build a small-ish semi-smart boombox for my son. He's 12 and is starting to show an interest in actually listening to real music. If/when that happens I'm sure we can iron out a few kinks and probably create a few,lol!!!

That sounds awesome! Your son is lucky to have you to show him the ropes when he's ready :)


Update change_license.html

Added TON to accepted payment currency, very important to people in europe and possibly the US as using USDT can cause issues.

We are not supporting TON overall, Only accept USDT, At this moment we are supporting TON just for some cases and It will removed later.

If we say we accept TON, everyone will choose to pay with TON, and that's not ideal for us. Developers prefer to receive USDT, not TON because TON prices can fluctuate. If the price changes, I would have to pay developers according to the new rate when they want to cash out. While we do support TON, if you pay with TON, you'll receive 5-10% less USDT due to price fluctuations.

Yes I get there would be price fluctuations, maybe sell immediately on a
DEX to reduce fluctuations and only charge a small fee, or support more
networks for USDT like arbitrum, ethereum etc?
On Tue, 8 Oct 2024, 14:21 Amin Mahmoudi, @.***> wrote:

If we say we accept TON, everyone will choose to pay with TON, and that's
not ideal for us. Developers prefer to receive USDT, not TON because TON
prices can fluctuate. If the price changes, I would have to pay developers
according to the new rate when they want to cash out. While we do support
TON, if you pay with TON, you'll receive 5-10% less USDT due to price
fluctuations.
—
Reply to this email directly, view it on GitHub
https://github.com/masterking32/MasterCryptoFarmBot/pull/41#issuecomment-2399833073,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHJHWL7LVJTJ23CHZCLGTFTZ2PL4NAVCNFSM6AAAAABPR2YCY2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJZHAZTGMBXGM
.
You are receiving this because you authored the thread.Message ID:
@.***>

Supporting other networks requires implementation and development, but right now, developing new modules is my priority. These modules are for the TON network, so anyone looking to use them must be using TON.

Maybe just convert the TON to USDT via a DEX then? There are many barriers
to sending crypto in Europe at the moment and if it's hard to buy many
people will just give up so more options will massively help.
On Tue, 8 Oct 2024, 15:12 Amin Mahmoudi, @.***> wrote:

Supporting other networks requires implementation and development, but
right now, developing new modules is my priority. These modules are for the
TON network, so anyone looking to use them must be using TON.
—
Reply to this email directly, view it on GitHub
https://github.com/masterking32/MasterCryptoFarmBot/pull/41#issuecomment-2399972038,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHJHWL4DVFEETA4RHBSV3E3Z2PR4HAVCNFSM6AAAAABPR2YCY2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJZHE3TEMBTHA
.
You are receiving this because you authored the thread.Message ID:
@.***>


[Question] yurt-app-manager-admission-patch yurt-app-manager-admission-create yurt-app-manager are not created on the same node

windrow@k8s-node:~/code/yurt-app-manager/config/setup$ kubectl apply -f all_in_one.yaml
windrow@k8s-node:~/code/yurt-app-manager/config/setup$ kubectl get pods -A -o wide
NAMESPACE     NAME                                               READY   STATUS              RESTARTS   AGE     IP              NODE                        NOMINATED NODE   READINESS GATES
default       yurt-app-manager-846cd4d98b-pkslh                  0/1     ContainerCreating   0          23s     <none>          pc-k8s-sp-192-168-0-157     <none>           <none>
default       yurt-app-manager-admission-create-nwftd            0/1     ContainerCreating   0          22s     <none>          pc-k8s-sp-192-168-0-157     <none>           <none>
default       yurt-app-manager-admission-patch-cmnpq             0/1     ContainerCreating   0          22s     <none>          rasp-ubuntu-192-168-0-163   <none>           <none>
...

These pods are not assigned to the same node, is it expected? Should there be any annotations or labels and selectors to make them on the same pod?
/kind question

nvm


go/mcap: Fix scenario where schemaID equals 0

Public-Facing Changes
mcap specification explains schema id that it must be not zero,and go cli has zero-check,The picture is as follows:

Description
schema's documnet of website is https://mcap.dev/spec;

so i add this judgment that schema can't not zero,but I'm not sure if this merging operation is reasonable；

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.12 out of 18 committers have signed the CLA.:white_check_mark: wkalt:white_check_mark: emersonknapp:white_check_mark: jtbandes:white_check_mark: achim-k:white_check_mark: omegacoleman:white_check_mark: amacneil:white_check_mark: mrkline:white_check_mark: pezy:white_check_mark: yizhang24:white_check_mark: wirthual:white_check_mark: StarCsu:white_check_mark: dmweis:x: esthersweon:x: james-rms:x: foxymiles:x: dependabot[bot]:x: defunctzombie:x: narasakaYou have signed the CLA already but the status is still pending? Let us recheck it.


initialSlide option only working briefly before defaulting to first slide

Using the latest versions (slick: 1.5.8, angular-slick-carousel: 3.0.9) setting the initialSlide in options works only momentarily before the carousel changes back to the first slide.
http://plnkr.co/edit/fYIvLiX6Q6d0ZdWQYKzW?p=preview
A working example can be made using an old version of slick: 1.3.15
http://plnkr.co/edit/kENaWAIVGETbBCV8JAfo?p=preview

Hello @OneHP
Please try 3.1.0 version. tell me if get problem.

Hi @devmark
It seems to work on my plunkr. I can't check it with my actual application as 3.1.0 isn't in npm yet (https://www.npmjs.com/package/angular-slick-carousel).
Thanks for getting this fixed so quickly.

npm updated :+1:

Works great. Thanks again.


Do not review, just test if the CI green.

Do not review, just test if the CI green.

If you are wanting to know if upstream master is green, you can refer to the build dashboard https://flutter-dashboard.appspot.com/#/build

If you are wanting to know if upstream master is green, you can refer to the build dashboard https://flutter-dashboard.appspot.com/#/build

Thank you.
Sometimes I am not sure if my modification caused the test to fail, such as this failed(framework_tests-libraries-linux ). I’m surprised that only my test case fails from the dashboard,


xsrfutil.py validate_token()

I'm trying to use the oauth2client/oauth2client/contrib/xsrfutil.py with Django, but get this error when using validate_token(): "string argument without an encoding". From the stacktrace it looks like this is the line causing the error: https://github.com/google/oauth2client/blob/master/oauth2client/contrib/xsrfutil.py#L99
I think the problem is with the token parameter, which is a string. For bytearray we need to specify the encoding.
Python versions attempted: 2.7.11, 3.4
Django versions attempted: 1.8, 1.9.9, 1.10

Looks like generate_token will return a bytestring. Are you sure you're passing a bytestring into validate_token?

In the code comments it says the parameter should be a regular string, will try using a bytestring later.

@wasabigeek bump, is this still an issue?

@jonparrott sorry haven't tried it - I've been using the decorator instead https://github.com/google/oauth2client/pull/636/files#diff-de2fc5853437bc87b3335ca6d764cf40R24

Just ran into this as well. In the django example the state value is passed directly from the request - which is always a string. A workaround is to first .encode('UTF-8') the value.

Thank you for creating this issue, however, this project is deprecatedand we will only be addressing critical security issues. You can read moreabout this deprecation here.
If you need support or help using this library, we recommend that you ask yourquestion on StackOverflow.
If you still think this issue is relevant and should be addressed, pleasecomment and let us know!


problems with your demo code

When I try to use your demo code in https://github.com/pellepl/spiffs/wiki/Using-spiffs like below:
  spiffs_file fd = SPIFFS_open(FS, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
I always get a negative fd. Is there anything else should be done to make this correct?

There could be one or more things wrong. Try printing out the value of fd returned when the call fails and checking the error code list in github here https://github.com/pellepl/spiffs/blob/master/src/spiffs.h. This might give you a clue for further investigation.


Module 2: CodeBuild fails

Please see log below.
Adding permissions  "ecr:UploadLayerPart" and "ecr:CompleteLayerUpload" to MythicalMysfitsService-CodeBuildServicePolicy helps.
denied: User: arn:aws:sts:::assumed-role/MythicalMysfitsServiceCodeBuildServiceRole/AWSCodeBuild-4c4a1c09-bbca-4853-9d15-e18fe7c6f667 is not authorized to perform: ecr:CompleteLayerUpload on resource: arn:aws:ecr:eu-west-1:026927173535:repository/mythicalmysfits/service
[Container] 2019/04/03 07:22:13 Command did not exit successfully docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/mythicalmysfits/service:latest exit status 1
[Container] 2019/04/03 07:22:13 Phase complete: POST_BUILD State: FAILED

what was the problem ?
I have the same issue


JFXTreeTableView add/remove on observableArrayList are not reflected to the control

I have JFXTreeTableView which is defined with a root item as ObservableList users
I am trying to add/remove items from the users list, but the changes are not been reflected to the JFXTreeTableView  control.
I also tried to force updating the JFXTreeTableView  by using  treeView.refresh(); but it did not helped
As i understand from previous discussion in this post:
https://github.com/jfoenixadmin/JFoenix/issues/186
that there should be  a complete support in pushing updated from the ObservableList to the JFXTreeTableView
here is my sample code
                ObservableList<User> users = FXCollections.observableArrayList();
		users.add(new User("Computer Department", "23","CD 1"));
		users.add(new User("Sales Department", "22","Employee 1"));

		for(int i = 0 ; i< 5; i++){
			users.add(new User("HR Department", i%10+"","HR 2" + i));
		}

		// build tree
		final TreeItem<User> root = new RecursiveTreeItem<User>(users, RecursiveTreeObject::getChildren);
		JFXTreeTableView<User> treeView = new JFXTreeTableView<User>(root, users);

		treeView.setShowRoot(false);
		treeView.setEditable(true);
		treeView.getColumns().setAll(deptColumn, ageColumn, empColumn);

--> and now if I do an "add" operation on the collection it does not effect the view
users.add(new User("HR Department ", "32","Employee 6" ));
treeView.refresh();
I also checked this in your demo  sample : TreeTableViewController
which perform add in run time by  doing
treeTableViewAdd.setOnMouseClicked((e) -> { 			root.getChildren().add(new Person(names[random.nextInt(names.length)], names[random.nextInt(names.length)], random.nextInt(100))); 			treeTableView.currentItemsCountProperty().set(treeTableView.currentItemsCountProperty().get()+1); 		});
I tried to do the add operation on the "people1" collection instead on  root (which is a RecursiveTreeObject)
like so:
treeTableViewAdd.setOnMouseClicked((e) -> { 			people1.add(new Person(names[random.nextInt(names.length)], names[random.nextInt(names.length)], random.nextInt(100)));  			treeTableView.refresh();					 		});
it also did not worked
Thank you

Hello,
How did you manage to create JFXTreeTableView using the following constructor?
JFXTreeTableView<User> treeView = new JFXTreeTableView<User>(root, users);
we tested the add/remove operation on JFXTreeTableView, both methods are working. if you could provide the whole code that demonstrates this issue we could be able to help.
Regards,

I used the sample code from the following thread
https://github.com/jfoenixadmin/JFoenix/issues/186
the new JFXTreeTableView(root, users); was available there
I can see this constructor is not even supported in the latest version.
Any way, it made my understand that I may be testing my sample on an old version.  So when switching to latest version the problem was fixed
thank you for the help


Revert lateral tuning change for some TSS2 Rav4

A rav4 user with one of the unconfirmed EPS fw versions from #21429 reported a regression in lateral control.

can we add b'8965B42171\x00\x00\x00\x00\x00\x00' to the list as well? my car have similar issue with that firmware

@yufeng66 that's the same fw as the author (@zorrobyte) of the PR. can you open an issue?

@adeebshihadeh could you share where such regression was reported?
I'm a little concerned as it took quite a bit of effort for that PR to be merged and that it can be undone based on one, unverified complaint. Tuning is a highly subjective matter and the values I proposed were considered "stock" OP values for mergability. Sure, better values can be found, but 0.15/0.05 is unusable for my vehicle.

The regression was reported in #21707. The tuning for your EPS's fw version wasn't reverted, only this one which was never confirmed.

The regression was reported in #21707. The tuning for your EPS's fw version wasn't reverted, only this one which was never confirmed.

Gotcha! Thank you for the clarification. Rav is a rare breed indeed.


Query is more slowly after using sharding-jdbc

Description：
Query becomes more slowly after using sharding-jdbc （MYSQL）.
(Oracle：query is more quickly，just in exception.)
My environment：
springboot + JPA + MySQL+sharding-jbdc    VS    springboot + JPA + MySQL（control group）
mysql：8.0.16
cpu:  G4560 3.5GHz
RAM:  8G
win10 x64
Which version of ShardingSphere did you use?
4.0.0-RC1
Which project did you use? Sharding-JDBC or Sharding-Proxy?
Sharding-JDBC
Data Node Configuration：
spring.shardingsphere.sharding.tables.t_basic_up_msg.actual-data-nodes=
sharding-test.t_basic_up_msg_20190${1..9}${1..2},sharding-test.t_basic_up_msg_2019${10..12}${1..2}
Sharding_test（the amount of data：20million）
├── t_basic_up_msg_201901_1
├── t_basic_up_msg_201901_2
├── t_basic_up_msg_201902_1
├── t_basic_up_msg_201902_2
├── t_basic_up_msg_201903_1
├── t_basic_up_msg_201903_2
..........
├── t_basic_up_msg_201911_1
├── t_basic_up_msg_201911_2
├── t_basic_up_msg_201912_1
├── t_basic_up_msg_201912_2
（There are 24 tables in total.  1 table each  half month）
VS
（database of control group）
Sharding_test1（another database，nosharding，the amount of data：20million）
├── t_basic_up_msg_
Entity

Sharding Key
receipt_time (type :datetime)
type of primary key
UUID
configuration
#Single Database ，multiple tables
spring.shardingsphere.datasource.names=sharding-test,sharding-test1
spring.shardingsphere.datasource.sharding-test.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.sharding-test.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.sharding-test.jdbc-url=jdbc:mysql://localhost:3306/sharding_test?useSSL=false&serverTimezone=CTT&characterEncoding=utf-8
spring.shardingsphere.datasource.sharding-test.username=root
spring.shardingsphere.datasource.sharding-test.password=root
spring.shardingsphere.datasource.sharding-test1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.sharding-test1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.sharding-test1.jdbc-url=jdbc:mysql://localhost:3306/sharding_test?useSSL=false&serverTimezone=CTT&characterEncoding=utf-8
spring.shardingsphere.datasource.sharding-test1.username=root
spring.shardingsphere.datasource.sharding-test1.password=root
spring.shardingsphere.sharding.tables.t_basic_up_msg.actual-data-nodes=
sharding-test.t_basic_up_msg_20190${1..9}${1..2},sharding-test.t_basic_up_msg_2019${10..12}${1..2}
spring.shardingsphere.sharding.tables.t_basic_up_msg.table-strategy.standard.sharding-column=receipt_time
spring.shardingsphere.sharding.tables.t_basic_up_msg.table-strategy.standard.precise-algorithm-class-name=com.bd.demo.algorithm.MyPreciseShardingTableAlgorithm
spring.shardingsphere.sharding.tables.t_basic_up_msg.table-strategy.standard.range-algorithm-class-name=com.bd.demo.algorithm.MyRangeShardingTableAlgorithm
#spring.shardingsphere.props.sql.show=true
sharding rule
`public final class MyPreciseShardingTableAlgorithm implements PreciseShardingAlgorithm {
@Override
public String doSharding(final Collection tableNames, final PreciseShardingValue preciseShardingValue) {
//System.out.println("tableNames:" + tableNames + ",preciseShardingValue:" + preciseShardingValue);
StringBuffer table_name = new StringBuffer("t_basic_up_msg");
    String year = String.format("%tY", preciseShardingValue.getValue());
    String mon = String.format("%tm", preciseShardingValue.getValue());

    table_name.append("_");
    table_name.append(year);
    table_name.append(mon);

    String day =String.format("%td",preciseShardingValue.getValue());
    String firstHalfMon = "_1";
    String secondHalfMon = "_2";
    int dayInt = Integer.parseInt(day);
    if(dayInt<=15){
        table_name.append(firstHalfMon);

    }else{
        table_name.append(secondHalfMon);

    }

    for (String each : tableNames) {
        if (each.equals(table_name.toString())){
            return each;
        }
    }

    throw new UnsupportedOperationException();

}

}`
API
/test/findByReceiptTime
`@RequestMapping("/findByReceiptTime")
@ResponseBody
public List findByReceiptTime() throws Exception{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date formatDate = null;

    formatDate = sdf.parse("2019-01-01 00:04:10");

    List<TBasicUpMsg> cs=  tBasicUpMsgService.findByReceiptTime(formatDate);

    return cs;

}

sercice:
public List findByReceiptTime(Date receiptTime) {
    List<TBasicUpMsg> tBasicUpMsgs= tBasicUpMsgRepository.findByReceiptTime(receiptTime);
    return tBasicUpMsgs;
}

repository:
@Repository
public interface TBasicUpMsgRepository extends JpaRepository<TBasicUpMsg, String>,JpaSpecificationExecutor {
public List<TBasicUpMsg> findByReceiptTime(Date receiptTime);

}`
Expected behavior
query more quickly
Actual behavior
query more slowly
insert more quickly
Reason analyze
don't know.
if I Execute SQL separately，the speed is almost the same（Whether sharding-jdbc is used or not ）.
May be the amount of data is too small（20million）.
（But the amount of oracle is only 800w，the improvement is obvious.）
My expection:
Is this normal?
It would be better if you can give me some suggestions.
Thank you!

result:
sharding:

noshading:

from https://shardingsphere.apache.org/document/current/cn/manual/sharding-jdbc/stress-test/

please translate Chinese word to english first

It's done.

@fdlzp Where's the SQLs? Please show me the SQLs in a very precise way, like select * from t_order;

@fdlzp Where's the SQLs? Please show me the SQLs in a very precise way, like select * from t_order;
sharing
select tbasicupms0_.basic_up_msg_id as basic_up1_0_, tbasicupms0_.basic_up_msg_no as basic_up2_0_, tbasicupms0_.cust_sender_ic as cust_sen3_0_, tbasicupms0_.data_source as data_sou4_0_, tbasicupms0_.data_type as data_typ5_0_, tbasicupms0_.forward_number as forward_6_0_, tbasicupms0_.hex_sms as hex_sms7_0_, tbasicupms0_.is_del as is_del8_0_, tbasicupms0_.palt_receive_ic as palt_rec9_0_, tbasicupms0_.process_status as process10_0_, tbasicupms0_.process_time as process11_0_, tbasicupms0_.project_id as project12_0_, tbasicupms0_.receipt_time as receipt13_0_ from t_basic_up_msg_201901_1 tbasicupms0_ where tbasicupms0_.receipt_time='2019-01-01 00:04:10.0'

range

select tbasicupms0_.basic_up_msg_id as basic_up1_0_, tbasicupms0_.basic_up_msg_no as basic_up2_0_, tbasicupms0_.cust_sender_ic as cust_sen3_0_, tbasicupms0_.data_source as data_sou4_0_, tbasicupms0_.data_type as data_typ5_0_, tbasicupms0_.forward_number as forward_6_0_, tbasicupms0_.hex_sms as hex_sms7_0_, tbasicupms0_.is_del as is_del8_0_, tbasicupms0_.palt_receive_ic as palt_rec9_0_, tbasicupms0_.process_status as process10_0_, tbasicupms0_.process_time as process11_0_, tbasicupms0_.project_id as project12_0_, tbasicupms0_.receipt_time as receipt13_0_ from t_basic_up_msg_201911_1 tbasicupms0_ where tbasicupms0_.receipt_time between  '2019-11-01 00:00:00.0' and '2019-11-03 00:00:00.0'
nosharding
select tbasicupms0_.basic_up_msg_id as basic_up1_0_, tbasicupms0_.basic_up_msg_no as basic_up2_0_, tbasicupms0_.cust_sender_ic as cust_sen3_0_, tbasicupms0_.data_source as data_sou4_0_, tbasicupms0_.data_type as data_typ5_0_, tbasicupms0_.forward_number as forward_6_0_, tbasicupms0_.hex_sms as hex_sms7_0_, tbasicupms0_.is_del as is_del8_0_, tbasicupms0_.palt_receive_ic as palt_rec9_0_, tbasicupms0_.process_status as process10_0_, tbasicupms0_.process_time as process11_0_, tbasicupms0_.project_id as project12_0_, tbasicupms0_.receipt_time as receipt13_0_ from t_basic_up_msg tbasicupms0_ where tbasicupms0_.receipt_time='2019-01-01 00:04:10.0'
  range

select tbasicupms0_.basic_up_msg_id as basic_up1_0_, tbasicupms0_.basic_up_msg_no as basic_up2_0_, tbasicupms0_.cust_sender_ic as cust_sen3_0_, tbasicupms0_.data_source as data_sou4_0_, tbasicupms0_.data_type as data_typ5_0_, tbasicupms0_.forward_number as forward_6_0_, tbasicupms0_.hex_sms as hex_sms7_0_, tbasicupms0_.is_del as is_del8_0_, tbasicupms0_.palt_receive_ic as palt_rec9_0_, tbasicupms0_.process_status as process10_0_, tbasicupms0_.process_time as process11_0_, tbasicupms0_.project_id as project12_0_, tbasicupms0_.receipt_time as receipt13_0_ from t_basic_up_msg tbasicupms0_ where tbasicupms0_.receipt_time between '2019-11-01 00:00:00.0' and '2019-11-03 00:00:00.0'

Now it's normal after I created another index and then droppd it.
It's really puzzling！！！
I’m looking for the root cause.(I don‘t know if it is related to the version of MySQL
)

I am thinking for a while. I guess, the samples are too few. and the test results are not stable.
You can increase the querys to 5 million, maybe you will find something.

I‘ll try it later.
I can confirm that the index cause the problem. Because the improvement is obvious now.
Thank you for your time.

Another question:
How do we create indexes after using sharding?
after

Hello I hava a new question.
How should we create index after using sharding-jdbc？
The sharding key is named receipt_time (type :datetime).
I just create an index like ALTER TABLE t_basic_up_msg ADD INDEX idx_upmsg_receiptTime(receipt_time);
and then
query become more slowly(It's obvious，slower 3 times).
Any suggestion?

You can open a new issue for the new question.

ok


tvOS Support

Added tvOS Support
Modified AppStoreAnimator so user can select the desired blur effect (useful for dark move on tvOS)
Added a simple tvOS demo to the example project so the AppStoreAnimator effect can be appreciated.

What can be improved:

Pod version was NOT bumped (yet)
More transition examples

💔


Fix waitForSceneCompletion hang when tiles have been freed by GpuMemoryLimit

Fixes an issue where waitForSceneCompletion never exits the loop because _hasMissingTiles is always true.  This occurs when a GpuMemoryLimit is used and has caused tiles to discard from the limit being exceeded.
This is actually due to three different issues.  The first (preloading) is dealt with in https://github.com/iTwin/itwinjs-core/pull/6512.

The culprit is RealityTile.preloadProtectedTiles.
We should disable preloading when under memory pressure. Proposed solution is to add a property like TileAdmin.allowPreloading that always returns false on mobile (RealityTileTree.ts checks this before preloading, it belongs here instead), and otherwise computes % utilization based on LRUTileList.totalBytesUsed / max memory limit (or 0%, if no memory limit) and returns false if it's above some threshold (80% seems reasonable).

Unfortunately, while this does work correctly now for disabling preloading when under memory pressure, it does not fix the hang problem after all, or at least not completely.
If I just bring up the debugger window while display-performance-test-app is hung on a view, then that view completes.  The following view then will hang.  But if I set breakpoints and step through a little of the code and then continue, then that view works and the test finishes.

@DStradley is this only reproducible with reality models?

@DStradley is this only reproducible with reality models?

As far as I know, it is only happening on a fairly large reality model, with shadows on, from my test suite.  However, it is not likely that many of the other models are under memory pressure (which is key here, I was a little surprised to find this one was), so I am not sure.

It would be surprising if the tile tree asks us to load content for a tile, but after the content loads the tile tree does not select it for display.

If am understanding the flow I am seeing, which I may not be, it wants to select it but doesn't get the chance to before it is freed, at least for this reality data case I am studying.

it is not likely that many of the other models are under memory pressure (which is key here

Have you performed the experiment of setting the memory threshold very low and seeing if the problem occurs with other views, and if so, if they all have something in common, such as containing only reality models, or only shadows, etc?

Have you performed the experiment of setting the memory threshold very low and seeing if the problem occurs with other views...

No I have not, I will try that.
Also, on the view it is failing on currently, there are two views drawn back to back that are the same view, except the first is "masked" and the second is "without mask".  Either view run by itself will succeed, but back to back, the second one hangs.  So it is a complex failure case, though repeatable.  And if I remove the GPUmemoryLimit then of course the pair succeeds.

Initial test results with a lower memory threshold:  I set the limit to 1000 MiB and ran the full test suite.  This produced a lot more hangs, all reality models.  35 hung views now across 9 different models, only 4 of which have shadows.  So the commonality so far seems to be reality models.
During the run with 35 hangs, I was able to manually keep the test going through these techniques, the middle one is the only one I think I understand why it worked:

Just bringing up the debugger (Ctrl-Shift-I) will clear the hang a lot of times, but not always.
Otherwise, I set a breakpoint in disposeContents and after this._state gets set to NotReady, I set it back to Ready (3) in the debugger, dismiss the debugger to continue, and that clears the hang.
Near the end I accidentally discovered that collapsing DPTA and restoring it would also clear the hang, at least for the few times I tried it.

I then launched a new run with a 100 MiB limit and PlanarClipMasks, RealityTests, and Thematic-Reality groups turned off.  This is to see if this low a limit shows up anything else (already tested reality models, a few more hangs there doesn't tell us anything).
I am only 20 views into the test and have already had 5 different views from 4 different imodels hang on this run (all plant models).  For some reason, I can't get the debugger to come up on this run, but collapsing the window and restoring it will free the hang.  I am going to kill this run, since I don't have time now to babysit all the hangs.
But apparently it is not just reality models, if the limit is set low enough.

Okay, I had another imodel hang (a building this time) before I could get the last test killed, so that made 6 hangs in a fairly short time, of all imodel tiles.  So I didn't see the point of continuing that test.  Instead, I tried moving processQueue to the end of process to see if that would fix these.  I first just ran that locally with the 6 known failing (after verifying they also failed locally).
However, what I found was that this would not reliably fix the problem.  Most would not hang now, but one of the files (varying, apparently random after 4 tries) in the test would still hang.  When it did, I found I could still do my scheme of forcing Ready back on in the debugger to clear the hang.  Also, it was just one tile that was "in a loop", just like reality tiles.
Not sure yet what to try next.

@pmconne I have been adding various debug prints in to attempt to figure out the flow of the problem cases.
I added a probtile field to tile and initialized it to 0.  I set it to 1 in renderFrame if missingTiles.size === 1, tile is not in use, and probtile is 0.  I set it to 0 again in markUsed.  Also, I increment it (if > 0) in freeMemory and go ahead and disposeContents.
All of this was an effort to narrow the scope of the problem tiles, and prevent a flood of prints.  When things work properly, probTile gets marked, but later markUsed clears it and everything is fine, otherwise, a single tile just churns.
I do print TileAdmin.process begin and end every time, and at the beginning I search for any probTile in the LRUlist.  If none found, it prints a -2.
Here is a sequence of prints (the [] portion contains timestamps) from a hung case, indicating the flow.  // comments were added afterwards.  It seems this tile repeatedly is getting freed before it can be selected. What would you suggest?
[51808:0311/174849.564:INFO:CONSOLE(128801)] "renderFrame: 1 missing: id -b-5-0-1-4-1 probtile 67  loadstatus 0  inUse false  selected false"  // renderFrame called that had 1 missing tile
[51808:0311/174849.568:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile -2" // -2 means probtile not in LRUlist
[51808:0311/174849.568:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile -2"   // -2 means probtile not in LRUlist
[51808:0311/174849.570:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile -2" // -2 means probtile not in LRUlist
[51808:0311/174849.570:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile -2"   // -2 means probtile not in LRUlist
[51808:0311/174849.583:INFO:CONSOLE(110838)] "setIsReady - probTile: id -b-5-0-1-4-1  probtile 67  state 3  inUse false  selected false"
                                                // setIsReady then calls onTileContentLoaded after this print, which calls drop and add, add puts the tile in the LRUlist as a non-selected tile
[51808:0311/174849.598:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile 67" // This shows that probTile is in the LRUlist at the beggining of process
[51808:0311/174849.598:INFO:CONSOLE(110770)] "freeMemory - free probTile: id -b-5-0-1-4-1  probtile 67  state 3  inUse false  selected false"  // so it gets freed, and I increment probTile afterwards
[51808:0311/174849.599:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile 67"
[51808:0311/174849.679:INFO:CONSOLE(145270)] "selectTiles: id -b-5-0-1-4-1  probtile 68  loadStatus 0  inUse false  vis true  hasGraphics false  selected false"  // then the select for this probTile happens, but now it has no content

                                             // repeat of all the above, with incremented probTile - keeps doing this forever
[51808:0311/174849.680:INFO:CONSOLE(128801)] "renderFrame: 1 missing: id -b-5-0-1-4-1 probtile 68  loadstatus 0  inUse false  selected false"
[51808:0311/174849.686:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile -2"
[51808:0311/174849.687:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile -2"
[51808:0311/174849.687:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile -2"
[51808:0311/174849.687:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile -2"
[51808:0311/174849.705:INFO:CONSOLE(110838)] "setIsReady - probTile: id -b-5-0-1-4-1  probtile 68  state 3  inUse false  selected false"
[51808:0311/174849.716:INFO:CONSOLE(130056)] "TileAdmin.process begin - probtile 68"
[51808:0311/174849.716:INFO:CONSOLE(110770)] "freeMemory - free probTile: id -b-5-0-1-4-1  probtile 68  state 3  inUse false  selected false"
[51808:0311/174849.716:INFO:CONSOLE(130060)] "TileAdmin.process end - probtile 68"
[51808:0311/174849.797:INFO:CONSOLE(145270)] "selectTiles: id -b-5-0-1-4-1  probtile 69  loadStatus 0  inUse false  vis true  hasGraphics false  selected false"

There appears to be a timing window that allows this case to occur where it can get freed before it is selected (under memory pressure).  setIsReady calls onTileContentLoaded, which calls _lruList.drop and _lruList.add.  The add puts in back in the lruList and calls moveBeforeSentinel, which means it can be freed if freeMemory happens to be called before selectTiles (which would end up causing it to be moved after the sentinel and therefore safe from free).
After some discussion of this in a group meeting, we decided to it should be okay to just have _lruList.add move it after the sentinel instead of before, and thus protect it.
I implemented this and tested it on a full suite of ImageTests views, but I found there were still hangs.  After digging into this, I found that it did indeed fix the problem I had been looking at, however, there is still a 3rd remaining hang problem related to models with Open Street Map buildings.

The flow I found this time is:

setIsReady calls _lruList drop and add on the tile.  (add now calls moveAfterSentinel, which makes it "safe" from freeMemory.)
Then, renderFrame happens and it calls clearTilesForUser, which calls _lruList.clearUsed, which calls moveBeforeSentinel, so then it is no longer "safe" from freeMemory.
Then, when TileAdmin.process gets called, it calls freeMemory, and a set of tiles which were needed and used, but not marked as such yet, get freed.
They then get put in the missing list, and so get requested again, and eventually are ready, and so setIsReady is called, and the cycle repeats.

While studying the code flow on all this, I noticed that part of the comment on markTileUsed says “A tile will not be discarded while it is in use by any TileUser.”  This appears to be the case for pruneAndPurge, which checks getIsTileInUse(), but it is not the case for freeMemory (which is only looking at the position in lruList with regard to sentinel). I also noticed that the tiles getting freed were considered inUse.  So I tried adding that check to freeMemory as well, and found that it fixes the OSM building hang.
I have started a full ImageTests run with a GPUMemLimit of 50 MB, to see how that goes.
@pmconne, is this a viable fix?

pruneAndPurge are the normal mechanisms for freeing up memory consumed by tiles that are no longer in use. freeMemory is the mechanism by which we free memory consumed by tiles that might still be in use. If you change freeMemory to only free memory for tiles that are not in use, you will largely defeat the whole purpose. It would be equivalent to setting the tile expiration time to zero. It would cause us to never free undisplayed ancestor tiles of displayed tiles, for example.

pruneAndPurge is the normal mechanism by which we free up memory consumed by tiles that are no longer in use...

So what is the definition of "in use", and how is it different than "selected" for instance?  I assume we still don't want to free tiles that are actually being displayed (or trying to be)?

I assume we still don't want to free tiles that are actually being displayed (or trying to be)?

Right, that is why freeMemory only frees selected tiles (based on its partition in the LRU list).

So what is the definition of "in use", and how is it different than "selected" for instance?

See TileDrawArgs.markUsed:

Indicate that the specified tile is being used for some purpose by the [[SceneContext]]'s [[Viewport]]. Typically "used" means "displayed", but the exact meaning is up to the [[TileTree]] - for example, "used" might also mean that the tile's children are being used. A tile that is "in use" by any [[Viewport]] will not be discarded.

Updates:

I made a test case that only has OSM buildings (no reality data or map tiles) and that still fails the same way.
I noticed AdditiveRefinementStepchildren are in play for some of these tiles, so I tried forcing that disabled in the code and that "fixes" the hang.

@pmconne as I think I currently understand things, AdditiveRefinementStepChildren mark themselves and their loadableTile as used.  Both are needed to draw since the StepChildren only contain transforms, but only the StepChildren are getting selected, I assume because we don't want the loadableTile to draw directly.  So the actual RealityTile is getting freed even though it is needed to draw.
So my current attempt at a fix is to check and not free a RealityTile if it has any StepChildren.  This prevents hanging on my test cases, is this a viable fix?


IX-Async implementation of GroupJoin possibly leading to deadlock

Heads up that this issue was reported on Entity Framework Core 1.0.0 RC2 at https://github.com/aspnet/EntityFramework/issues/5481.
Customer provided a repro at https://github.com/iberodev/EntityFramework5481.
We haven't tried to produce a self-contained repro with only IX-Async in the picture but we worked around it by creating our own implementation of GroupJoin().
cc @anpete

Is there any chance you can submit your implementation of GroupJoin as a PR here?

@onovotny We rely on async/await, which, so far, IX-Async does not want to depend on.

Do you recall the reason why Ix-Async has avoided async/await?

I think it was compat. Not sure if it still matters.

If that was the reason, then a PR would be very welcome

This should be fixed in #170. Can you please retest against 3.0.1-build00046 or later?


Raspberry Pi 4 build instructions

There have been several issues dealing with bugs related to the Raspberry Pi 4 including #29 and #23 . The wiki instructions have not been updated to reflect this. There seem to be specific steps that need to be taken such as building a non-master branch or applying a patch. These instructions should be incorporated into the wiki instructions.

Since you're working through this now, could you summarize what needs to be updated?

I will if I can figure it out. I haven't gotten it to work yet.

I am also having problems with setting up Raspberry Pi 4 (Raspberry Pi OS)/Purethermal2/GetThermal
Has there been any success with this?  I have tried every method I can find available.

Any updates regarding those issues?

used the following for qt5 related error and kept the rest same, its currently working..
sudo apt-mark manual qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
article is here: https://forum.qt.io/topic/132190/issue-with-sudo-apt-get-install-qt5-default/2

As @girgine mentioned above and according to the provided link the correct command for Raspberry Pi 4 with Rasbpian bullseye, in step 2 of the Wiki should be:
sudo apt-get install qtbase5-dev qtchooser qt5-qmake \
    qtbase5-dev-tools qtmultimedia5-dev qtdeclarative5-dev \
    qml-module-qtquick-controls2 qml-module-qtmultimedia \
    qml-module-qtquick-layouts qml-module-qtquick-window2 \
    qml-module-qtquick-templates2 qml-module-qtgraphicaleffects \
    libusb-1.0-0-dev cmake git

Otherwise, I followed the process as mentioned in the Wiki and it worded perfectly.
Maybe it can be updated with a note that this command is just for Rasbpian bullseye @kekiefer ? Thank you!