Repository: adafruit/adafruit_learning_system_guides
Issue: ulab.scipy.signal import spectrogram stopped working with 8.0.0-beta.4

### CircuitPython version

```python
Adafruit CircuitPython 8.0.0-beta.4 on 2022-10-30; Adafruit QT Py RP2040 with rp2040
```


### Code/REPL

```python
from ulab.scipy.signal import spectrogram
```


### Behavior

ImportError: can't import name spectrogram

### Description

Had working example of this tutorial: https://learn.adafruit.com/mini-led-matrix-audio-visualizer
Stopped working after latest update.

### Additional information

From the repl >>> help(ulab.scipy.signal) 
shows only sosfilt function. 
None for [scipy.signal.spectrogram](https://micropython-ulab.readthedocs.io/en/2.1.2/scipy-signal.html#spectrogram)

Changed files:
Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/audio_spectrum_lightshow/code.py
Ukulele/code.py
EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py
Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py
ulab_Crunch_Numbers_Fast/waterfall/code.py

diff --git a/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py
index 0ec5cb2a..34587684 100755
--- a/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py
+++ b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py
@@ -18,8 +18,11 @@ import adafruit_is31fl3741
 from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses
 from rainbowio import colorwheel
 from ulab import numpy as np
-from ulab.scipy.signal import spectrogram
 
+try:
+    from ulab.utils import spectrogram
+except ImportError:
+    from ulab.scipy.signal import spectrogram
 
 # FFT/SPECTRUM CONFIG ----
 
diff --git a/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/audio_spectrum_lightshow/code.py b/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/audio_spectrum_lightshow/code.py
index aa6cc81f..2cfd9c94 100755
--- a/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/audio_spectrum_lightshow/code.py
+++ b/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/audio_spectrum_lightshow/code.py
@@ -18,11 +18,11 @@ import adafruit_is31fl3741
 from adafruit_is31fl3741.adafruit_rgbmatrixqt import Adafruit_RGBMatrixQT
 from rainbowio import colorwheel
 from ulab import numpy as np
-#  if using CP7 and below:
-from ulab.scipy.signal import spectrogram
-#  if using CP8 and above:
-#  from ulab.utils import spectrogram
 
+try:
+    from ulab.utils import spectrogram
+except ImportError:
+    from ulab.scipy.signal import spectrogram
 
 # FFT/SPECTRUM CONFIG ----
 
@@ -40,7 +40,7 @@ high_bin = 75  # Highest bin "
 i2c = I2C(board.SCL, board.SDA, frequency=1000000)
 
 # Initialize the IS31 LED driver, buffered for smoother animation
-#glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
+# glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
 glasses = Adafruit_RGBMatrixQT(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
 
 glasses.show()  # Clear any residue on startup
@@ -152,7 +152,7 @@ while True:
 
         # Apply vertical scale to spectrum data. Results may exceed
         # matrix height...that's OK, adds impact!
-        #data = (spectrum - lower) * (7 / (dynamic_level - lower))
+        # data = (spectrum - lower) * (7 / (dynamic_level - lower))
         data = (spectrum - lower) * ((glasses.height + 2) / (dynamic_level - lower))
 
         for column, element in enumerate(column_table):
diff --git a/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py b/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py
index afa51100..9049fa3c 100644
--- a/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py
+++ b/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py
@@ -2,16 +2,20 @@
 #
 # SPDX-License-Identifier: MIT
 
-'''Adapted from the FFT Example: Waterfall Spectrum Analyzer
+"""Adapted from the FFT Example: Waterfall Spectrum Analyzer
 by Jeff Epler
-https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/overview '''
+https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/overview """
 
 import array
 import board
 import audiobusio
 import busio
 from ulab import numpy as np
-from ulab.scipy.signal import spectrogram
+
+try:
+    from ulab.utils import spectrogram
+except ImportError:
+    from ulab.scipy.signal import spectrogram
 import adafruit_is31fl3741
 from adafruit_is31fl3741.adafruit_rgbmatrixqt import Adafruit_RGBMatrixQT
 
@@ -27,6 +31,7 @@ is31.set_led_scaling(0x19)
 is31.global_current = 0x03
 is31.enable = True
 
+# fmt: off
 #  array of colors for the LEDs
 #  goes from purple to red
 #  gradient generated using https://colordesigner.io/gradient-generator
@@ -41,23 +46,26 @@ heatmap = [0xb000ff,0xa600ff,0x9b00ff,0x8f00ff,0x8200ff,
            0xedff00,0xf5eb00,0xfcd600,0xffc100,0xffab00,
            0xff9500,0xff7c00,0xff6100,0xff4100,0xff0000,
            0xff0000,0xff0000]
+# fmt: on
 
 #  size of the FFT data sample
 fft_size = 64
 
 #  setup for onboard mic
-mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
-                       sample_rate=16000, bit_depth=16)
+mic = audiobusio.PDMIn(
+    board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
+)
 
 #  use some extra sample to account for the mic startup
-samples_bit = array.array('H', [0] * (fft_size+3))
+samples_bit = array.array("H", [0] * (fft_size + 3))
 
 #  sends visualized data to the RGB matrix with colors
 def waves(data, y):
-    offset = max(0, (13-len(data))//2)
+    offset = max(0, (13 - len(data)) // 2)
 
     for x in range(min(13, len(data))):
-        is31.pixel(x+offset, y, heatmap[int(data[x])])
+        is31.pixel(x + offset, y, heatmap[int(data[x])])
+
 
 # main loop
 def main():
@@ -78,7 +86,7 @@ def main():
         # spectrum() is always nonnegative, but add a tiny value
         # to change any zeros to nonzero numbers
         spectrogram1 = np.log(spectrogram1 + 1e-7)
-        spectrogram1 = spectrogram1[1:(fft_size//2)-1]
+        spectrogram1 = spectrogram1[1 : (fft_size // 2) - 1]
         #  sets range of the spectrogram
         min_curr = np.min(spectrogram1)
         max_curr = np.max(spectrogram1)
@@ -86,10 +94,10 @@ def main():
         if max_curr > max_all:
             max_all = max_curr
         else:
-            max_curr = max_curr-1
+            max_curr = max_curr - 1
         min_curr = max(min_curr, 3)
         # stores spectrogram in data
-        data = (spectrogram1 - min_curr) * (51. / (max_all - min_curr))
+        data = (spectrogram1 - min_curr) * (51.0 / (max_all - min_curr))
         # sets negative numbers to zero
         data = data * np.array((data > 0))
         #  resets y
@@ -101,4 +109,5 @@ def main():
         #  writes data to the RGB matrix
         is31.show()
 
+
 main()
diff --git a/Ukulele/code.py b/Ukulele/code.py
index b0dae025..78bff364 100644
--- a/Ukulele/code.py
+++ b/Ukulele/code.py
@@ -24,7 +24,11 @@ import digitalio
 import audiobusio
 import board
 import neopixel
-from ulab.scipy.signal import spectrogram
+
+try:
+    from ulab.utils import spectrogram
+except ImportError:
+    from ulab.scipy.signal import spectrogram
 from ulab import numpy as np
 from rainbowio import colorwheel
 from adafruit_lsm6ds import lsm6ds33
@@ -46,11 +50,11 @@ from adafruit_led_animation.color import (
     WHITE,
 )
 
-MAX_BRIGHTNESS = 0.3 #set max brightness for sound reactive mode
-NORMAL_BRIGHTNESS = 0.1 #set brightness for non-reactive mode
-VOLUME_CALIBRATOR = 50 #multiplier for brightness mapping
-ROCKSTAR_TILT_THRESHOLD = 200 #shake threshold
-SOUND_THRESHOLD = 430000 #main strum or pluck threshold
+MAX_BRIGHTNESS = 0.3  # set max brightness for sound reactive mode
+NORMAL_BRIGHTNESS = 0.1  # set brightness for non-reactive mode
+VOLUME_CALIBRATOR = 50  # multiplier for brightness mapping
+ROCKSTAR_TILT_THRESHOLD = 200  # shake threshold
+SOUND_THRESHOLD = 430000  # main strum or pluck threshold
 
 # Set to the length in seconds for the animations
 POWER_ON_DURATION = 1.3
@@ -71,11 +75,11 @@ pixels.fill(0)  # NeoPixels off ASAP on startup
 pixels.show()
 
 
-#PIXEL MAPS: Used for reordering pixels so the animations can run in different configurations.
-#My LED strips inside the neck are accidentally swapped left-right,
-#so these maps also correct for that
-
+# PIXEL MAPS: Used for reordering pixels so the animations can run in different configurations.
+# My LED strips inside the neck are accidentally swapped left-right,
+# so these maps also correct for that
 
+# fmt: off
 #Bottom up along both sides at once
 pixel_map_reverse = PixelMap(pixels, [
     0, 103, 1, 102, 2, 101, 3, 100, 4, 99, 5, 98, 6, 97, 7, 96, 8, 95, 9, 94, 10,
@@ -121,6 +125,7 @@ pixel_map_skip = PixelMap(pixels, [
     83, 22, 81, 24, 79, 26, 77, 29, 74, 31, 72, 33, 70, 35, 68, 37, 66, 39, 64, 41,
     62, 43, 60, 45, 58, 47, 56, 49, 54, 51, 52,
     ], individual_pixels=True)
+# fmt: on
 
 pixel_map = [
     pixel_map_reverse,
@@ -130,15 +135,15 @@ pixel_map = [
     pixel_map_skip,
 ]
 
-#Set up accelerometer & mic
+# Set up accelerometer & mic
 sensor = lsm6ds33.LSM6DS33(i2c)
-mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK,
-                       board.MICROPHONE_DATA,
-                       sample_rate=16000,
-                       bit_depth=16)
+mic = audiobusio.PDMIn(
+    board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
+)
 
 NUM_SAMPLES = 256
-samples_bit = array.array('H', [0] * (NUM_SAMPLES+3))
+samples_bit = array.array("H", [0] * (NUM_SAMPLES + 3))
+
 
 def power_on(duration):
     """
@@ -151,6 +156,7 @@ def power_on(duration):
             break  # Stop animating
         powerup.animate()
 
+
 def rockstar_tilt(duration):
     """
     Tilt animation - lightning effect with a rotating color
@@ -181,6 +187,7 @@ def rockstar_tilt(duration):
         pixels.show()
         time.sleep(0.03)
 
+
 # Cusomize LED Animations  ------------------------------------------------------
 powerup = RainbowComet(pixel_map[3], speed=0, tail_length=25, bounce=False)
 rainbow = Rainbow(pixel_map[4], speed=0, period=6, name="rainbow", step=2.4)
@@ -190,13 +197,13 @@ chase = Chase(pixel_map[1], speed=0.1, color=RED, size=1, spacing=6)
 rainbow_comet = RainbowComet(pixel_map[2], speed=0, tail_length=80, bounce=True)
 rainbow_comet2 = RainbowComet(
     pixel_map[0], speed=0, tail_length=104, colorwheel_offset=80, bounce=True
-    )
+)
 rainbow_comet3 = RainbowComet(
     pixel_map[1], speed=0, tail_length=25, colorwheel_offset=80, step=4, bounce=False
-    )
+)
 strum = RainbowComet(
     pixel_map[3], speed=0, tail_length=25, bounce=False, colorwheel_offset=50, step=4
-    )
+)
 lava = Comet(pixel_map[3], speed=0.01, color=ORANGE, tail_length=40, bounce=False)
 sparkle = Sparkle(pixel_map[4], speed=0.01, color=BLUE, num_sparkles=10)
 sparkle2 = Sparkle(pixel_map[1], speed=0.05, color=PURPLE, num_sparkles=4)
@@ -213,18 +220,18 @@ animations = AnimationSequence(
     AnimationGroup(
         sparkle,
         strum,
-        ),
+    ),
     AnimationGroup(
         sparkle2,
         rainbow_comet3,
-        ),
+    ),
     auto_clear=True,
     auto_reset=True,
 )
 
 
 MODE = 0
-LASTMODE = 1 # start up in sound reactive mode
+LASTMODE = 1  # start up in sound reactive mode
 i = 0
 
 # Main loop
@@ -245,9 +252,9 @@ while True:
         spectrum[1] = 0
         peak_idx = np.argmax(spectrum)
         peak_freq = peak_idx * 16000 / 256
-#        print((peak_idx, peak_freq, spectrum[peak_idx]))
+        #        print((peak_idx, peak_freq, spectrum[peak_idx]))
         magnitude = spectrum[peak_idx]
-#         time.sleep(1)
+        #         time.sleep(1)
         if peak_freq == 812.50 and magnitude > SOUND_THRESHOLD:
             animations.next()
             time.sleep(1)
@@ -262,10 +269,10 @@ while True:
                 print("mode = 1")
                 LASTMODE = 1
                 time.sleep(1)
-    # Read accelerometer
+        # Read accelerometer
         x, y, z = sensor.acceleration
-        accel_total = x * x + y * y # x=tilt, y=rotate
-#         print (accel_total)
+        accel_total = x * x + y * y  # x=tilt, y=rotate
+        #         print (accel_total)
         if accel_total > ROCKSTAR_TILT_THRESHOLD:
             MODE = 3
             print("Tilted: ", accel_total)
@@ -273,9 +280,9 @@ while True:
             VOLUME = magnitude / (VOLUME_CALIBRATOR * 100000)
             if VOLUME > MAX_BRIGHTNESS:
                 VOLUME = MAX_BRIGHTNESS
-#             print(VOLUME)
+            #             print(VOLUME)
             pixels.brightness = VOLUME
-#             time.sleep(2)
+            #             time.sleep(2)
             animations.animate()
         elif MODE == 2:
             pixels.brightness = NORMAL_BRIGHTNESS
diff --git a/ulab_Crunch_Numbers_Fast/waterfall/code.py b/ulab_Crunch_Numbers_Fast/waterfall/code.py
index 23a2826b..40d58296 100644
--- a/ulab_Crunch_Numbers_Fast/waterfall/code.py
+++ b/ulab_Crunch_Numbers_Fast/waterfall/code.py
@@ -12,12 +12,17 @@ import board
 import audiobusio
 import displayio
 from ulab import numpy as np
-from ulab.scipy.signal import spectrogram
+
+try:
+    from ulab.utils import spectrogram
+except ImportError:
+    from ulab.scipy.signal import spectrogram
 
 display = board.DISPLAY
 
 # Create a heatmap color palette
 palette = displayio.Palette(52)
+# fmt: off
 for i, pi in enumerate((0xff0000, 0xff0a00, 0xff1400, 0xff1e00,
                         0xff2800, 0xff3200, 0xff3c00, 0xff4600,
                         0xff5000, 0xff5a00, 0xff6400, 0xff6e00,
@@ -31,6 +36,7 @@ for i, pi in enumerate((0xff0000, 0xff0a00, 0xff1400, 0xff1e00,
                         0x00a4ff, 0x0094ff, 0x0084ff, 0x0074ff,
                         0x0064ff, 0x0054ff, 0x0044ff, 0x0032ff,
                         0x0022ff, 0x0012ff, 0x0002ff, 0x0000ff)):
+    # fmt: on
     palette[51-i] = pi
 
 class RollingGraph(displayio.TileGrid):