I have this nice code in python, that takes file in 1A.wav , and makes 83 note files from 1A to 7G#. 1A is the lowest note Every note file, gets converted to .ogg 48000hz with 80kbps and mono instead of stereo for further use. The problem is that, every next note file, gets less lengthy. For example, if original came in 20 seconds,then by 7G#, the note file might not even be a second long. I need to make sure every file that gets generated stay's the same length as original 1A.wav.
here's the code
#!/usr/bin/env python
from pydub import AudioSegment
from pydub.playback import play
import wave, struct, math, random
import os
# sound = AudioSegment.from_file('in.wav', format="wav")
list_of_values = ["1A", "1A#", "1B","1C","1C#","1D","1D#","1E","1F","1F#","1G","1G#","2A","2A#","2B","2C","2C#","2D","2D#","2E","2F","2F#","2G","2G#","3A","3A#","3B","3C","3C#","3D","3D#",
"3E","3F","3F#","3G","3G#","4A","4A#","4B","4C","4C#","4D","4D#","4E","4F","4F#","4G","4G#","5A","5A#","5B","5C","5C#","5D","5D#","5E","5F","5F#","5G","5G#","6A","6A#","6B","6C","6C#","6D",
"6D#","6E","6F","6F#","6G","6G#","7A","7A#","7C","7C#","7D","7D#","7E","7F","7F#","7G","7G#"]
for prev, current, nxt in zip(list_of_values, list_of_values[1:], list_of_values[2:]):
print(prev, current, nxt)
sound = AudioSegment.from_file(prev + '.wav', format="wav")
octaves = 0.04
new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))
hipitch_sound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})
hipitch_sound = hipitch_sound.set_frame_rate(44100)
# play(hipitch_sound)
hipitch_sound.export(current + ".wav", format="wav")
sound = AudioSegment.from_file('7G.wav', format="wav")
octaves = 0.03
new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))
hipitch_sound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})
hipitch_sound = hipitch_sound.set_frame_rate(44100)
#play(hipitch_sound)
hipitch_sound.export("7G#.wav", format="wav")
path = './7G#.wav'
check_file = os.path.isfile(path)
#converts all files to .ogg with 48000hz 80kbps mono and deletes .wav files after
if check_file:
os.system('for i in *.wav; do ffmpeg -i "$i" -ar 48000 -b:a 80k -ac 1 "${i%.*}.ogg"; done')
os.system('rm *.wav')
Anyway, I have alternative script called generate_missing_keys.py that might do something like this, but I don't understand how to use it, somebody might understand it?
#!/usr/bin/env python
# source waveforms used:
# https://archive.org/download/SalamanderGrandPianoV3
# file: SalamanderGrandPianoV3_OggVorbis.tar.bz2
# Audio files belong to: Alexander Holm
# Wavforms (input and output) follows license CC BY 3.0
# License of this code: MIT License
# This script generates the missing keys
# (only 4 are provided per octave, others have to be generated)
import os
import subprocess
import shlex
VEL = 7
SRC = 'ogg'
DST = 'piano'
def shell(cmd):
print('CMD:', cmd)
subprocess.check_call(shlex.split(cmd.strip()))
def getResKeyRemap():
keys = 'C C# D D# E F F# G G# A A# B'.split()
allowed = 'C D# F# A'.split()
octmin = 1
octmax = 7
okseq = [ (oc, k) for oc in range(octmin, octmax+1) for k in keys ]
resmap = {}
for idx, (oc, k) in enumerate(okseq):
if k not in allowed:
continue
prv = None
nxt = None
if idx > 0:
prv = okseq[idx-1]
if idx < len(okseq) - 1:
nxt = okseq[idx+1]
resmap[(oc, k)] = ((-1, prv), (1, nxt))
return resmap
def writeMappedTone(base, mapped, shift=0):
jump = ''
if shift != 0:
jump = f'pitch {100*shift:+d}'
o1, k1 = base
o2, k2 = mapped
shell(f'''
sox {SRC}/{k1}{o1}v{VEL}.ogg
-r48k -c1
{DST}/{o2}{k2}.ogg {jump}
''')
def processAllKeys(resmap):
for key, val in resmap.items():
print('--' * 40)
writeMappedTone(key, key)
for shift, mapped in val:
if mapped is None:
continue
writeMappedTone(key, mapped, shift)
def resampleWavs():
resmap = getResKeyRemap()
processAllKeys(resmap)
def main():
resampleWavs()
if __name__ == '__main__':
main()
after some time of thinking I came up with these:
here's what should be done, since stretching the pitched file would make the note lower again, what I need to be done is to ether cut the higher note in fraction of lost length and add it to end of the higher note.. since sample could be unusual and not just straight sound, this would cause crippling of the sample...
so technically I should do is take the fourier transform and double the frequency there, then back to time domain to get the wave
if anybody knows how to do it in code, please help with some code sample!!