diff options
author | Navan Chauhan <navanchauhan@gmail.com> | 2020-07-07 20:27:58 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-07 20:27:58 +0530 |
commit | 4edd4d1bd27180dbe8179b08c2f5e2930bd0d440 (patch) | |
tree | 1157294180ebe84486750fa39c54fa1a26023417 /src/VaporSong.py | |
parent | 6624f8fb1aa7cf4d67c8b5256158515c06f55686 (diff) | |
parent | 52694cd7ad9bbd5c514de448d46ac3c7ef0aef9e (diff) |
Merge pull request #5 from navanchauhan/deepsource-transform-8bc97824
Format code with Black
Diffstat (limited to 'src/VaporSong.py')
-rw-r--r-- | src/VaporSong.py | 342 |
1 files changed, 173 insertions, 169 deletions
diff --git a/src/VaporSong.py b/src/VaporSong.py index d2f2020..3531db7 100644 --- a/src/VaporSong.py +++ b/src/VaporSong.py @@ -11,174 +11,178 @@ from logzero import setup_logger CONFIDENCE_THRESH = 0.02 + class VaporSong: - # Slows down Track - - def slow_down(src, rate, dest): - cmd = "sox -G -D " + src + " " + dest + " speed " + str(rate) - os.system(cmd) - return dest - - # Adds Reverb - - def reverbize(src, dest): - cmd = "sox -G -D " + src + " " + dest + " reverb 100 fade 5 -0 7" # idk what this does tbh, https://stackoverflow.com/a/57767238/8386344 - os.system(cmd) - return dest - - - # Crops "src" from "start" plus "start + dur" and return it in "dest" - def crop(src,dest,start,dur): - cmd = "sox " + src + " " + dest + " trim " + " " + str(start) + " " + str(dur) - os.system(cmd) - - - # Randomly crops a part of the song of at most max_sec_len. - def random_crop(src, max_sec_len, dest): - out = subprocess.check_output(["soxi","-D",src]).rstrip() - f_len = int(float(out)) - if (f_len <= max_sec_len): - os.system("cp " + src + " " + dest) - return - else: - start_region = f_len - max_sec_len - start = randint(0,start_region) - VaporSong.crop(src,dest,start,max_sec_len) - - - # Given a file, returns a list of [beats, confidence], executable based on audibo's test-beattracking.c - # TODO: Move away from executable and use aubio's Python module - def fetchbeats(src): - beat_matrix = [] - if platform == 'darwin': - beats = subprocess.check_output(["noah", "get-beats",src]).rstrip() - else: - beats = subprocess.check_output(["./get-beats",src]).rstrip() - beats_ary = beats.splitlines() - for i in beats_ary: - record = i.split() - record[0] = float(record[0])/1000.0 - record[1] = float(record[1]) - beat_matrix.append(record) - return beat_matrix - - # Splits an audio file into beats according to beat_matrix list - - def split_beat(src,beat_matrix): - split_files = [] - for i in range(0,len(beat_matrix)-1): - - if(beat_matrix[i][1] > CONFIDENCE_THRESH): - dur = (beat_matrix[i+1][0] - beat_matrix[i][0]) - out = src.split(".")[0]+str(i)+".wav" - VaporSong.crop(src,out,beat_matrix[i][0],dur) - split_files.append(out) - return split_files - - # Combines a list of sections - - def combine(sections,dest): - tocomb = [] - tocomb.append("sox") - tocomb.append("-G") - for section in sections: - for sample in section: - tocomb.append(sample) - tocomb.append(dest) - tmpFileLimit = len(tocomb) + 256 # in case the program messes up, it does not actually frick up your system - n = str(tmpFileLimit) - #logger.info("Setting file limit to ", n) - os.system("ulimit -n " + n) - subprocess.check_output(tocomb) - return dest - - # Arbitrarily groups beats into lists of 4, 6, 8, or 9, perfect for looping. - - def generate_sections(ary): - sections = [] - beats = [4,6,8,9] - index = 0 - while(index != len(ary)): - current_beat = beats[randint(0,len(beats)-1)] - new_section = [] - while((current_beat != 0) and (index != len(ary))): - new_section.append(ary[index]) - current_beat -= 1 - index += 1 - sections.append(new_section) - return sections - - - # given a list of sections, selects some of them and duplicates them, perfect for that vaporwave looping effect - def dup_sections(sections): - new_section = [] - for section in sections: - new_section.append(section) - if(randint(0,1) == 0): - new_section.append(section) - return new_section - - # a passage is a list of sections. This takes some sections and groups them into passages. - - def make_passages(sections): - passages = [] - index = 0 - while(index != len(sections)): - passage_len = randint(1,4) - passage = [] - while(index != len(sections) and passage_len > 0): - passage.append(sections[index]) - index += 1 - passage_len -= 1 - passages.append(passage) - return passages - - # Given all of our passages, picks some of them and inserts them into a list some number of times. - - def reorder_passages(passages): - new_passages = [] - passage_count = randint(5,12) - while(passage_count != 0): - passage = passages[randint(0,len(passages)-1)] - passage_count -= 1 - dup = randint(1,4) - while(dup != 0): - dup -= 1 - new_passages.append(passage) - return new_passages - - # converts a list of passages to a list of sections. - - def flatten(passages): - sections = [] - for passage in passages: - for section in passage: - sections.append(section) - return sections - - # It's all coming together - - def vaporize_song(fname, title): - logger.info("Slowing down the music") - VaporSong.slow_down(fname, 0.7, "beats/out.wav") - #logger.info("Cropping") - #VaporSong.random_crop("beats/out.wav",150,"beats/outcrop.wav") - logger.info("Doing Beat Analysis") - bm = VaporSong.fetchbeats("beats/out.wav") - logger.info("Split into beats") - splitd = VaporSong.split_beat("beats/out.wav",bm) - #group beats to sections - logger.info("Divide into sections") - sections = VaporSong.generate_sections(splitd) - logger.info("Duping Sections") - sdup = VaporSong.dup_sections(sections) - # group sections into passages - paslist = VaporSong.make_passages(sdup) - # reorder packages - pasloop = VaporSong.reorder_passages(paslist) - sectionflat = VaporSong.flatten(pasloop) - logger.info("Mastering & Reverbing") - VaporSong.combine(sectionflat,"beats/out_norev.wav") - VaporSong.reverbize("beats/out_norev.wav","./" + (re.sub(r"\W+|_", " ", title)).replace(" ","_") + ".wav") - logger.info("Generated V A P O R W A V E") + # Slows down Track + + def slow_down(src, rate, dest): + cmd = "sox -G -D " + src + " " + dest + " speed " + str(rate) + os.system(cmd) + return dest + + # Adds Reverb + + def reverbize(src, dest): + cmd = ( + "sox -G -D " + src + " " + dest + " reverb 100 fade 5 -0 7" + ) # idk what this does tbh, https://stackoverflow.com/a/57767238/8386344 + os.system(cmd) + return dest + + # Crops "src" from "start" plus "start + dur" and return it in "dest" + def crop(src, dest, start, dur): + cmd = "sox " + src + " " + dest + " trim " + " " + str(start) + " " + str(dur) + os.system(cmd) + + # Randomly crops a part of the song of at most max_sec_len. + def random_crop(src, max_sec_len, dest): + out = subprocess.check_output(["soxi", "-D", src]).rstrip() + f_len = int(float(out)) + if f_len <= max_sec_len: + os.system("cp " + src + " " + dest) + return + else: + start_region = f_len - max_sec_len + start = randint(0, start_region) + VaporSong.crop(src, dest, start, max_sec_len) + + # Given a file, returns a list of [beats, confidence], executable based on audibo's test-beattracking.c + # TODO: Move away from executable and use aubio's Python module + def fetchbeats(src): + beat_matrix = [] + if platform == "darwin": + beats = subprocess.check_output(["noah", "get-beats", src]).rstrip() + else: + beats = subprocess.check_output(["./get-beats", src]).rstrip() + beats_ary = beats.splitlines() + for i in beats_ary: + record = i.split() + record[0] = float(record[0]) / 1000.0 + record[1] = float(record[1]) + beat_matrix.append(record) + return beat_matrix + + # Splits an audio file into beats according to beat_matrix list + + def split_beat(src, beat_matrix): + split_files = [] + for i in range(0, len(beat_matrix) - 1): + + if beat_matrix[i][1] > CONFIDENCE_THRESH: + dur = beat_matrix[i + 1][0] - beat_matrix[i][0] + out = src.split(".")[0] + str(i) + ".wav" + VaporSong.crop(src, out, beat_matrix[i][0], dur) + split_files.append(out) + return split_files + + # Combines a list of sections + + def combine(sections, dest): + tocomb = [] + tocomb.append("sox") + tocomb.append("-G") + for section in sections: + for sample in section: + tocomb.append(sample) + tocomb.append(dest) + tmpFileLimit = ( + len(tocomb) + 256 + ) # in case the program messes up, it does not actually frick up your system + n = str(tmpFileLimit) + # logger.info("Setting file limit to ", n) + os.system("ulimit -n " + n) + subprocess.check_output(tocomb) + return dest + + # Arbitrarily groups beats into lists of 4, 6, 8, or 9, perfect for looping. + + def generate_sections(ary): + sections = [] + beats = [4, 6, 8, 9] + index = 0 + while index != len(ary): + current_beat = beats[randint(0, len(beats) - 1)] + new_section = [] + while (current_beat != 0) and (index != len(ary)): + new_section.append(ary[index]) + current_beat -= 1 + index += 1 + sections.append(new_section) + return sections + + # given a list of sections, selects some of them and duplicates them, perfect for that vaporwave looping effect + def dup_sections(sections): + new_section = [] + for section in sections: + new_section.append(section) + if randint(0, 1) == 0: + new_section.append(section) + return new_section + + # a passage is a list of sections. This takes some sections and groups them into passages. + + def make_passages(sections): + passages = [] + index = 0 + while index != len(sections): + passage_len = randint(1, 4) + passage = [] + while index != len(sections) and passage_len > 0: + passage.append(sections[index]) + index += 1 + passage_len -= 1 + passages.append(passage) + return passages + + # Given all of our passages, picks some of them and inserts them into a list some number of times. + + def reorder_passages(passages): + new_passages = [] + passage_count = randint(5, 12) + while passage_count != 0: + passage = passages[randint(0, len(passages) - 1)] + passage_count -= 1 + dup = randint(1, 4) + while dup != 0: + dup -= 1 + new_passages.append(passage) + return new_passages + + # converts a list of passages to a list of sections. + + def flatten(passages): + sections = [] + for passage in passages: + for section in passage: + sections.append(section) + return sections + + # It's all coming together + + def vaporize_song(fname, title): + logger.info("Slowing down the music") + VaporSong.slow_down(fname, 0.7, "beats/out.wav") + # logger.info("Cropping") + # VaporSong.random_crop("beats/out.wav",150,"beats/outcrop.wav") + logger.info("Doing Beat Analysis") + bm = VaporSong.fetchbeats("beats/out.wav") + logger.info("Split into beats") + splitd = VaporSong.split_beat("beats/out.wav", bm) + # group beats to sections + logger.info("Divide into sections") + sections = VaporSong.generate_sections(splitd) + logger.info("Duping Sections") + sdup = VaporSong.dup_sections(sections) + # group sections into passages + paslist = VaporSong.make_passages(sdup) + # reorder packages + pasloop = VaporSong.reorder_passages(paslist) + sectionflat = VaporSong.flatten(pasloop) + logger.info("Mastering & Reverbing") + VaporSong.combine(sectionflat, "beats/out_norev.wav") + VaporSong.reverbize( + "beats/out_norev.wav", + "./" + (re.sub(r"\W+|_", " ", title)).replace(" ", "_") + ".wav", + ) + logger.info("Generated V A P O R W A V E") |