Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
azuwis committed Feb 3, 2021
0 parents commit d4145b8
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build/
/dist/
__pycache__/
129 changes: 129 additions & 0 deletions MakePackage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
function MakeDir {
param($Dir)
if (-not (Test-Path $Dir)) {
mkdir -Path $Dir | Out-Null
}
}

function Registry {
param($Path,$Name,$Value,$Type)
$Json = (ConvertTo-Json $Value)
$command = ""
if (-not (Test-Path $Path)) {
$command = "New-Item `"$Path`" -Force | New-ItemProperty -Name `"$Name`" -PropertyType $Type -Force -Value "
} elseif (-not ((ConvertTo-Json (Get-ItemProperty $Path | Select-Object -ExpandProperty $Name -ErrorAction Ignore)) -eq $Json)) {
$command = "Set-ItemProperty `"$Path`" -Name `"$Name`" -Type $Type -Force -Value "
}
if (-not ($command -eq "")) {
Write-Host "Registry: $Path!$Name -> $Value"
if ($Type -eq "String") {
$command += "`"$Value`""
} else {
$command += "(ConvertFrom-Json `"$Json`")"
}
RunAsAdmin $command
}
}

function RunAsAdmin {
param($Command)
$bytes = [System.Text.Encoding]::Unicode.GetBytes($Command)
$encodedCommand = [Convert]::ToBase64String($bytes)
Start-Process powershell -Verb runAs -ArgumentList "-EncodedCommand $encodedCommand"
}

function UnpackUrl {
param($Url,$File,$UnpackDir,$TestPath)
if (-not $File) {
$File = $Url.Substring($Url.LastIndexOf("/") + 1)
}
$Output = "dist\downloads\$File"
if (-not $TestPath) {
$TestPath = $UnpackDir
}
if (-not (Test-Path "$TestPath")) {
Write-Host "UnpackUrl: $Url -> $UnpackDir"
if (-not (Test-Path $Output)) {
Import-Module BitsTransfer
Start-BitsTransfer -Description "Downloading $File from $Url" -Source $Url -Destination $Output
}
switch ((Get-Item $Output).Extension) {
'.zip' {
$shell = New-Object -com shell.application
$shell.Namespace([IO.Path]::Combine($pwd, $UnpackDir)).CopyHere($shell.Namespace([IO.Path]::Combine($pwd, $Output)).Items())
}
'.exe' {
Start-Process $output -Wait -ArgumentList "-y -o$UnpackDir"
}
}
}
}

# disable bits branchcache https://powershell.org/forums/topic/bits-transfer-with-github/
Registry -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\BITS -Name DisableBranchCache -Value 1 -Type DWord

MakeDir build\
MakeDir dist\downloads\

UnpackUrl -Url https://github.com/winpython/winpython/releases/download/2.3.20200530/Winpython64-3.7.7.1dot.exe `
-UnpackDir build\ -TestPath build\python\
if (-not (Test-Path build\python\)) {
mv build\WPy64-3771\ build\python\
}

$Python="build\python\scripts\python.bat"
$ScriptsDir="build\python\python-3.7.7.amd64\Scripts"
$LibsDir="build\python\python-3.7.7.amd64\Lib\site-packages"

if (-not (Test-Path $LibsDir\torch)) {
& $Python -m pip install torch==1.4.0 -f https://download.pytorch.org/whl/torch_stable.html
}

if (-not (Test-Path $LibsDir\piano_transcription_inference)) {
& $Python -m pip install piano_transcription_inference
}

if (-not (Test-Path $ScriptsDir\pyinstaller.exe)) {
& $Python -m pip install pyinstaller
}

& $Python -m pip freeze | Out-File -encoding UTF8 pip.txt

