Hamasaki Square Ambience — v1.3.1 User Guide

A practical 4-channel ambience processor inspired by Hamasaki Square practice. It accepts one mono or stereo Sound and produces four channels in the order L, R, Ls, Rs. The implementation is a signal-processing approximation; it does not model or decode a physical Hamasaki microphone array.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 1.3.1 (2026) License: MIT License Repo: GitHub
Contents:

What this does

The script requires exactly one selected Sound object with one or two channels. Any input with more than two channels is rejected. The output is one four-channel Sound named <source>_HamasakiSq.

Signal roles:
  • Stereo input: front L/R are extracted directly from the source. The rear source begins as the unscaled difference signal L - R, with an optional contribution from the average mid signal (L + R) / 2.
  • Mono input: the mono source is copied to both front channels; R is delayed by the requested mono-width value after sample rounding. Both front copies are then Hann-band filtered with fixed 20 Hz lower edges and different upper edges (18 kHz for L, 15 kHz for R). The rear source begins as the mono source itself.
  • Rears: the rear source is band-limited, delayed differently for Ls/Rs, gain-scaled, and given an additional filtering pass on Rs for spectral difference.
  • Final level: all four channels are combined first and then scaled together to the requested peak target.

The script contains no random process and no seed control. Given the same input, settings, and Praat behaviour, processing is deterministic.

Version note: the script header identifies v1.3.1 (2026) as a runtime visual-QA revision that corrects spacing between the waveform and summary regions; the DSP is unchanged from v1.3.

Quick start

  1. Select exactly one mono or stereo Sound object in Praat.
  2. Run Hamasaki_Square_Ambience.praat.
  3. Leave Preset = Custom to use the form values, or choose one of the five named presets. A named preset overrides the seven rear/width parameters listed below.
  4. Set Headroom_dB, Draw_visualization, and Play_result as required; named presets do not override these three controls.
  5. Click OK. The result is left selected as <source>_HamasakiSq.
No automatic file export: the current implementation creates an in-memory Praat Sound object only. Although the script header still mentions optional WAV saving, there is no save control and no file-writing command in the implementation.

Presets

The form opens with Custom selected. When a named preset is chosen, it overrides Rear_level_dB, Rear_delay_ms, Decorr_offset_ms, Mono_width_ms, Rear_highpass_Hz, Rear_lowpass_Hz, and Rear_mid_blend_dB.

PresetRear dBDelay msDecorr msMono width msHP HzLP HzMid blend dB
Custom defaults-93070.351206000-12
Subtle-62050.251007000-14
Natural-93070.351206000-12
Spacious-645100.401005500-10
Cinematic-360120.50808000-9
Wide Mono-93580.601505000-12
Wide Mono is not input-locked: it can also be selected for a stereo source. In that case its rear settings still apply, while Mono_width_ms is not used because the stereo front channels are extracted directly.

Processing pipeline

Stereo input

Front L = input L
Front R = input R
Side S = L - R
Mid M = (L + R) / 2
Rear source A = S + gmidM, when mid blend is enabled
gmid = 10^(Rear_mid_blend_dB / 20)
Rear gain grear = 10^(Rear_level_dB / 20)

If Rear_mid_blend_dB <= -100, g_mid is set to zero and the mid contribution is disabled. Stereo front channels receive no separate front filtering or delay before the final shared normalization.

Mono input

Front L begins as x
Front R begins as x delayed by round(Mono_width_ms / 1000 × sampleRate) samples
L then receives: Filter (pass Hann band), 20 Hz to 18 kHz, smoothing 100 Hz
R then receives: Filter (pass Hann band), 20 Hz to 15 kHz, smoothing 100 Hz
Rear source A = x + gmidx when mid blend is enabled
Rear source A = x when mid blend is disabled

For mono input, mid blend does not rescue a zero side signal: the code never uses a side signal in the mono path. Instead, enabled mid blend increases the mono rear source by adding a scaled copy of the same signal.

Rear filtering and decorrelation

