Skip to content

Commit

Permalink
Add experimental "-a, --a4" option #1
Browse files Browse the repository at this point in the history
  • Loading branch information
jurihock committed Mar 31, 2024
1 parent 36ed838 commit 6d3dddd
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/remucs/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
default=','.join(["1"]*len(STEMS)),
show_default=True,
help=f'Gain of individual stems \"{",".join(sorted(STEMS))}\", e.g. \"2,1,0.5,0\".')
@click.option('-a', '--a4',
default=None,
type=int,
help='Target tuning reference frequency, to automatically estimate the pitch shifting factor (experimental).')
@click.option('-p', '--pitch',
default='0',
show_default=True,
Expand All @@ -57,7 +61,7 @@
VERSION,
'-V', '--version',
message='%(version)s')
def main(files, fine, norm, mono, bala, gain, pitch, data, quiet):
def main(files, fine, norm, mono, bala, gain, a4, pitch, data, quiet):

try:

Expand All @@ -72,6 +76,7 @@ def main(files, fine, norm, mono, bala, gain, pitch, data, quiet):
mono=mono,
bala=bala,
gain=gain,
a4=a4,
pitch=pitch)

for file in list(set(files)):
Expand Down
3 changes: 2 additions & 1 deletion src/remucs/options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass, field
from typing import List
from typing import List, Union


@dataclass
Expand All @@ -14,6 +14,7 @@ class RemucsOptions:
bala: List[float] = field(default_factory=lambda: [0]*4)
gain: List[float] = field(default_factory=lambda: [1]*4)

a4: Union[int, None] = None
pitch: float = 1
quefrency: float = 1e-3

Expand Down
7 changes: 7 additions & 0 deletions src/remucs/remucs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from remucs.options import RemucsOptions
from remucs.analysis import analyze
from remucs.synthesis import synthesize
from remucs.tuning import howto_shift_pitch


def remucs(file: Union[str, PathLike], data: Union[str, PathLike] = '~', opts: Union[RemucsOptions, None] = None):
Expand Down Expand Up @@ -36,4 +37,10 @@ def remucs(file: Union[str, PathLike], data: Union[str, PathLike] = '~', opts: U
dst = file.with_suffix(opts.remucs + file.suffix)

analyze(src, data, opts)

if opts.a4:

file = data / opts.model / ('other' + src.suffix)
opts.pitch = howto_shift_pitch(file, opts)

synthesize(dst, data, opts)
24 changes: 23 additions & 1 deletion src/remucs/tuning.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def analyze(src: Path, opts: RemucsOptions) -> Tuple[NDArray, NDArray]:
x, samplerate = resample(src, samplerate)

reference = 440
bandwidth = (100, 4000)
bandwidth = 100, 4000
resolution = int(1200 / 25)
batchsize = int(1 * samplerate)
numpeaks = 3
Expand Down Expand Up @@ -117,3 +117,25 @@ def analyze(src: Path, opts: RemucsOptions) -> Tuple[NDArray, NDArray]:
assert numpy.all(numpy.isfinite(weights))

return estimates, weights


def howto_shift_pitch(src: Path, opts: RemucsOptions) -> float:

estimates, weights = analyze(src, opts)

values = numpy.round(estimates).astype(int)
bounds = numpy.min(values), numpy.max(values)
bins = numpy.arange(bounds[0], bounds[1] + 1)
edges = numpy.arange(bounds[0], bounds[1] + 2) - 0.5
hist = numpy.histogram(values, bins=edges, weights=weights)

assert hist[0].shape == bins.shape
assert hist[1].shape == edges.shape

a4 = bins[numpy.argmax(hist[0])]
q = opts.a4 / a4

if not opts.quiet:
click.echo(f'Estimated pitch shifting factor {q} (from {a4} Hz to {opts.a4} Hz)')

return q
6 changes: 3 additions & 3 deletions src/sandbox/tuning.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ def main():
cp2, weights = analyze(test, RemucsOptions())

values = np.round(cp2).astype(int)
minmax = np.min(values), np.max(values)
bins = np.arange(minmax[0], minmax[1] + 1)
edges = np.arange(minmax[0], minmax[1] + 2) - 0.5
bounds = np.min(values), np.max(values)
bins = np.arange(bounds[0], bounds[1] + 1)
edges = np.arange(bounds[0], bounds[1] + 2) - 0.5
hist = np.histogram(values, bins=edges, weights=weights)

assert hist[0].shape == bins.shape
Expand Down

0 comments on commit 6d3dddd

Please sign in to comment.