Due to the limitations of Pyodide which does not include support for the librosa Python library, we will exclusively work with WAV files, specifically those with a sample rate of 44100 Hz. No other types of audio files will be considered.
Independent Component Analysis (ICA) is a computational technique designed to separate a multivariate signal into its additive, independent non-Gaussian components. This method is particularly effective for analyzing mixed signals that originate from multiple sources. In contrast to Principal Component Analysis (PCA), which seeks orthogonal components that maximize variance under the assumption of Gaussian source signals, ICA identifies components based on their statistical independence rather than their variance. Unlike PCA, which is significantly influenced by the orientation of the first eigenvector, ICA does not prioritize components based on variance. Instead, it focuses on the statistical independence of components, ensuring that each component's amplitude at any given point is unrelated to that of any other at the same time, indicative of their origins from distinct physical processes.
PCA reduces data dimensionality by emphasizing the variance captured by the first few eigenvectors, potentially leading to a reliance on the first principal component. This reliance is due to the first eigenvector's orientation, determined by the direction associated with the maximum variance principal component (PC). In contrast, ICA's approach to signal separation is not constrained by the variance or order of components. It seeks to identify independent sources within the signal mixtures, guided by the statistical properties of the signals rather than their variance. This fundamental difference underlines ICA's utility in separating mixed signals into components that represent original, independent sources, free from the hierarchical constraints of variance prioritization seen in PCA.
ICA is rooted in fundamental mathematical concepts such as entropy maximization, likelihood estimation, and the utilization of non-linear functions, notably the hyperbolic tangent (tanh), to approximate the cumulative distribution functions (CDFs) of source signals. A hallmark of successful separation through ICA is the alignment of the joint distribution of signals with the product of their marginal distributions, signifying statistical independence. Key characteristics of signal mixtures include (1) the independence of source signals versus the dependence observed in mixtures, (2) the presence of non-Gaussian histograms for each source signal in contrast to Gaussian histograms for mixtures, and (3) the lower complexity found in the simplest source signal compared to any of its mixtures. These principles underscore the theoretical and practical underpinnings of ICA, distinguishing it from other signal processing methods by emphasizing the non-Gaussian nature and statistical independence of source signals.
Independent Component Analysis (ICA) boasts a wide array of applications, from speech processing and brain imaging using functional Magnetic Resonance Imaging (fMRI) to the analysis of electrical brain signals via Electroencephalography (EEG). Its core advantage lies in the ability to discern and isolate source signals from their mixtures based on unique properties — particularly their statistical independence, non-Gaussian distribution, and comparative simplicity. This distinction is crucial in fields requiring precise signal separation, such as distinguishing individual voices in a noisy environment or isolating specific brain activities from complex imaging data. Furthermore, ICA's adaptability is showcased through its spatial and temporal variants: Spatial ICA (sICA) excels in analyzing data points like image pixels to segregate different visual sources, making it indispensable in image processing, while Temporal ICA (tICA) is pivotal for unraveling sequences over time, such as isolating distinct audio tracks or analyzing temporal brain signal patterns. This dual capability highlights ICA's comprehensive approach to addressing analytical challenges across a spectrum of domains, enhancing its utility in both spatially and temporally oriented data analysis.
FastICA, while aligned with the fundamental objective of the ICA to separate mixed signals into independent components, introduces specific nuances in its approach, theoretical focus, and practical execution, making it a variant of the broader family of ICA algorithms.
Distinctly, FastICA is tailored for rapid convergence by employing a negentropy approximation to optimize for non-Gaussianity. Its fixed-point iteration scheme for updating the unmixing matrix stands out for its efficiency. Although the implementation may slightly differ concerning the choice of non-linear functions (e.g., logcosh or exp) to approximate negentropy, the underlying principle of non-Gaussianity maximization remains intact. Other salient features include:
Amazon's Alexa is equipped with an innovative feature through its LED ring atop the device, which plays a crucial role beyond mere aesthetic appeal. When activated with the wake word "Alexa," this LED ring serves as a directional indicator, illuminating to point towards the source of the voice. This functionality not only adds an element of interaction by mimicking human-like responsiveness to sound sources but also signifies the sophisticated audio processing capabilities of the device. The directional illumination of the LED ring is a direct outcome of the device's ability to analyze and locate the origin of the sound, a process rooted deeply in the principles of independent component analysis (ICA).
ICA is pivotal for two primary functions within Alexa's operational framework. Firstly, it aids in pinpointing the direction from which the voice command is issued. By separating the mixed audio signals received by Alexa's microphones into their independent components, the system can identify the specific direction of the sound source. This process allows Alexa to "focus" on the speaker, enhancing user interaction by providing visual feedback through the LED ring.
Secondly, ICA plays a vital role in background noise reduction, a critical factor in far-field speech recognition. Voice commands captured from a distance inherently carry more noise and reverberation compared to those spoken directly into a device, such as a smartphone. These disturbances, primarily caused by sound waves reflecting off surfaces like walls or windows, can significantly hinder speech recognition accuracy. Through ICA, Alexa can effectively isolate the voice command from the background noise and reverberation. This isolation not only improves the clarity of the signal being processed but also enhances Alexa's ability to understand and respond to the user accurately, even in acoustically challenging environments.
ffmpegMac: Install using Homebrew:
brew install ffmpeg
Linux: Install using apt for Ubuntu or Debian:
sudo apt-get install ffmpeg
Once ffmpeg is installed, you can convert an MP3 file to WAV format with the following command:
ffmpeg -i input.mp3 output.wav
soxMac: Install using Homebrew:
brew install sox
Linux: Install using apt for Ubuntu or Debian:
sudo apt-get install sox
With sox installed, convert an MP3 file to WAV format with the following command:
sox input.mp3 output.wav
This explores the field of audio processing with our Independent Component Analysis (ICA) tool, crafted with medical professionals and researchers in mind. This software aids in the separation of complex audio signals, with a focus on heart and lung sounds.


