<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <h1>Soundscape Analysis by Shift-Invariant Latent Components</h1>
<h2>Michael Casey - Bregman Labs, Dartmouth College</h2>
A toolkit for matrix factorization of soundscape spectrograms into independent streams of sound objects, possibly representing individual species or independent group behaviours. 
The method employs shift-invariant probabilistic latent component analysis (SIPLCA) for factoring a time-frequency matrix (2D array) into a convolution of 2D kernels (patches) with sparse activation functions. 
Methods are based on the following
Step1:  <h2>Example audio</h2>
Load an example audio file from the 'sounds' directory, 44.1kHz, stereo, 60 seconds duration.
Step2:  <h2>Spectrum Analysis Parameters</h2>
Inspect the soundfile by loading it (using wavread) and printing some useful parameters.
A window size of 4096 with a hop of 1024 translates to 92ms and 23ms respectively for an audio samplerate of 44100Hz
Step3:  <h2>SoundscapeEcology Toolkit</h2>
Analyze species-specific patterns in environmental recordings
SoundscapeEcology methods
<ASSISTANT_TASK:>
Python Code:
from pylab import * # numpy, matplotlib, plt
from bregman.suite import * # Bregman audio feature extraction library
from soundscapeecology import * # 2D time-frequency shift-invariant convolutive matrix factorization
%matplotlib inline
rcParams['figure.figsize'] = (15.0, 9.0)
Explanation: <h1>Soundscape Analysis by Shift-Invariant Latent Components</h1>
<h2>Michael Casey - Bregman Labs, Dartmouth College</h2>
A toolkit for matrix factorization of soundscape spectrograms into independent streams of sound objects, possibly representing individual species or independent group behaviours. 
The method employs shift-invariant probabilistic latent component analysis (SIPLCA) for factoring a time-frequency matrix (2D array) into a convolution of 2D kernels (patches) with sparse activation functions. 
Methods are based on the following:
Smaragdis, P, B. Raj, and M.V. Shashanka, 2008. Sparse and shift-invariant feature extraction from non-negative data. In proceedings IEEE International Conference on Audio and Speech Signal Processing, Las Vegas, Nevada, USA.
Smaragdis, P. and Raj, B. 2007. Shift-Invariant Probabilistic Latent Component Analysis, tech report, MERL technical report, Camrbidge, MA.
A. C. Eldridge, M. Casey, P. Moscoso, and M. Peck (2015) A New Method for Ecoacoustics? Toward the Extraction and Evaluation of Ecologically-Meaningful Sound Objects using Sparse Coding Methods. PeerJ PrePrints, 3(e1855) 1407v2 [In Review]
End of explanation
sound_path = 'sounds'
sounds = os.listdir(sound_path)
print "sounds:", sounds
Explanation: <h2>Example audio</h2>
Load an example audio file from the 'sounds' directory, 44.1kHz, stereo, 60 seconds duration.
End of explanation
N=4096; H=N/4
x,sr,fmt = wavread(os.path.join(sound_path,sounds[0]))
print "sample_rate:", sr, "(Hz), fft size:", (1000*N)/sr, "(ms), hop size:", (1000*H)/sr, "(ms)"
Explanation: <h2>Spectrum Analysis Parameters</h2>
Inspect the soundfile by loading it (using wavread) and printing some useful parameters.
A window size of 4096 with a hop of 1024 translates to 92ms and 23ms respectively for an audio samplerate of 44100Hz
End of explanation
# 1. Instantiate a new SoundscapeEcololgy object using the spectral analysis parameters defined above
S = SoundscapeEcology(nfft=N, wfft=N/2, nhop=H)
# Inspect the contents of this object
print S.__dict__
# 2. load_audio() - sample segments of the soundfile without replacement, to speed up analysis
# The computational complexity of the analysis is high, and the information in a soundscape is largely redundant
# So, draw 25 random segments in time order, each consisting of 20 STFT frames (~500ms) of audio data
S.load_audio(os.path.join(sound_path,sounds[0]), num_samples=25, frames_per_sample=20) # num_samples=None means analyze the whole sound file
# 3. analyze() into shift-invariant kernels 
# The STFT spectrum will be converted to a constant-Q transform by averaging over logarithmically spaced bins
# The shift-invariant kernels will have shift and time-extent dimensions
# The default kernel shape yields 1-octave of shift (self.feature_params['nbpo']), 
# and its duration is frames_per_sample. Here, the num_components and win parameters are illustrated.
S.analyze(num_components=7, win=(S.feature_params['nbpo'], S.frames_per_sample))
# 4. visualize() - visualize the spectrum reconstruction and the individual components
# inputs:
#    plotXi - visualize individual reconstructed component spectra [True]
#    plotX - visualize original (pre-analysis) spectrum and reconstruction [False]
#    plotW - visualize component time-frequency kernels [False]
#    plotH - visualize component shift-time activation functions [False]
#    **pargs - plotting key word arguments [**self.plt_args]
S.visualize(plotX=True, plotXi=True, plotW=True, plotH=True)
# 5. resynthesize() - sonify the results
# First, listen to the original (inverse STFT) and the full component reconstruction (inverse CQFT with random phases)
x_orig = S.F.inverse(S.X)
x_recon = S.F.inverse(S.X_hat, Phi_hat=(np.random.rand(*S.F.STFT.shape)*2-1)*np.pi) # random phase reconstruction
play(balance_signal(x_orig))
play(balance_signal(x_recon))
# First, listen to the original (inverse CQFT with original phases in STFT reconstruction) 
# and the all-components reconstruction (inverse CQFT with random phases)
# Second, listen to the individual component reconstructions
# Use the notebook's "interrupt kernel" button (stop button) if this is too long (n_comps x audio sequence)
# See above plots for the individual component spectrograms
for k in range(S.n_components):
    x_hat = S.resynthesize(k) # resynthesize individual component
    play(balance_signal(x_hat)) # play it back
Explanation: <h2>SoundscapeEcology Toolkit</h2>
Analyze species-specific patterns in environmental recordings
SoundscapeEcology methods:
        load_audio()   - load sample of a soundscape recording
        sample_audio_dir() - load group sample from multiple recordings
        analyze()      - extract per-species?? time-frequency partitioning from loaded audio
        visualize()    - show component spectrograms 
        resynthesize() - reconstruct audio for component spectrograms to sonify
        model_fit_resynhesize() - generative statistical model of time-shift kernels
        summarize()    - show soundscape ecology entropy statistics
SoundscapeEcology static methods:
        batch_analyze() - multiple analyses for a list of recordings
        entropy() - compute entropy (in nats) of an acoustic feature distribution
        gen_test_data() - generate an artificial soundscape for testing
Workflows:
     [load_audio(), sample_audio_dir()] -&gt; analyze() -&gt; [visualize(), resynthesize(), summarize()]
In the following example we will:
1. Instantiate a new SoundscapeEcololgy object
2. load_audio() and sample segments of it without replacement
3. analyze() extract Constant-Q Frequency Transform (CQFT) and extract shift-invariant kernels 
4. visualize() - reconstruct individual component features (CQFT) and make subplots
5. resynthesize() - invert individual feature reconstructions back to audio for sonifying
End of explanation
<END_TASK>