Repository navigation
Subtract
James Brundage edited this page Oct 23, 2026
·
1 revision
If the wave has no samples, this will simply set the samples to their inverse.
If a wave has samples, this will subtract the samples to the wave, mixing the audio together.
Parameters
The other wave
| required | type | position | pipeline | wildcard | aliases |
|---|---|---|---|---|---|
| false | Object | 1 | false | false |
The start time for the subtraction
| required | type | position | pipeline | wildcard | aliases |
|---|---|---|---|---|---|
| false | Object | 2 | false | false |
View Source
<#
.SYNOPSIS
Subtracts Samples
.DESCRIPTION
Subtracts Samples to a wave.
If the wave has no samples, this will simply set the samples to their inverse.
If a wave has samples, this will subtract the samples to the wave,
mixing the audio together.
#>
param(
# The other wave
$OtherWave,
# The start time for the subtraction
$Time = 0
)
# Collect our samples from the other wave
[double[]]$Samples =
# If the other wave is a `Wave`
if ($otherWave.pstypenames -contains 'wave') {
# get it's samples
$otherWave.Samples
}
# If the other wave can be cast to a `[double[]]`
elseif ($OtherWave -as [double[]])
{
# treat it as an array of samples
$OtherWave -as [double[]]
}
# Get our current samples
[double[]]$current = $this.Samples
# If we have no current samples
if (-not $current) {
# Then we are just going to add to the samples to the end
$this.Samples = foreach ($sample in $samples) {
$sample * -1
}
return $this
}
# If a start time was specified
if ($Time) {
# it could be a `[TimeSpan]`
if ($time -is [TimeSpan]) {
$time = $time.TotalSeconds
}
# Or a `[double]`
else {
$time = $time -as [double]
}
# Either way, set the start to the time
$start = $time
}
# If we have not set a start,
if (-not $start) {
$Start = 0 # initialize to zero
}
# Get the sample rate and channel count
$SampleRate = $this.SampleRate
$ChannelCount = $this.ChannelCount
# This can be used to compute an offset
$Offset = [Math]::Floor($start * $SampleRate * $ChannelCount)
# Collect our new samples
[double[]]$NewSamples = @(
# If the current sample is larger than the offset
if ($current.Length -ge $Offset) {
$current[0..$Offset] # get the samples until the offset
} else {
# Otherwise, include the current samples
if ($current.Length) {
$current
}
# and pad the remainder of the time until start with silence
$deltaSamples = [Math]::Floor($Offset - $current.Length)
@(0) * $deltaSamples
}
# Add the samples
for ($index = 0; $index -lt $samples.Count; $index++) {
# If we are still within the current timeframe
if ($current.Length -gt ($index + $Offset)) {
# Add samples in at that point
$current[$index + $Offset] - ($samples[$index])
} else {
# Otherwise, simply include the negated new sample
$samples[$index] * -1
}
}
# If we have remaining original samples
if (($index + $offset) -lt $current.Length) {
# they should still be part of the audio and be included
for ($remaining = $index + $Offset; $remaining -lt $current.Length; $remaining++) {
$current[$remaining]
}
}
)
$this.Samples = $NewSamples
return $thisIf you like making waves, please star this repo and consider sponsoring