This attached Python script first generates the mixed wavelets of heart and lung sounds. You can view and listen to this mixed sound:
Each iteration of the ICA algorithm generates two wavelet visualization files and two sound files:










In the pursuit of advancing and streamlining signal processing workflows, two new Python modules have been developed: nGene_rpy2 and nGene_Waveform. These modules are designed to facilitate the integration of R scripts into Python applications and to efficiently manage waveform data. The following sections provide an overview of these modules and demonstrate their practical applications.
nGene_rpy2 is a Python class that utilizes the rpy2 library to seamlessly integrate R scripts and packages into Python applications. This class enables the loading of R code from files or strings, the importation of R packages, and the invocation of R functions directly from Python. Such integration is instrumental in leveraging R's advanced statistical and signal processing capabilities within a Python environment.
The following example demonstrates the utilization of nGene_rpy2 to perform Independent Component Analysis (ICA) using R's fastICA function:
nGene_Waveform is a Python class dedicated to the processing and visualization of waveform data. This class simplifies tasks such as reading audio files, normalizing signals, saving audio data, and plotting waveforms. It is essential for applications involving audio signal processing, particularly within the context of biomedical signals like heart and lung sounds.
.wav files and normalization of audio signals for processing..wav files.The example below illustrates how to utilize nGene_Waveform to read audio files and plot their waveforms:
main.py serves as an example script demonstrating the application of the nGene_rpy2 and nGene_Waveform classes to perform Independent Component Analysis (ICA) on mixed audio signals, such as heart and lung sounds. Users may adapt this script to their specific requirements by renaming it accordingly.
nGene_rpy2 and nGene_Waveform..wav files.The complete script is available in main.py. Users may adapt this script as needed:
nGene_rpy2 and nGene_Waveform.nGene_rpy2.nGene_Waveform to read and normalize heart and lung sound files.nGene_rpy2 to execute the fastICA function from R on the mixed signals.nGene_Waveform..wav files for further analysis or playback.Upon executing main.py, the script generates both console output and waveform plots. These outputs demonstrate the successful integration of R scripts within Python and the effective separation of audio signals using Independent Component Analysis (ICA).
The console output provides detailed logs of the script's execution process, including information about loading scripts, processing audio data, performing ICA, and saving the results. You can download the complete console output for further inspection:
/Users/frank/nGeneDL20241116/pythonProject/.venv/bin/python /Users/frank/nGeneDL20241116/pythonProject/main.py
Using R code from file: fastICA.R
2024-11-17 06:50:35,274 - nGene_rpy2 - INFO - Detected R installation: R version 4.4.1 (2024-06-14)
2024-11-17 06:50:35,274 - nGene_rpy2 - DEBUG - Activated numpy2ri and pandas2ri for automatic data conversion.
2024-11-17 06:50:35,274 - nGene_rpy2 - DEBUG - Initialized internal dictionaries for packages and scripts.
2024-11-17 06:50:35,276 - nGene_rpy2 - INFO - Loaded R script into package 'DefaultPackage'.
2024-11-17 06:50:35,276 - nGene_rpy2 - INFO - Loaded R script from file 'fastICA.R' into package 'DefaultPackage'.
2024-11-17 06:50:35,276 - nGene_Waveform - DEBUG - Initialized nGene_Waveform instance.
2024-11-17 06:50:35,278 - nGene_Waveform - INFO - Fetched and normalized audio data from 'heart_sound.wav'.
2024-11-17 06:50:35,278 - nGene_Waveform - INFO - Fetched and normalized audio data from 'lung_sound.wav'.
2024-11-17 06:50:35,279 - nGene_rpy2 - DEBUG - Retrieved fastICA package successfully.
2024-11-17 06:50:35,281 - nGene_rpy2 - DEBUG - Converted NumPy array to R matrix.
2024-11-17 06:50:35,281 - nGene_rpy2 - DEBUG - Retrieved R function 'fastICA' from package.
2024-11-17 06:50:35,319 - nGene_rpy2 - INFO - Called R function 'fastICA' successfully.
2024-11-17 06:50:35,319 - nGene_rpy2 - INFO - Executed fastICA function successfully.
2024-11-17 06:51:13,560 - nGene_Waveform - INFO - Plotted waveforms successfully.
2024-11-17 06:51:13,562 - nGene_Waveform - INFO - Saved separated signal 1 to 'separated_signal_1.wav'.
2024-11-17 06:51:13,564 - nGene_Waveform - INFO - Saved separated signal 2 to 'separated_signal_2.wav'.
The waveform plot visualizes the original, mixed, and separated audio signals, providing a clear representation of the ICA process. You can view the waveform plot below or download the image for your records:
| Topic | Details |
|---|---|
| Purpose |
Two-column HTML5 studio for audio/video playback, live signal visualization, lightweight tempo analysis, and simple source–mixture experiments. Pure vanilla JS; SVG-only waveforms; no frameworks or Canvas. New in v 3.3.5 line (3.3.1–3.3.5): Trim (loop-based clip creation with auto-download), matrix-based Mix of the last two items, and ICA separation of stereo mixes into two mono sources. |
| Layout |
Left column: Player (seek/loop, playhead cursor, volume, speed, transport controls, playlist, uploads). Right column: Trim · Mix · ICA toolbar, Tempo details panel, and Signal views (Overview, Mid, Micro, and band rows: Low/Mid/High). |
| File locations |
Place nws.html anywhere.Primary playlist: ./playlist.json (same folder as nws.html).Legacy/fallback playlist and tempo meta: optional sibling folder /media/ containing playlist.json and tempo_meta.json.
Files should be world-readable (e.g., chmod 644 *).
|
| Playlist |
On load, the player first attempts ./playlist.json (array of media entries, order preserved); if unavailable, a legacy /media/playlist.json is attempted.Absent JSON → starts empty and awaits uploads (drag-&-drop or picker). Uploaded files are referenced via blob-URLs only (no disk writes). |
| Playlist ordering |
Each row contains a dedicated ↓ button that sends that item directly to the bottom of the playlist while preserving the order of all others. The currently selected row remains highlighted; index bookkeeping is adjusted so that the audible selection is preserved when possible. |
| Trim |
Trim cuts the current loop range of the selected item into a new media item and appends it to the playlist, then immediately plays it. Audio items: decoded into an AudioBuffer, sliced in the loop interval, given short fade-in/fade-out ramps, encoded as 16-bit PCM WAV, and added as a new playlist entry.Video items: preferred path uses MediaRecorder on a captureStream() of the element over the loop range, targeting MP4 when supported and falling back to WebM; a pure audio WAV fallback is used when capturing A/V is not possible.New in v 3.3.4–3.3.5: the trimmed clip is auto-downloaded using the same filename shown in the playlist (WAV or MP4/WebM), immediately after creation. |
| Mix (matrix A) |
Mix combines the last two playlist entries into a stereo mixture using a fixed 2×2 mixing matrix:A = [[1, 1], [0.5, 2]], where rows index output channels (L,R) and columns index sources (S1,S2).Processing: each source is downmixed to mono, linearly resampled to a common sample rate, then mixed by A with automatic peak-based scaling to avoid clipping.Output: stereo WAV blob (L = mixture#1, R = mixture#2), auto-named as MixA_S1+S2_YYYYMMDDhhmmss.wav, appended to the playlist, and auto-selected for playback. Tempo metadata and overview are computed for the mix and stored under its filename.
|
| ICA separation |
ICA operates on the currently selected stereo item (e.g., a Mix result). Internals: 2×N mixtures are centered, whitened via a 2×2 symmetric eigendecomposition, then separated with a 2-component FastICA (tanh nonlinearity, symmetric decorrelation between components, Frobenius-norm convergence). Output: two mono WAV signals ( ICA_A_of_* and ICA_B_of_*), normalized with modest headroom and short fades, appended to the playlist as independent entries with their own tempo and overview metadata.
|
| Decoding & fallback |
Primary decoding path: decodeAudioData on fetched/uploaded bytes. For playlist URLs, fetch is attempted first.Fallback: full-length or range-limited capture via MediaElementSource → AudioWorklet (preferred) or ScriptProcessor, routed through a zero-gain node to keep the capture path inaudible. The muted property is never used in logic.
|
| Tempo metadata |
If present, /media/tempo_meta.json (keyed by filename) provides BPM and auxiliary fields (confidence, beat period, half/double suggestions, textual tempo class), which are reflected both in the playlist badge and the Tempo details panel.Otherwise, an internal estimator runs on decoded buffers or short capture segments, yielding approximate BPM and beat-period values sufficient for exploratory work. |
| Uploads |
Accessible uploader with ➕ Upload button and drag-&-drop support; the uploader itself is keyboard-focusable. Typical formats: MP3, M4A, FLAC, WAV, OGG, AAC, and common video containers such as MP4, MOV, WebM, MKV, and AVI. |
| First-30-second cue | Uploader border and hint text gently pulse every 2 s for the first 30 s after load, encouraging an initial user gesture that reliably resumes the AudioContext on modern browsers. |
| A–B Looping |
Seek bar shows cerulean A (“[”) and B (“]”) handles plus a thin ultramarine loop fill, always constrained within the gray full-track bar. ✖ Clear restores full-length playback. During playback, when the playhead reaches B, it wraps to A (with a small tolerance) as long as the loop is active. |
| Playhead | Current time is indicated by a vertical “I”; the center of that stroke corresponds to the true position. The playhead is draggable and is clamped within the current loop range. |
| Click-to-toggle video | Single-click on the video element toggles play/pause; double-click toggles fullscreen. The central ⏸︎/▶︎ transport button remains synchronized with element state. |
| Autoplay | The first playlist item may start automatically depending on browser autoplay policy. The AudioContext resumes on the first user interaction (click, drag, drop, or keyboard action) to ensure consistent audio routing. |
| Repeat Mode |
Repeat cycles between One (🔁 with “1”), All (🔁), and Off (⛔). With an A–B loop active, playback wraps within the loop regardless of repeat mode. When the loop is cleared, Repeat = All advances across playlist items; Repeat = One replays the same item. |
| Controls | ⏮︎ Prev • ⏸︎/▶︎ Toggle • ⏭︎ Next • 🔁/⛔ Repeat • ✖ Loop-Clear • ⛶ Fullscreen (video). |
| Seek & Time |
Smooth range input with live “elapsed / total” time label, draggable A–B handles, thin loop fill, and a precise “I”-shaped cursor.Loop bounds constrain both seeking and continuous playback; a small, duration-dependent epsilon avoids stickiness at the upper boundary during wrap. |
| Volume |
0–500 % via WebAudio GainNode (primary route, single audible path).If WebAudio is unavailable, a graceful fallback uses native element volume (0–100 %). The design avoids double-routing and unintended parallel audio paths. |
| Speed | 0.05× – 2.00× with − / + step buttons (0.01 increments) and a 1× reset button. The same playback rate is applied to both audio and video media elements. |
| Tempo details |
Tempo panel presents BPM (with confidence), beat period (ms), half/double candidates, tempo class (Slow/Moderate/Fast), and effective BPM at the current playback speed (BPM × rate). The panel is visible whenever either file-based metadata or the internal estimator provides data for the selected item. |
| Overview (playlist.json-aware) |
Overview is a whole-file SVG representation built from min/max envelopes over fixed buckets. In v 3.3.5, an internal helper ensures that an Overview is generated for the currently selected item even when it comes from playlist.json loaded at startup (audio or video).Once constructed, the same Overview supports both the main Overview view and the centered Micro view around the playhead. |
| Signal views |
Overview (entire file, absolute timebase, interactive loop brackets and cursor), Mid (live trailing window, default 8 s), and Micro (centered ±3 s around the playhead; falls back to trailing when no Overview is available). Band rows (Low ≤~200 Hz, Mid ~200–2000 Hz, High ≥~2 kHz) use a simple one-pole filter bank per band and share the same trailing length as the Mid window, with distinct color-coded strokes for quick visual discrimination. |
| Live tap |
AudioWorklet-based collector (preferred) or ScriptProcessor fallback receives data from the shared MediaElementSource nodes via an inaudible zero-gain branch.Envelope rings are filled at an effective rate of ~2 kHz and decimated to maintain responsiveness while limiting CPU load. Tap operations do not alter the audible signal. |
| Resizable wrapper |
Outer .wrapper uses resize:both; the default width is governed by --w (980 px), suitable for dual-column layouts on desktop screens.The playlist panel is vertically resizable, allowing adaptation to longer track lists or small windows. |
| Accent colour |
Changing --accent (default #1e90ff) rebrands key UI elements, including buttons, sliders, pulse highlights, and active playlist rows, while preserving structural CSS.
|
| Fullscreen | The ⛶ button and the F key toggle fullscreen for video items only; audio items retain the compact layout. The output route is re-applied on fullscreen changes to maintain consistent gain behaviour. |
| Source-code reveal | Embedded “Full Source Code” accordion shows the entire page’s HTML/JS/CSS, syntax-highlighted via Highlight.js, allowing inspection, copy-paste, and regression testing from a single file. |
| Namespace |
All logic resides inside a single IIFE; public surface is limited to instantiation of the WaveformStudio class against the #box container. CSS is scoped by class names to minimize interaction with surrounding pages or frameworks.
|
| Notes & caveats |
Decoding and cross-origin fetching depend on server CORS configuration; when direct decoding fails, the capture-based fallback is used instead. Some exotic codecs or DRM-protected streams may remain unsupported. Mixed, trimmed, and ICA-derived outputs are held as in-memory blobs and appear as playlist entries; only Trim explicitly triggers a download by default in v 3.3.5. |
| Topic | Details |
|---|---|
| Purpose |
Two-column HTML5 studio for audio/video playback, live signal visualization, and lightweight tempo analysis.
Pure vanilla JS; SVG-only waveforms; no frameworks or Canvas. New in v 3.1.0: Mix button (right column) that combines the last two playlist items into a headroom-safe WAV and appends it to the playlist for immediate playback. |
| Layout |
Left column: Player (seek/loop, volume, speed, transport, playlist, uploads). Right column: Mix toolbar, Tempo details panel, and Signal views (Overview, Mid, Micro, and band rows). |
| File locations |
Place nws.html anywhere.Optional sibling folder /media/ for playlist.json and tempo_meta.json.
Ensure readable permissions (e.g., chmod 644 *).
|
| Playlist |
Optional /media/playlist.json — array of media paths (order preserved).Absent JSON → starts empty and awaits uploads (drag-&-drop or picker). Uploaded files are referenced via blob-URLs (no disk writes). |
| Mix (new) |
Click Mix to combine the last two playlist entries (audio or the audio track of video). Processing: OfflineAudioContext offline render; per-track gain = 0.5 for headroom; linear sum; length = max(duration).Output: in-memory WAV blob, auto-named as Mix - A + B.wav, appended to the playlist, and auto-played. Status text reports progress or errors (e.g., CORS/decoding).
|
| Decoding & fallback |
Primary: decodeAudioData on fetched/uploaded bytes.Fallback: full-length capture via MediaElementSource → Worklet/ScriptProcessor (kept inaudible through a zero-gain node; no muted property used).
|
| Tempo metadata |
If available, /media/tempo_meta.json (keyed by filename) populates BPM and related fields in the list and Tempo panel.
When absent, a quick internal estimator computes approximate BPM/beat period from short decoded segments or short captures.
|
| Uploads | ➕ Upload button and drag-&-drop; keyboard focusable uploader. Uploaded audio/video formats commonly supported: MP3/M4A/FLAC/WAV and MP4/MOV/WEBM/MKV/AVI. |
| First-30-second cue | Uploader border and hint gently pulse every 2 s for the first 30 s after load to encourage interaction (resumes AudioContext reliably). |
| A–B Looping |
Seek bar shows cerulean A (“[”) and B (“]”) handles and a thin ultramarine loop fill, always inside the gray full-track bar. ✖ Clear restores full-length playback instantly. |
| Playhead | Current time indicated by a vertical “I”; the center of the line is the true position. Draggable, clamped within the loop. |
| Click-to-toggle video | Single-click on video toggles play/pause; double-click toggles fullscreen. The ⏸︎/▶︎ control remains synchronized. |
| Autoplay | First item may start automatically (per browser policy). AudioContext resumes on first user gesture (click, drag, drop) for consistent sound. |
| Repeat Mode |
Cycles: One (🔁 with “1”) → All (🔁) → Off (⛔). With a loop active, playback wraps to loop start. After clearing loop and with Repeat = All, playback advances to the next track. |
| Controls | ⏮︎ Prev • ⏸︎/▶︎ Toggle • ⏭︎ Next • 🔁/⛔ Repeat • ✖ Loop-Clear • ⛶ Fullscreen (video). |
| Seek & Time |
Smooth range input with live “elapsed / total”, draggable A–B handles, thin loop fill, and precise “I” cursor.
Loop bounds clamp seeking and playback, with edge-aware wrap to loop start.
|
| Volume |
0–500 % via WebAudio GainNode (primary route).
Graceful fallback uses element volume (0–100 %) if WebAudio is unavailable. Single audible route is always maintained.
|
| Speed | 0.05× – 2.00× with − / + step buttons (0.01) and 1× reset. Applies to audio and video uniformly. |
| Tempo details | BPM (with confidence), beat period (ms), half/double suggestions, tempo class (Slow/Moderate/Fast), and effective BPM at current speed. Panel appears when data are available (from metadata file or internal estimator). |
| Signal views | Overview (whole file; absolute “now” marker), Mid (live trailing window, default 8 s), Micro (centered ±3 s around playhead; falls back to trailing if overview not ready), and Band rows (Low ≤~200 Hz, Mid ~200–2000 Hz, High ≥~2 kHz) with color-coded strokes. Window lengths selectable; ✖ clears live buffers. |
| Live tap |
AudioWorklet collector (preferred) or ScriptProcessor fallback feeds envelope rings at ~2 kHz sampling for responsive SVG paths.
Capture remains inaudible through a zero-gain branch; no reliance on muted.
|
| Resizable wrapper |
Outer .wrapper uses resize:both; default width from --w (980 px for two columns).
Track list is vertically resizable.
|
| Accent colour |
Adjust --accent (default #1e90ff) to rebrand buttons, sliders, uploader, and active highlights.
|
| Fullscreen | Dedicated ⛶ button and keyboard F toggle fullscreen for video items. |
| Source-code reveal | Built-in “Full Source Code” accordion displays the whole page, syntax-highlighted via Highlight.js, for sharing and tests. |
| Namespace | All logic is encapsulated in an IIFE; CSS classes are locally scoped. Safe to embed alongside other pages and scripts. |
| Notes & caveats | Decoding and cross-origin fetching depend on server CORS policies; when decoding fails, the inaudible capture fallback is attempted. Mixed output is stored as an in-memory blob (download prompt is not issued automatically). |
| Topic | Details |
|---|---|
| Purpose |
Self-contained, resizable HTML5 media player for audio
(MP3/M4A/FLAC/WAV) and video (MP4/MOV/WEBM/MKV/AVI).
Pure vanilla JS—no frameworks. New since v 2.6: vertical “I” playhead (center = true position), refined A–B loop visuals, hardened uploads/drag-&-drop, reliable play/pause with AudioContext resume. |
| File locations |
Place nmp.html anywhere.Media files live in sibling /media/.Ensure readable permissions, e.g., chmod 644 *.
|
| Playlist |
Optional /media/playlist.json — array of media paths (order preserved).
If absent, player starts empty and waits for user uploads.
|
| Tempo metadata |
Player reads tempo_meta.json (keyed by filename)
to show integer-rounded BPM beside each track
and in the title line (e.g., “128 BPM”).
|
| Uploads | ➕ Upload button and drag-&-drop. Files are played via blob-URLs (no disk writes). The dashed uploader box is clickable and keyboard-focusable. |
| First-30-second attention cue | Uploader border and hint softly pulse/glow every 2 s for the first 30 s after load. |
| A–B Looping |
Seek bar shows two cerulean brackets: • A handle “[” — loop start. • B handle “]” — loop end. Ultramarine blue loop bar (thinner) fills the loop region and is always fully inside the gray full-length bar (entire track). ✖ Clear resets loop to full-length instantly. |
| Playhead | Current position is a vertical “I” line; its center is the true time point. It can be dragged, and is always clamped inside the blue loop bar. |
| Click-to-toggle video | Click anywhere on the visible video to play/pause; ⏸︎/▶︎ stays in sync. Double-click toggles fullscreen. |
| Autoplay | First item starts automatically (subject to browser policy). AudioContext is resumed on first user gesture (e.g., button, drag, drop) for reliable playback. |
| Repeat Mode |
Cycles: 🔂 One → 🔁 All → ⛔ Off. With a loop active, playback wraps to the loop start. After you press ✖ to clear loop and Repeat = All, the player advances to the next track at end (not the same track). |
| Controls | ⏮︎ Prev • ⏸︎/▶︎ Toggle • ⏭︎ Next • 🔂/🔁/⛔ Repeat • ✖ Loop-Clear • ⛶ Fullscreen (video). |
| Seek & Time |
Sleek seek bar with live “elapsed / total” timer,
A–B handles, thin blue loop bar, and draggable “I” playhead.
|
| Volume | 0–200 % gain via WebAudio (gain node). Default is 33 %. If WebAudio is unavailable, falls back to element volume (0–100 %). |
| Speed | 0.05× – 2.00× slider with − / + step buttons (0.01) and 1× reset. Applies to both audio and video. |
| Resizable wrapper |
Outer .wrapper uses resize:both;
default width from --w (360 px).
Track-list is vertically resizable.
|
| Accent colour |
Edit --accent (default #1e90ff)
to rebrand buttons, slider thumbs, uploader, and active track highlight.
|
| Fullscreen | Dedicated ⛶ button and keyboard F toggle fullscreen for video items. |
| Source-code reveal | Built-in “Full Source Code” accordion shows the entire page, syntax-highlighted via Highlight.js (for easy sharing/tests). |
| Namespace | All logic wrapped in an IIFE; CSS uses scoped class names. Safe to embed alongside other scripts and styles. |
| Topic | Details |
|---|---|
| Purpose | Self-contained, resizable HTML5 player for audio (MP3/M4A) and video (MP4/MOV/WEBM). Pure vanilla JS—no frameworks required. New since v 1.8: tempo-aware track-list showing BPM (integer-rounded), auto-loading from tempo_meta.json; initial volume defaults to 17 % at page-load.
|
| File locations | Place nmp.html anywhere.Media files live in a sibling /media/ folder.Ensure readable permissions with chmod 644 *.
|
| Playlist | Optional /media/playlist.json—an array of paths (order preserved). If absent, the player simply waits for user uploads. |
| Tempo metadata | Run extract_meta_from_media.py v 2.4 to generate tempo_meta.json (single integer-rounded bpm). Player displays it beside each track and in the title-bar as “### BPM”. |
| Uploads | ➕ Upload button and drag-&-drop. Files become blob-URLs, so nothing is written to disk. |
| First-30-second attention cue | Uploader border, hint-text and container gently pulse, glow and scale every 2 s for the first 30 s after page-load. |
| A-B Looping | Seek-bar sports two cerulean “brackets”: • A handle “[” — left edge marks loop-start. • B handle “]” — right edge marks loop-end. Drag to set; ultramarine bar fills the loop range. ✖ Clear button instantly resets the loop. |
| Click-to-toggle video | Click anywhere on the visible video to play/pause; the ⏸︎/▶︎ button stays synchronised. |
| Autoplay | The first track auto-starts; subsequent behaviour follows Repeat Mode. |
| Repeat Mode | Begins at 🔂 One (loop current). Button cycles: 🔂 One → 🔁 All → 🔁 Off. |
| Controls | ⏮︎ Prev • ⏸︎/▶︎ Toggle • ⏭︎ Next • Repeat — plus ✖ Loop-Clear beside the seek-bar. |
| Seek & Time | Sleek seek-bar with live “elapsed / total” timer, integrated A-B loop handles and ultramarine fill. |
| Volume | Smooth 0–100 % slider with live percentage label; initial default 17 % (0.17). |
| Speed | 0.70× – 2.00× slider with − / + step buttons and 1× reset. Applies to audio & video. |
| Resizable wrapper | Outer .wrapper uses resize:both; default width governed by --w (360 px). Track-list is vertically resizable. |
| Accent colour | Edit --accent (default #1e90ff) to rebrand buttons, slider thumbs, active-track row and uploader pulse. |
| Source-code reveal | Built-in “Full Source Code” accordion shows the entire page, syntax-highlighted via Highlight.js. |
| Namespace | All logic wrapped in an IIFE; CSS uses local class names—safe to embed anywhere. |
| Topic | Details |
|---|---|
| Purpose | Self‑contained, resizable HTML5 player for audio (MP3/M4A) and video (MP4/MOV/WEBM). Pure vanilla JS—no frameworks. New since v 1.6 (c): draggable cerulean‑blue “bracket” handles for precise A‑B looping, ultramarine loop‑fill, and click‑to‑toggle playback directly on the video surface. |
| File locations | Place nmp.html anywhere.Media files live in a sibling /media/ folder.Ensure readable permissions with chmod 644 *.
|
| Playlist | Optional /media/playlist.json—an array of paths (order preserved). If absent, the player simply waits for user uploads. |
| Uploads | ➕ Upload button and drag‑&‑drop. Files become blob‑URLs, so nothing is written to disk. |
| First‑30‑second attention cue | Uploader border, hint‑text and container gently pulse, glow and scale every 2 s for the first 30 s after page‑load. |
| A‑B Looping (1.8 series) | Seek‑bar sports two cerulean “brackets”: • A handle “[” — left edge marks loop‑start. • B handle “]” — right edge marks loop‑end. Drag to set; ultramarine bar fills the loop range. ✖ Clear button instantly resets the loop. |
| Click‑to‑toggle video | Click anywhere on the visible video to play/pause; the ⏸︎/▶︎ button stays synchronised. |
| Autoplay | The first track auto‑starts; subsequent behaviour follows Repeat Mode. |
| Repeat Mode (default) | Begins at 🔂 One (loop current). Button cycles: 🔂 One → 🔁 All → 🔁 Off. |
| Controls | ⏮︎ Prev • ⏸︎/▶︎ Toggle • ⏭︎ Next • Repeat — plus ✖ Loop‑Clear beside the seek‑bar. |
| Seek & Time | Sleek seek‑bar with live “elapsed / total” timer. Integrates A‑B loop handles and ultramarine fill described above. |
| Volume | Smooth 0–100 % slider with live percentage label. |
| Resizable wrapper | Outer .wrapper uses resize:both; default width governed by --w (360 px). Track‑list is vertically resizable. |
| Accent colour | Edit --accent (default #1e90ff) to rebrand buttons, slider thumbs, active‑track row and uploader pulse. |
| Source‑code reveal | Built‑in “Full Source Code” accordion shows the entire page, syntax‑highlighted via Highlight.js. |
| Namespace | All logic wrapped in an IIFE; CSS uses local class names—safe to embed anywhere. |