Example #1
0
def worker(_):
    sig = np.random.standard_normal(44100 * 8)

    effect = AudioEffectsChain()
    effect = effect.pitch(np.random.uniform(-300, 300))
    effect = effect.tempo(np.random.uniform(0.8, 1.2))
    effect = effect.reverb(np.random.uniform(0, 100))

    return effect(sig)
Example #2
0
    def __call__(self, input):
        effect = AudioEffectsChain()

        if np.random.uniform() > 0.5:
            effect = effect.pitch(np.random.uniform(-300, 300))
        if np.random.uniform() > 0.5:
            effect = effect.tempo(np.random.uniform(0.8, 1.2))
        if np.random.uniform() > 0.5:
            effect = effect.reverb(np.random.uniform(0, 100))
        # if np.random.uniform() > 0.5:
        #     effect = effect.overdrive(np.random.uniform(0, 10))
        # if np.random.uniform() > 0.5:
        #     effect = effect.limiter(np.random.uniform(-10, 10))
        # if np.random.uniform() > 0.5:
        #     effect = effect.lowshelf()
        # if np.random.uniform() > 0.5:
        #     effect = effect.highshelf()

        return effect(input)
Example #3
0
    def __call__(self, wav_file):
        if not Path(wav_file).exists():
            print(wav_file)
            raise IOError

        sr, wav = scipy.io.wavfile.read(wav_file)
        if wav.ndim > 1 and wav.shape[1] > 1:
            logger.error("wav file has two or more channels")
            sys.exit(1)
        if type(wav[0]) is np.int32:
            wav = wav.astype('float32', copy=False) / 2147483648.0
        elif type(wav[0]) is np.int16:
            wav = wav.astype('float32', copy=False) / 32768.0
        elif type(wav[0]) is np.uint8:
            wav = wav.astype('float32', copy=False) / 256.0 - 128.0

        fx = AudioEffectsChain()

        if self.resample:
            if self.sample_rate > sr:
                ratio = int(self.sample_rate / sr)
                fx.upsample(ratio)
            elif self.sample_rate < sr:
                ratio = int(sr / self.sample_rate)
                fx.custom(f"downsample {ratio}")

        if self.tempo:
            tempo_change = np.random.uniform(*self.tempo_range)
            fx.tempo(tempo_change, opt_flag="s")

        if self.pitch:
            pitch_change = np.random.uniform(*self.pitch_range)
            fx.pitch(pitch_change)

        # dithering
        fx.custom(f"dither -s")

        wav = fx(wav, sample_in=sr, sample_out=self.sample_rate)
        #wav = wav / max(abs(wav))

        # normalize audio power
        gain = 0.1
        wav_energy = np.sqrt(np.sum(np.power(wav, 2)) / wav.size)
        wav = gain * wav / wav_energy

        # sample-domain padding
        if self.padding:
            wav = np.pad(wav, self.num_padding, mode='constant')

        # sample-domain offset
        if self.offset:
            offset = np.random.randint(*self.offset_range)
            wav = np.roll(wav, offset, axis=0)

        if self.noise:
            snr = 10.0**(np.random.uniform(*self.noise_range) / 10.0)
            noise = np.random.normal(0, 1, wav.shape)
            noise_energy = np.sqrt(np.sum(np.power(noise, 2)) / noise.size)
            wav = wav + snr * gain * noise / noise_energy

        #filename = wav_file.replace(".wav", "_augmented.wav")
        #scipy.io.wavfile.write(filename, self.sample_rate, wav)
        return torch.FloatTensor(wav)
