File size: 2,222 Bytes
06af375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import soundfile as sf
import numpy as np
from scipy import signal
from pydub import AudioSegment
import subprocess
import os

# ref. Hirst The analysis by synthesis of speech melody: from data to models


# reaper requires wav file path input,
#  not audio data itself.
# reaper does NOT require 16khz mono audio.
def reaper_soundfile(sound_path, orig_filetype):
    
    aud_data = AudioSegment.from_file(sound_path, orig_filetype)
    curdir = subprocess.run(["pwd"], capture_output=True, text=True)
    curdir = curdir.stdout.splitlines()[0]
    fname = sound_path.split('/')[-1].replace(orig_filetype,'')
    tmp_path = f'{curdir}/REAPER_TMP/{fname}_tmp.wav'
    if not os.path.exists(f'{curdir}/REAPER_TMP'):
        os.mkdir(f'{curdir}/REAPER_TMP')
    aud_data.export(tmp_path, format="wav")
    wav_path = tmp_path
        
    return wav_path



def get_reaper(wav_path, maxf0='700', minf0='50', reaper_path = "REAPER/build/reaper"):
    
    f0_data = subprocess.run([reaper_path, "-i", wav_path, '-f', '/dev/stdout', '-x', maxf0, '-m', minf0, '-a'],capture_output=True).stdout
    #print('PLAIN:',f0_data)
    f0_data = f0_data.decode()
    #print('DECODE-PITCH:',f0_data)
    f0_data = f0_data.split('EST_Header_End\n')[1].splitlines()
    #print(f0_data) 
    f0_data = [l.split(' ') for l in f0_data] 
    f0_data = [l for l in f0_data if len(l) == 3] # the last line or 2 lines are other info, different format
    f0_data = [ [float(t), float(f)] for t,v,f in f0_data if v=='1']

    return f0_data
    


# 2 pass pitch estimation
def estimate_pitch(sound_path):

    orig_ftype = sound_path.split('.')[-1]
    if orig_ftype == '.wav':
        wav_path = sound_path
    else:
        tmp_path = reaper_soundfile(sound_path)
        wav_path = tmp_path

    print('REAPER FILE PATH:', wav_path)

    first_pass = get_reaper(wav_path)
    first_pass = [f for t,f in first_pass]
    
    q1 = np.quantile(first_pass,0.25)
    q3 = np.quantile(first_pass,0.75)
    
    pfloor = 0.75 * q1
    pceil = 1.5 * q3

    second_pass = get_reaper(wav_path,maxf0 = str(round(pceil)), minf0 = str(round(pfloor)))


    if orig_ftype != '.wav':
        subprocess.run(["rm", tmp_path])
        
    return second_pass