generated from mscheltienne/template-python
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deploying to gh-pages from @ a860091 🚀
- Loading branch information
0 parents
commit e24dd78
Showing
137 changed files
with
22,215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# macOS | ||
.DS_Store |
Empty file.
113 changes: 113 additions & 0 deletions
113
_downloads/0d95c47479bb83aaf162357584d36ccd/30_apply_a_window.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
""" | ||
============== | ||
Apply a window | ||
============== | ||
.. include:: ../../links.inc | ||
In signal processing and statistics, a window function (also known as an | ||
apodization function or tapering function) is a mathematical function that is | ||
zero-valued outside of some chosen interval, normally symmetric around the | ||
middle of the interval, usually near a maximum in the middle, and usually | ||
tapering away from the middle. Mathematically, when another function or | ||
waveform/data-sequence is "multiplied" by a window function, the product is | ||
also zero-valued outside the interval: all that is left is the part where they | ||
overlap, the "view through the window". | ||
Source: `Wikipedia <https://en.wikipedia.org/wiki/Window_function>`_ | ||
A sound waveform might have an abrupt onset or offset. It is often preferred to | ||
apply a window to ramp up and ramp down the volume. | ||
""" | ||
|
||
# %% | ||
|
||
# sphinx_gallery_thumbnail_number = 3 | ||
|
||
import numpy as np | ||
from matplotlib import pyplot as plt | ||
from scipy.signal.windows import tukey | ||
|
||
from stimuli.audio import Tone | ||
|
||
# %% | ||
# | ||
# In this tutorial, we will create a pure tone auditory stimuli and apply a | ||
# window with a linear ramp-up and a linear ramp-down to smooth the onset and | ||
# offset. | ||
|
||
# %% | ||
# Create a pure tone | ||
# ------------------ | ||
# | ||
# To create the stimuli, we create a :class:`~stimuli.audio.Tone` object with | ||
# a given volume and frequency. | ||
|
||
sound = Tone(frequency=200, volume=10, duration=0.1) | ||
|
||
# %% | ||
# By default, a generated signal will have a rectangular window applied. A | ||
# recctangular window is equal to 0 outside of the signal definition range, and | ||
# to 1 inside. We can plot the waveform of one of the channels: | ||
|
||
# draw the waveform | ||
_, ax = sound.plot() | ||
ax.set_title("Waveform - Rectangular window") | ||
|
||
# overlay a rectangular window | ||
# note: for demonstration purposes, we make the window 20% longer than the | ||
# signal by extending it by 10% before and after the signal. | ||
extension = int(0.1 * sound.times.size) | ||
window = np.zeros(extension + sound.times.size + extension) | ||
window[extension + 1 : extension + sound.times.size] = 1 / sound.volume | ||
# determine the timestamps associated to each sample in the window (ms) | ||
window_times = np.arange(0, 1 / sound.sample_rate * window.size, 1 / sound.sample_rate) | ||
window_times -= extension / sound.sample_rate | ||
# draw the window | ||
ax.plot(window_times, window, color="crimson") | ||
plt.show() | ||
|
||
# %% | ||
# Create a different window | ||
# ------------------------- | ||
# | ||
# For this tutorial, we will define a window with a ramp from ``0`` to ``1`` | ||
# during the first 10% of the total duration, and a ramp from ``1`` to ``0`` | ||
# during the last 10% of the total duration. A correctly defined window is a | ||
# 1D `~numpy.array` with the same number of samples as the sound. | ||
|
||
window = np.ones(sound.times.size) | ||
n_samples_ramp = int(0.1 * sound.times.size) | ||
ramp = np.linspace(start=0, stop=1, num=n_samples_ramp) | ||
window[:n_samples_ramp] = ramp | ||
window[-n_samples_ramp:] = ramp[::-1] | ||
|
||
# %% | ||
# Change the window | ||
# ----------------- | ||
# | ||
# We can change the applied window by setting the property ``window``. | ||
|
||
sound.window = window | ||
|
||
# draw the modified sound and the window | ||
_, ax = sound.plot() | ||
ax.set_title("Waveform - Ramp onset/offset window") | ||
ax.plot(sound.times, window / sound.volume, color="crimson") # overlay the window | ||
plt.show() | ||
|
||
# %% | ||
# Scipy windows | ||
# ------------- | ||
# | ||
# `scipy`_ has many windows implemented in :mod:`scipy.signal.windows`. For instance | ||
# we can use a Tukey window with the function `~scipy.signal.windows.tukey`. | ||
|
||
window = tukey(sound.times.size) | ||
sound.window = window | ||
|
||
# draw the modified sound and the window | ||
_, ax = sound.plot() | ||
ax.set_title("Waveform - Tukey window") | ||
ax.plot(sound.times, window / sound.volume, color="crimson") # overlay the window | ||
plt.show() |
61 changes: 61 additions & 0 deletions
61
_downloads/23dcf1a3cfcdf770fbf9a4983f0a29ed/40_sychronize_sound_and_trigger.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"\n# Synchronize sound and trigger\n\nOften, a trigger must be emitted simultenously with a sound onset, with as little delay\nand jitter as possible. With ``stimuli``, similarly to ``psychtoolbox``, the key concept\nis to schedule the sound.\n\nFirst, let's have a look at our default device latency.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"import sounddevice as sd\n\nfrom stimuli.audio import SoundAM\nfrom stimuli.time import sleep\nfrom stimuli.triggers import MockTrigger\n\nidx = sd.default.device[\"output\"]\nprint(f\"Low-latency (s): {sd.query_devices()[idx]['default_low_output_latency']}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Next, we can schedule a sound with the argument ``when`` which will use the clock\nprovided in the argument ``clock`` to schedule the sound. Then, we wait for this\nduration to elapse before sending the trigger.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"trigger = MockTrigger() # replace with your trigger object\nsound = SoundAM(\n frequency_carrier=1000,\n frequency_modulation=40,\n method=\"dsbsc\",\n volume=10,\n duration=1,\n)\nsound.play(when=0.5, blocking=False)\nsleep(0.5)\ntrigger.signal(1)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.10" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 0 | ||
} |
140 changes: 140 additions & 0 deletions
140
_downloads/5cd9f36d95a835433df7ed54eca518a8/30_apply_a_window.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"\n# Apply a window\n\n.. include:: ../../links.inc\n\nIn signal processing and statistics, a window function (also known as an\napodization function or tapering function) is a mathematical function that is\nzero-valued outside of some chosen interval, normally symmetric around the\nmiddle of the interval, usually near a maximum in the middle, and usually\ntapering away from the middle. Mathematically, when another function or\nwaveform/data-sequence is \"multiplied\" by a window function, the product is\nalso zero-valued outside the interval: all that is left is the part where they\noverlap, the \"view through the window\".\n\nSource: [Wikipedia](https://en.wikipedia.org/wiki/Window_function)\n\nA sound waveform might have an abrupt onset or offset. It is often preferred to\napply a window to ramp up and ramp down the volume.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\nfrom matplotlib import pyplot as plt\nfrom scipy.signal.windows import tukey\n\nfrom stimuli.audio import Tone" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"In this tutorial, we will create a pure tone auditory stimuli and apply a\nwindow with a linear ramp-up and a linear ramp-down to smooth the onset and\noffset.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Create a pure tone\n\nTo create the stimuli, we create a :class:`~stimuli.audio.Tone` object with\na given volume and frequency.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"sound = Tone(frequency=200, volume=10, duration=0.1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"By default, a generated signal will have a rectangular window applied. A\nrecctangular window is equal to 0 outside of the signal definition range, and\nto 1 inside. We can plot the waveform of one of the channels:\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"# draw the waveform\n_, ax = sound.plot()\nax.set_title(\"Waveform - Rectangular window\")\n\n# overlay a rectangular window\n# note: for demonstration purposes, we make the window 20% longer than the\n# signal by extending it by 10% before and after the signal.\nextension = int(0.1 * sound.times.size)\nwindow = np.zeros(extension + sound.times.size + extension)\nwindow[extension + 1 : extension + sound.times.size] = 1 / sound.volume\n# determine the timestamps associated to each sample in the window (ms)\nwindow_times = np.arange(0, 1 / sound.sample_rate * window.size, 1 / sound.sample_rate)\nwindow_times -= extension / sound.sample_rate\n# draw the window\nax.plot(window_times, window, color=\"crimson\")\nplt.show()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Create a different window\n\nFor this tutorial, we will define a window with a ramp from ``0`` to ``1``\nduring the first 10% of the total duration, and a ramp from ``1`` to ``0``\nduring the last 10% of the total duration. A correctly defined window is a\n1D `~numpy.array` with the same number of samples as the sound.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"window = np.ones(sound.times.size)\nn_samples_ramp = int(0.1 * sound.times.size)\nramp = np.linspace(start=0, stop=1, num=n_samples_ramp)\nwindow[:n_samples_ramp] = ramp\nwindow[-n_samples_ramp:] = ramp[::-1]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Change the window\n\nWe can change the applied window by setting the property ``window``.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"sound.window = window\n\n# draw the modified sound and the window\n_, ax = sound.plot()\nax.set_title(\"Waveform - Ramp onset/offset window\")\nax.plot(sound.times, window / sound.volume, color=\"crimson\") # overlay the window\nplt.show()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Scipy windows\n\n`scipy`_ has many windows implemented in :mod:`scipy.signal.windows`. For instance\nwe can use a Tukey window with the function `~scipy.signal.windows.tukey`.\n\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"window = tukey(sound.times.size)\nsound.window = window\n\n# draw the modified sound and the window\n_, ax = sound.plot()\nax.set_title(\"Waveform - Tukey window\")\nax.plot(sound.times, window / sound.volume, color=\"crimson\") # overlay the window\nplt.show()" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.10" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 0 | ||
} |
Oops, something went wrong.