Example #4
0
def main():
    # Parsing for command line arguments
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=
        ("Creates a vaporwave (slowed, with reverb) remix of a given MP3 file, with"
         " multiple audio effects available, and the option of playing over a looped"
         " GIF as a video."),
    )

    parser.add_argument(
        "-o",
        "--output",
        dest="output_name",
        help=
        ("Name of output file(s), instead of audio file name with the addition of"
         " '_vaporised'."),
        type=str,
    )

    required_arguments = parser.add_argument_group("required arguments")

    required_arguments.add_argument(
        "-a",
        "--audio",
        dest="audio_input",
        help="Input audio file to vaporise (.mp3)",
        type=str,
        required=True,
    )

    audio_arguments = parser.add_argument_group(
        "audio arguments",
        "these arguments control audio effects that will be applied by default",
    )

    audio_arguments.add_argument(
        "-s",
        "--speed",
        dest="speed_ratio",
        help="Ratio of new playback speed to old speed.",
        type=float,
        default=0.75,
    )

    audio_arguments.add_argument(
        "-p",
        "--pitch",
        dest="pitch_shift",
        help="Pitch shift (100ths of a semitone).",
        type=float,
        default=-75,
    )

    audio_arguments.add_argument(
        "-l",
        "--lowpass",
        dest="lowpass_cutoff",
        help="Cutoff for lowpass filter (Hz).",
        type=int,
        default=3500,
    )

    audio_arguments_optional = parser.add_argument_group(
        "extra audio arguments",
        "these arguments control extra, optional audio effects")

    audio_arguments_optional.add_argument(
        "-b",
        "--bass",
        dest="bass_boost",
        help="Add a bass boost effect (e.g. --bass 3).",
        type=int,
        default=None,
    )

    audio_arguments_optional.add_argument(
        "-ga",
        "--gain",
        dest="gain_db",
        help="Applies gain (dB).",
        type=int,
        default=None,
    )

    audio_arguments_optional.add_argument(
        "-op",
        "--oops",
        dest="oops",
        help=
        ("Applies Out Of Phase Stereo effect. This is sometimes known as the"
         " ‘karaoke’ effect as it often has the effect of removing most or all of"
         " the vocals from a recording."),
        action="store_true",
    )

    audio_arguments_optional.add_argument(
        "-ph",
        "--phaser",
        dest="phaser",
        help="Enable phaser effect.",
        action="store_true",
    )

    audio_arguments_optional.add_argument(
        "-tr",
        "--tremolo",
        dest="tremolo",
        help="Enable tremolo effect.",
        action="store_true",
    )

    audio_arguments_optional.add_argument(
        "-co",
        "--compand",
        dest="compand",
        help="Enable compand, which compresses the dynamic range of the audio.",
        action="store_true",
    )

    video_arguments = parser.add_argument_group(
        "video arguments",
        "optional arguments, result in an MP4 video output in addition to the MP3"
        " audio",
    )

    video_arguments.add_argument(
        "-g",
        "--gif",
        dest="gif_file",
        help=
        ("Input GIF file to loop. Without a GIF, only an MP3 is created. With a GIF,"
         " an MP4 video is also created."),
        type=str,
    )

    video_arguments.add_argument(
        "-sb",
        "--sobel",
        dest="sobel_filter",
        help="Applies a Sobel filter to video output.",
        action="store_true",
    )

    args = parser.parse_args()

    # Setting name of output file
    if args.output_name is None:
        # If no output name is given, add "_vaporised" to input audio file name
        audio_input_string = re.sub(".mp3", "", str(args.audio_input))
        audio_output = audio_input_string + "_vaporised.mp3"
        video_output = audio_input_string + "_vaporised.mp4"
    else:
        # Otherwise, use the output file name given via the command line
        output_string = re.sub(".mp3", "", str(args.output_name))
        output_string = re.sub(".mp4", "", str(output_string))
        audio_output = output_string + ".mp3"
        video_output = output_string + ".mp4"
        if args.audio_input == args.output_name:
            print("ERROR: Input and output name are identical")
            sys.exit()

    # Creating an audio effects chain, beginning with...
    if args.bass_boost:
        # ...bass boost effect
        bass_boost = f'{"bass "}{args.bass_boost}'
        fx = AudioEffectsChain().custom(bass_boost)
        fx = fx.pitch(args.pitch_shift)
    else:
        # ...pitch shift
        fx = AudioEffectsChain().pitch(args.pitch_shift)

    # Adding OOPS to audio effects chain
    if args.oops:
        fx = fx.custom("oops")

    # Adding tremolo effect to the audio effects chain
    if args.tremolo:
        fx = fx.tremolo(freq=500, depth=50)

    # Adding phaser to the audio effects chain
    if args.phaser:
        # fx.phaser(gain_in, gain_out, delay, decay, speed)
        fx = fx.phaser(0.9, 0.8, 2, 0.2, 0.5)

    # Adding gain to the audio effects chain
    if args.gain_db is not None:
        fx = fx.gain(db=args.gain_db)

    # Adding compand to the audio effects chain
    if args.compand:
        fx = fx.compand()

    # Adding reverb, lowpass filter, speed alteration to audio effects chain
    fx = fx.speed(args.speed_ratio).lowpass(args.lowpass_cutoff).reverb()

    # Applying audio effects
    fx(args.audio_input, audio_output)

    def apply_sobel(image):
        # returns image with Sobel filter applied
        return sobel(image.astype(float))

    # Create video if a GIF file is provided
    if args.gif_file is None:
        # If no GIF is provided, exit here
        print("Script finished at",
              datetime.datetime.now().strftime("%H:%M:%S"))
        print("Vaporised MP3 file (audio):", audio_output)
        sys.exit()
    else:
        # If a GIF is provided, loop it for the length of the vaporised audio file
        mp3_movedit = movedit.AudioFileClip(audio_output)
        gif_movedit = movedit.VideoFileClip(args.gif_file)
        number_of_loops = float(mp3_movedit.duration / gif_movedit.duration)
        gif_looped = gif_movedit.loop(number_of_loops)
        # Applies Sobel filter to looped GIF, if --sobel is used
        if args.sobel_filter:
            gif_looped = gif_looped.fl_image(apply_sobel)
        gif_looped_with_audio = gif_looped.set_audio(mp3_movedit)
        gif_looped_with_audio.write_videofile(video_output)
        print("Script finished at",
              datetime.datetime.now().strftime("%H:%M:%S"))
        print("Vaporised MP3 file (audio):", audio_output)
        print("Vaporised MP4 file (video):", video_output)