if (-not (Test-Path build\dist\PianoTrans\)) {
cp PianoTrans.py, PianoTrans.spec build\
& $Python $ScriptsDir\pyinstaller.exe `
--noconfirm `
--distpath build\dist\ `
--workpath build\build\ `
--specpath build\ `
build\PianoTrans.spec
}

MakeDir build\dist\PianoTrans\piano_transcription_inference_data\
UnpackUrl -Url 'https://zenodo.org/record/4034264/files/CRNN_note_F1%3D0.9677_pedal_F1%3D0.9186.pth?download=1' `
-File 'note_F1=0.9677_pedal_F1=0.9186.pth' -TestPath 'dist\downloads\note_F1=0.9677_pedal_F1=0.9186.pth'
if (-not (Test-Path 'build\dist\PianoTrans\piano_transcription_inference_data\note_F1=0.9677_pedal_F1=0.9186.pth')) {
cp dist\downloads\note_F1=0.9677_pedal_F1=0.9186.pth 'build\dist\PianoTrans\piano_transcription_inference_data\note_F1=0.9677_pedal_F1=0.9186.pth'
}

$ffmpeg_version='ffmpeg-n4.3.1-30-g666d2fc6e2-win64-gpl-4.3'
MakeDir build\dist\PianoTrans\ffmpeg\
UnpackUrl -Url https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2021-02-01-12-44/$ffmpeg_version.zip `
-UnpackDir build\ -TestPath build\dist\PianoTrans\ffmpeg\ffmpeg.exe
if (Test-Path build\$ffmpeg_version\) {
mv build\$ffmpeg_version\bin\ffmpeg.exe build\dist\PianoTrans\ffmpeg\
rm -r build\$ffmpeg_version\
}

MakeDir build\dist\PianoTrans\reg\
cp README.md build\dist\PianoTrans\README.txt
cp RightClickMenuRegister.bat, RightClickMenuUnregister.bat build\dist\PianoTrans\
cp RightClickMenuRegister.reg.in, RightClickMenuUnregister.reg build\dist\PianoTrans\reg\

if (-not (Test-Path dist\PianoTrans.zip)) {
Add-Type -assembly "system.io.compression.filesystem"
[IO.Compression.ZipFile]::CreateFromDirectory([IO.Path]::Combine($pwd, "build\dist\"), [IO.Path]::Combine($pwd, "dist\PianoTrans.zip"))
}

Write-Host
Read-Host "Done, press enter to exit"
70 changes: 70 additions & 0 deletions PianoTrans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/python

import argparse
import os
import sys
import time
import torch


class Args:
def __init__(self, **entries):
self.__dict__.update(entries)

def inference(args):
"""Inference template.
Args:
model_type: str
audio_path: str
cuda: bool
"""

from piano_transcription_inference import PianoTranscription, sample_rate, load_audio

# Arugments & parameters
audio_path = args.audio_path
output_midi_path = args.output_midi_path
checkpoint_path = args.checkpoint_path
device = 'cuda' if args.cuda and torch.cuda.is_available() else 'cpu'

# Load audio
(audio, _) = load_audio(audio_path, sr=sample_rate, mono=True)

# Transcriptor
transcriptor = PianoTranscription(device=device, checkpoint_path=checkpoint_path)
"""device: 'cuda' | 'cpu'
checkpoint_path: None for default path, or str for downloaded checkpoint path.
"""

# Transcribe and write out to MIDI file
transcribe_time = time.time()
transcribed_dict = transcriptor.transcribe(audio, output_midi_path)
print('Transcribe time: {:.3f} s'.format(time.time() - transcribe_time))

if __name__ == '__main__':
files = tuple(sys.argv)[1:]

if len(files) == 0:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
files = filedialog.askopenfilenames(filetypes = [('audio files', '*')])
files = root.tk.splitlist(files)

script_dir = os.path.dirname(sys.argv[0])
os.environ['PATH'] += os.pathsep + os.path.abspath(os.path.join(script_dir, 'ffmpeg'))
checkpoint_path = os.path.abspath(os.path.join(script_dir, 'piano_transcription_inference_data', 'note_F1=0.9677_pedal_F1=0.9186.pth'))

for file in files:
args = Args(**{
'audio_path': file,
'output_midi_path': '{}.mid'.format(file),
'cuda': True,
'checkpoint_path': checkpoint_path
})
print('Transcribe {}, please wait...'.format(file))
inference(args)

input("\nPress Enter to exit...")
40 changes: 40 additions & 0 deletions PianoTrans.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

from PyInstaller.utils.hooks import collect_data_files, copy_metadata
datas = collect_data_files('librosa')
hiddenimports = ['sklearn.utils._weight_vector']

a = Analysis(['PianoTrans.py'],
pathex=['build\\'],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='PianoTrans',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='PianoTrans')
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## Simple GUI for ByteDance's Piano Transcription with Pedals

[ByteDance's Piano Transcription][1] is the PyTorch implementation of the
piano transcription system, "High-resolution Piano Transcription with Pedals
by Regressing Onsets and Offsets Times `[1]`".

Using this, we can transcribe piano recordings into MIDI files with pedals.

This is a simple GUI and packaging for Windows.

![screenshot](screenshot.png)

### Requirement

* OS: Windows 7 or later (64-bit)
* Memory: at least 8G

Only Windows 10 is tested.

It works on Linux, mac OS, Windows, but only Windows package is provided
here.

If you use other OS, follow those [install and usage][2] guides instead.

### How to use

1. Download [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019][3] `vc_redist_x64.exe` and install
2. Download and unpack [PianoTrans.zip][4]
3. Close other apps to free memory, need at least 4G free memory
4. Run `PianoTrans.exe` in `PianoTrans` directory
5. Choose audio files, multiple selection is supported
6. Result MIDI files are in the same directory as the audio files

If you want right click menu for audio files, run `RightClickMenuRegister.bat`,
then you can right click an audio file, and choose `Piano Transcribe`.

[1]: https://github.com/bytedance/piano_transcription
[2]: https://github.com/qiuqiangkong/piano_transcription_inference
[3]: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
[4]: https://github.com/azuwis/PianoTrans/releases/download/v0.1/PianoTrans-v0.1.zip

### Changelog

#### [0.1] - 2021-02-02

* Initial release.

## Cite
`[1]` Qiuqiang Kong, Bochen Li, Xuchen Song, Yuan Wan, and Yuxuan Wang. "High-resolution Piano Transcription with Pedals by Regressing Onsets and Offsets Times." arXiv preprint arXiv:2010.01815 (2020). [[pdf]](https://arxiv.org/pdf/2010.01815.pdf)
16 changes: 16 additions & 0 deletions RightClickMenuRegister.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@echo off
echo Register right click menu for audio files.
set dir=%~dp0
for /f "delims=" %%i in ('type "reg\RightClickMenuRegister.reg.in" ^& break ^> "reg\RightClickMenuRegister.reg" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
>>"reg\RightClickMenuRegister.reg" echo(!line:@REPLACE@=%dir:\=\\%!
endlocal
)
regedit /S "%~dp0reg\RightClickMenuRegister.reg"
echo Done.
IF %0 == "%~0" (
echo Press any key to exit...
pause >nul
)

8 changes: 8 additions & 0 deletions RightClickMenuRegister.reg.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\PianoTrans]
@="Piano Transcribe"
"AppliesTo"=".flac OR .m4a OR .mp3 OR .mp4 OR .wav"

[HKEY_CLASSES_ROOT\*\shell\PianoTrans\command]
@="\"@[email protected]\" \"%1\""
9 changes: 9 additions & 0 deletions RightClickMenuUnregister.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@echo off
echo Unregister right click menu for audio files.
regedit /S "%~dp0reg\RightClickMenuUnregister.reg"
echo Done.
IF %0 == "%~0" (
echo Press any key to exit...
pause >nul
)

5 changes: 5 additions & 0 deletions RightClickMenuUnregister.reg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Windows Registry Editor Version 5.00

[-HKEY_CLASSES_ROOT\*\shell\PianoTrans\command]

[-HKEY_CLASSES_ROOT\*\shell\PianoTrans]
44 changes: 44 additions & 0 deletions pip.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
altgraph==0.17
appdirs==1.4.4
audioread==2.1.9
certifi==2020.12.5
cffi==1.14.4
chardet==4.0.0
cycler==0.10.0
decorator==4.4.2
future==0.18.2
idna==2.10
importlib-metadata==3.4.0
joblib==1.0.0
kiwisolver==1.3.1
librosa==0.8.0
llvmlite==0.35.0
matplotlib==3.3.4
mido==1.2.9
numba==0.52.0
numpy==1.20.0
packaging==20.9
pefile==2019.4.18
piano-transcription-inference==0.0.4
Pillow==8.1.0
pooch==1.3.0
pycparser==2.20
pyinstaller==4.2
pyinstaller-hooks-contrib==2020.11
pyparsing==2.4.7
python-dateutil==2.8.1
pywin32-ctypes==0.2.0
requests==2.25.1
resampy==0.2.2
scikit-learn==0.24.1
scipy==1.6.0
six==1.15.0
SoundFile==0.10.3.post1
sqlite-bro==0.9.1
threadpoolctl==2.1.0
torch==1.4.0+cu92
torchlibrosa==0.0.7
typing-extensions==3.7.4.3
urllib3==1.26.3
winpython==2.4.20200425
zipp==3.4.0
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d4145b8

Please sign in to comment.