rearFilt = HannBand(A, Rear_highpass_Hz, Rear_lowpass_Hz, smoothing=100 Hz)
Ls source = rearFilt
Rs source = HannBand(rearFilt, Rear_highpass_Hz, 0.85 × Rear_lowpass_Hz, smoothing=100 Hz)

Ls delay = max(0, Rear_delay_ms - Decorr_offset_ms / 2)
Rs delay = Rear_delay_ms + Decorr_offset_ms / 2

Ls = delayed(Ls source) × grear
Rs = delayed(Rs source) × grear

The important implementation detail is that Rs is filtered again from the already filtered rearFilt. It therefore receives a cascaded second Hann-band pass, with an upper edge at exactly 85% of the user/preset rear low-pass value; it is not simply an alternative one-pass filter at 85%.

All implemented delays are made by prepending silence and then extracting back to the original source duration. They therefore shift material later without lengthening the output, and the corresponding amount of tail material is discarded.

FORM & code behaviour

The comments in the form give typical-use suggestions, but most are not enforced ranges. The table below distinguishes the Praat field type from explicit code behaviour.

ControlDefaultWhat the code actually enforces
PresetCustomOption menu: Custom plus five named presets. Named presets override seven processing controls.
Rear_level_dB-9.0real; no explicit clamp. Converted directly with 10^(dB/20).
Rear_delay_ms30.0positive; no explicit upper clamp.
Decorr_offset_ms7.0positive; no explicit upper clamp. Only the computed Ls delay is clamped to zero if it would become negative.
Mono_width_ms0.35positive; no explicit upper clamp. Used only for mono input and rounded to an integer number of samples.
Rear_mid_blend_dB-12.0real; values <= -100 disable the blend. Other values are converted directly to linear gain.
Rear_highpass_Hz120.0positive; no explicit code range or sample-rate clamp.
Rear_lowpass_Hz6000.0positive; no explicit code range, HP/LP ordering check, or sample-rate clamp. Rs uses 0.85 × LP in its second pass.
Headroom_dB-1.0real; any value above 0 is clamped to 0. Negative values are otherwise not limited.
Draw_visualizationyesBoolean. Draws the Praat Picture visualization when enabled.
Play_resultyesBoolean. Calls Play on the four-channel result when enabled.

Output & normalization

The four mono working objects are combined in this order:

Output channelSignal
1L
2R
3Ls
4Rs

After the four-channel Sound is created, the script measures the absolute peak across the combined object and applies one gain factor to all four channels together:

Shared peak normalization

target = 10^(Headroom_dB / 20)
normGain = target / rawPeak
output = output × normGain

This is true normalization, not an attenuation-only ceiling: if the raw peak is below the target, the script amplifies the entire four-channel output. For numerical protection, a measured peak below 0.0001 is replaced by 0.0001 before calculating the gain.

Visualization (Praat Picture)

With Draw_visualization = yes, v1.3.1 draws:

The v1.3.1 revision changes the spacing between the waveform and summary regions; the processing path is unchanged.

Edge cases & troubleshooting

Very small stereo side signal

If L and R are very similar, L - R can be small. Increasing the mid blend adds (L + R)/2 at the selected gain before rear filtering. Setting the blend to -100 dB or below disables it.

Custom delay values can remove tail material

Delay is implemented by prepending silence and trimming back to the original duration. Large delay or mono-width settings therefore discard an equally long portion from the end; sufficiently extreme values can shift most or all audible content outside the retained window.

Custom filter values are not validated as a pair

The form requires positive HP/LP values, but the code does not enforce a specific range, verify HP < LP, verify HP < 0.85×LP for the Rs pass, or adapt the cutoffs to the source sample rate. Preset values are internally ordered; unusual custom values should be chosen with these constraints in mind.

Mono width is sample-quantized

The requested milliseconds are converted to samples with round(). The realized delay is therefore the nearest whole-sample delay at the source sampling rate, although the Info/visualization text reports the requested millisecond value.

Front-channel gain after processing

Stereo front L/R are copied without per-front processing, but they are still scaled by the final shared normalization. They are therefore preserved in content and balance before that final global gain, not necessarily at their original absolute sample level.