Ejemplo n.º 1
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    print('1 second waveform at 1000Hz')
    frequency_powers = analyze_window(sig_gen.sin_constant(1000))
    print("Frequency Powers found by FFT: ", frequency_powers)

    print('\n0.5 second waveform at 880Hz')
    frequency_powers = analyze_window(sig_gen.sin_constant(880, length=0.5))
    print("Frequency Powers found by FFT: ", frequency_powers)

    print('\n0.75 second waveform at 1234Hz')
    frequency_powers = analyze_window(sig_gen.sin_constant(1234, length=0.75))
    tmp = list(frequency_powers.items())
    tmp.sort(key=lambda x: x[1], reverse=True)
    print('{} present non-zero frequencies in signal. The most '
          'powerfull frequencies are:\n{}'.format(
              len(frequency_powers), '\n'.join([str(t) for t in tmp[:10]])))

    return 0
Ejemplo n.º 2
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.framerate(parser)
    common.ParserArguments.set_defaults(parser, type='constant', length=2.0)
    args = parser.parse_args()
    common.defaults.framerate = args.framerate

    sg = Generator(length=args.length, verbose=args.debug)

    key = Key()
    unison = sg.sin_constant(key.interval(Interval.unison))
    maj_third = sg.sin_constant(key.interval(Interval.major_third))
    min_third = sg.sin_constant(key.interval(Interval.minor_third))
    fifth = sg.sin_constant(key.interval(Interval.fifth))

    powerchord = unison.mix_down(fifth)

    maj_triad = powerchord.mix_down(maj_third)
    min_triad = mix_down(powerchord, min_third)

    with wav_file_context(args.filename) as fout:
        fout.write_frames(powerchord.frames)
        fout.write_frames(maj_triad.frames)
        fout.write_frames(min_triad.frames)

    return 0
Ejemplo n.º 3
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.set_defaults(parser, type='constant')

    default_freqs = [300, 440]
    parser.add_argument(
        '-f', '--frequencies', action='append', dest='freqs', type=float,
        default=[], help="Specify the frequencies to use. Defaults to "
                         "%s." % default_freqs)
    args = parser.parse_args()

    freqs = default_freqs
    if len(args.freqs) > 0:
        freqs = args.freqs

    sg = FFTGenerator(framerate=args.framerate, length=args.length,
                      verbose=args.debug)
    waveform = sg.generate(freqs)

    if args.plot:
        import potty_oh.plot as plot
        plot.plot_waveform(waveform.frames, waveform.channels, 0,
                           len(waveform))
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 4
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.framerate(parser)
    common.ParserArguments.set_defaults(parser, type='constant',
                                        length=2.0)
    args = parser.parse_args()
    common.defaults.framerate = args.framerate

    sg = Generator(length=args.length, verbose=args.debug)

    key = Key()
    unison = sg.sin_constant(key.interval(Interval.unison))
    maj_third = sg.sin_constant(key.interval(Interval.major_third))
    min_third = sg.sin_constant(key.interval(Interval.minor_third))
    fifth = sg.sin_constant(key.interval(Interval.fifth))

    powerchord = unison.mix_down(fifth)

    maj_triad = powerchord.mix_down(maj_third)
    min_triad = mix_down(powerchord, min_third)

    with wav_file_context(args.filename) as fout:
        fout.write_frames(powerchord.frames)
        fout.write_frames(maj_triad.frames)
        fout.write_frames(min_triad.frames)

    return 0
Ejemplo n.º 5
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    print('1 second waveform at 1000Hz')
    frequency_powers = analyze_window(
        sig_gen.sin_constant(1000))
    print("Frequency Powers found by FFT: ", frequency_powers)

    print('\n0.5 second waveform at 880Hz')
    frequency_powers = analyze_window(
        sig_gen.sin_constant(880, length=0.5))
    print("Frequency Powers found by FFT: ", frequency_powers)

    print('\n0.75 second waveform at 1234Hz')
    frequency_powers = analyze_window(
        sig_gen.sin_constant(1234, length=0.75))
    tmp = list(frequency_powers.items())
    tmp.sort(key=lambda x: x[1], reverse=True)
    print('{} present non-zero frequencies in signal. The most '
          'powerfull frequencies are:\n{}'.format(
              len(frequency_powers), '\n'.join([str(t) for t in tmp[:10]])))

    return 0
Ejemplo n.º 6
0
def main():
    ui_map = {'noise': whitenoise, 'constant': sin_constant,
              'linear': sin_linear}

    parser = common.get_cmd_line_parser(description=__doc__)
    parser.add_argument(
        '-t', '--type', help='Type of signal to generate',
        choices=ui_map.keys())
    common.ParserArguments.filename(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.frequency(parser)
    common.ParserArguments.set_defaults(parser, type='constant')
    args = parser.parse_args()

    common.defaults.framerate = 8000

    sg = Generator(length=args.length, framerate=common.defaults.framerate,
                   verbose=args.debug)

    ui_map[args.type](args, sg)
    waveform = sg.waveform

    if args.plot:
        import potty_oh.plot as plot
        plot.plot_waveform(waveform.frames, waveform.channels, 0, 4000)
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 7
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    print('0.2 second waveform at 1000Hz and 0.2 seconds at 440Hz '
          '(starting 0.1 second in)')
    signal = Waveform([])
    signal = signal.insert(0, sig_gen.sin_constant(1000, length=0.2))
    signal = signal.insert(seconds_to_frame(0.1),
                           sig_gen.sin_constant(440, length=0.2))

    if args.plot:
        plot.plot_waveform(signal.frames, 1, 0, 4000)
    else:
        with wav_file_context('signal.wav') as fout:
            fout.write_frames(signal.frames)

    spectrum = analyze_whole_waveform(signal)
    print("Frequency Powers found by STFT: ")
    timeslices = [(time, spec) for time, spec in spectrum.items()]
    timeslices.sort(key=lambda x: x[0])
    for timeslice in timeslices:
        print(timeslice)

    return 0
Ejemplo n.º 8
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    print('0.2 second waveform at 1000Hz and 0.2 seconds at 440Hz '
          '(starting 0.1 second in)')
    signal = Waveform([])
    signal = signal.insert(0, sig_gen.sin_constant(1000, length=0.2))
    signal = signal.insert(seconds_to_frame(0.1),
                           sig_gen.sin_constant(440, length=0.2))

    if args.plot:
        plot.plot_waveform(signal.frames, 1, 0, 4000)
    else:
        with wav_file_context('signal.wav') as fout:
            fout.write_frames(signal.frames)

    spectrum = analyze_whole_waveform(signal)
    print("Frequency Powers found by STFT: ")
    timeslices = [(time, spec) for time, spec in spectrum.items()]
    timeslices.sort(key=lambda x: x[0])
    for timeslice in timeslices:
        print(timeslice)

    return 0
Ejemplo n.º 9
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    ParserArguments.set_defaults(parser)
    ParserArguments.best(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    song = Stream()

    roots = 'ABCDEFG'
    scales = [scale.MajorScale, scale.MinorScale,
              scale.WholeToneScale, scale.ChromaticScale]

    print('Choosing a random scale from Major, Minor, Whole Tone, Chromatic.')
    rscale = random.choice(scales)(Pitch(random.choice(roots)))
    print('Using: %s' % rscale.name)

    print('Generating a score...')
    random_note_count = 50
    random_note_speeds = [0.5, 1]
    print('100 Random 1/8th and 1/4th notes in rapid succession...')
    for i in range(random_note_count):
        note = Note(random.choice(rscale.pitches))
        note.duration.quarterLength = random.choice(random_note_speeds)
        song.append(note)

    scale_practice_count = 4
    print('Do the scale up and down a few times... maybe %s' %
          scale_practice_count)
    rev = rscale.pitches[:]
    rev.reverse()
    updown_scale = rscale.pitches[:]
    updown_scale.extend(rev[1:-1])
    print('updown scale: %s' % updown_scale)
    for count, pitch in enumerate(cycle(updown_scale)):
        print(' note %s, %s' % (count, pitch))
        song.append(Note(pitch))
        if count >= scale_practice_count * len(updown_scale):
            break

    print('Composition finished:')
    song.show('txt')

    if args.best:
        print('Audifying the song to file "{}"...')
        wave = audify_to_file(song, args.tempo, args.filename, verbose=True)
    else:
        wave = audify_basic(song, args.tempo, verbose=True)
        print('Writing Song to file "{}"...'.format(args.filename))
        with wav_file_context(args.filename) as fout:
            fout.write_frames(wave.frames)

    return 0
Ejemplo n.º 10
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser.parse_args()

    work_path = numpy.random.choice(corpus.getComposer('bach'))
    work = corpus.parse(work_path)
    for note in work.flat.notes:
        print('{} [{}]: {} {}'.format(note.offset, note.duration.quarterLength,
                                      note.pitch, note.frequency))
    return 0
Ejemplo n.º 11
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser.parse_args()

    work_path = numpy.random.choice(corpus.getComposer('bach'))
    work = corpus.parse(work_path)
    for note in work.flat.notes:
        print('{} [{}]: {} {}'.format(note.offset, note.duration.quarterLength,
                                      note.pitch, note.frequency))
    return 0
Ejemplo n.º 12
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    ParserArguments.set_defaults(parser)
    ParserArguments.best(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    print('Generating Signal:')
    sig_gen = Generator()
    song = Waveform([])
    qnl = quarter_note_length(args.tempo)

    # work = corpus.parse(numpy.random.choice(corpus.getComposer('bach')))
    work = corpus.parse(numpy.random.choice(corpus.getCorePaths()))
    notes = work.flat.notes
    if args.best:
        audify_to_file(notes, args.tempo, args.filename, args.verbose)
        return 0

    note_count = len(notes)
    try:
        for count, note in enumerate(notes):
            print('{}/{}: {} [{}]: {} {}'.format(count, note_count,
                                                 note.offset,
                                                 note.duration.quarterLength,
                                                 note.pitch,
                                                 note.pitch.frequency))
            note_length = qnl * note.quarterLength
            start = seconds_to_frame(qnl * note.offset)
            print('  inserting {} seconds into frame {}'.format(
                note_length, start))
            song = song.insert(
                start,
                sig_gen.sin_constant(note.pitch.frequency, length=note_length))
    except KeyboardInterrupt:
        print('Stopping song generating here...')

    print('Writing Song {} to file {}...'.format(work.corpusFilepath,
                                                 args.filename))
    with wav_file_context(args.filename) as fout:
        fout.write_frames(song.frames)

    return 0
Ejemplo n.º 13
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    parser.add_argument('-r', '--repo', help='The git repository to use.')
    ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    repo_data = scrape_repository_data(args.repo)
    song = compose_repository_song(repo_data)

    notes = song.flat.notes
    waveform = audify(notes, args.tempo, args.verbose)
    with wav_file_context(args.filename) as fout:
        fout.write_frames(waveform.frames)
    return 0
Ejemplo n.º 14
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.length(parser)
    ParserArguments.modify_argument(parser, 'length', 'help',
                                    'Length per pitch clip.')
    ParserArguments.set_defaults(parser, length=0.75)
    args = parser.parse_args()

    sg = Generator(length=args.length / 2.0, verbose=args.debug)

    with wav_file_context(args.filename) as fout:
        for tone, temperament in itertools.product(range(Interval.max() + 1),
                                                   Temperament.iter()):
            key = Key(temperament=temperament)
            waveform = sg.sin_constant(key.interval(tone))
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 15
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.length(parser)
    ParserArguments.modify_argument(parser, 'length', 'help',
                                    'Length per pitch clip.')
    ParserArguments.set_defaults(parser, length=0.75)
    args = parser.parse_args()

    sg = Generator(length=args.length / 2.0, verbose=args.debug)

    with wav_file_context(args.filename) as fout:
        for tone, temperament in itertools.product(
                range(Interval.max() + 1), Temperament.iter()):
            key = Key(temperament=temperament)
            waveform = sg.sin_constant(key.interval(tone))
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 16
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    print('Generating Signal:')
    work = corpus.parse(numpy.random.choice(corpus.getCorePaths()))
    notes = work.flat.notes
    waveform = audify(notes, args.tempo, args.verbose)

    print('Writing Song {} to file {}...'.format(
        work.corpusFilepath, args.filename))
    with wav_file_context(args.filename) as fout:
        fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 17
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    ParserArguments.set_defaults(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    print('Generating Signal:')
    work = corpus.parse(numpy.random.choice(corpus.getCorePaths()))
    notes = work.flat.notes
    waveform = audify(notes, args.tempo, args.verbose)

    print('Writing Song {} to file {}...'.format(work.corpusFilepath,
                                                 args.filename))
    with wav_file_context(args.filename) as fout:
        fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 18
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.set_defaults(parser, type='constant')

    default_freqs = [300, 800]
    parser.add_argument('-f',
                        '--frequencies',
                        action='append',
                        dest='freqs',
                        type=float,
                        default=[],
                        help="Specify the frequencies to use. Defaults to "
                        "%s." % default_freqs)
    args = parser.parse_args()

    freqs = default_freqs
    if len(args.freqs) > 0:
        freqs = args.freqs

    sg = ContinuousGenerator(framerate=args.framerate,
                             length=args.length,
                             verbose=args.debug)
    for freq in freqs[:-1]:
        sg.generate(freq, args.length)
    sg.generate(freqs[-1], args.length, end=True)
    waveform = sg.waveform

    if args.plot:
        import potty_oh.plot as plot
        plot.plot_waveform(waveform.frames, waveform.channels, 0,
                           len(waveform))
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 19
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    parser.add_argument('--phase',
                        help="Run the experiment with a given phase value.",
                        type=float,
                        default=0.0)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    phase = 0 if not hasattr(args, 'phase') else args.phase
    signal = sig_gen.sin_constant(440, length=0.05, phase=phase % (2 * pi))

    freq, power_domain, freq_domain = do_fft(signal)

    try:
        _, subplots = pyplot.subplots(1, 2)
        subplots[0].plot(power_domain)
        subplots[0].set_title('Power Domain')
        subplots[1].plot(freq_domain)
        subplots[1].set_title('Freq Domain')
        pyplot.show()

        _, subplots = pyplot.subplots(1, 2)
        subplots[0].plot(real(freq_domain))
        subplots[0].set_title('Real Freq. Domain')
        subplots[1].plot(imag(freq_domain))
        subplots[1].set_title('Imaginary Freq. Domain')
        pyplot.show()
    finally:
        pyplot.close()

    return 0
Ejemplo n.º 20
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    parser = ParserArguments.filename(parser)
    parser = ParserArguments.plot(parser)
    parser = ParserArguments.framerate(parser)
    parser = ParserArguments.set_defaults(parser)
    parser.add_argument(
        '--phase', help="Run the experiment with a given phase value.",
        type=float, default=0.0)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    sig_gen = Generator(verbose=args.debug)

    phase = 0 if not hasattr(args, 'phase') else args.phase
    signal = sig_gen.sin_constant(440, length=0.05, phase=phase % (2 * pi))

    freq, power_domain, freq_domain = do_fft(signal)

    try:
        _, subplots = pyplot.subplots(1, 2)
        subplots[0].plot(power_domain)
        subplots[0].set_title('Power Domain')
        subplots[1].plot(freq_domain)
        subplots[1].set_title('Freq Domain')
        pyplot.show()

        _, subplots = pyplot.subplots(1, 2)
        subplots[0].plot(real(freq_domain))
        subplots[0].set_title('Real Freq. Domain')
        subplots[1].plot(imag(freq_domain))
        subplots[1].set_title('Imaginary Freq. Domain')
        pyplot.show()
    finally:
        pyplot.close()

    return 0
Ejemplo n.º 21
0
def main():
    ui_map = {
        'noise': whitenoise,
        'constant': sin_constant,
        'linear': sin_linear
    }

    parser = common.get_cmd_line_parser(description=__doc__)
    parser.add_argument('-t',
                        '--type',
                        help='Type of signal to generate',
                        choices=ui_map.keys())
    common.ParserArguments.filename(parser)
    common.ParserArguments.length(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.frequency(parser)
    common.ParserArguments.set_defaults(parser, type='constant')
    args = parser.parse_args()

    common.defaults.framerate = 8000

    sg = Generator(length=args.length,
                   framerate=common.defaults.framerate,
                   verbose=args.debug)

    ui_map[args.type](args, sg)
    waveform = sg.waveform

    if args.plot:
        import potty_oh.plot as plot
        plot.plot_waveform(waveform.frames, waveform.channels, 0, 4000)
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(waveform.frames)

    return 0
Ejemplo n.º 22
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.set_defaults(parser, type='constant')
    args = parser.parse_args()

    sg = FFTGenerator(framerate=args.framerate, verbose=args.debug)

    if args.plot:
        length = 0.05
    else:
        length = 2.0
    main_freqs = [440.0, 660.0]  # Hz
    harmony_freqs = [550.0]  # Hz (major third)

    main_track = sg.generate(main_freqs, length=length * 3)
    print("440 and 660HZ main track is %s seconds or %s frames" %
          (length * 3, len(main_track)))

    harmony_note = sg.generate(harmony_freqs, length=length)
    print("%sHz Harmony is audible for %s seconds or %s frames" %
          (harmony_freqs, length, len(harmony_note)))

    print("Insert the harmony note at the right place a zeroed track.")
    note_frames = seconds_to_frame(length)
    harmony_track = Waveform(scipy.zeros(len(main_track)))
    for index in range(note_frames, note_frames * 2):
        harmony_track._wavedata[index] = (harmony_note._wavedata[index -
                                                                 note_frames -
                                                                 1])

    preprocessed_harmony_track = Waveform(harmony_track._wavedata.copy())
    for index, frame in enumerate(preprocessed_harmony_track.frames):
        preprocessed_harmony_track._wavedata[index] = 0.5 - (0.5 * frame)

    convolution_data = scipy.convolve(main_track.frames,
                                      preprocessed_harmony_track.frames,
                                      mode="full")
    print("Convolution (including mirrored data) is %s seconds or %s frames" %
          (frame_to_seconds(len(convolution_data),
                            framerate=sg.framerate), len(convolution_data)))

    print("Normalizing Convolution Amplitude")
    convolution = Waveform(
        normalize(convolution_data[:int(len(convolution_data) / 2)]))

    if args.plot:
        _, subplots = pyplot.subplots(4, 1)
        subplots[0].plot(main_track.frames)
        subplots[0].set_title('Main Track 440.0 and 660.0 Hz - Root and Fifth')
        subplots[1].plot(harmony_track.frames)
        subplots[1].set_title('Harmony Major Third (550.0 Hz)')
        subplots[2].plot(preprocessed_harmony_track.frames)
        subplots[2].set_title('Preprocessed Harmony Track')
        subplots[3].plot(convolution.frames)
        subplots[3].set_title('Convolved track of the two waveforms.')
        pyplot.show()
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(convolution.frames)

    return 0
Ejemplo n.º 23
0
def main():
    parser = common.get_cmd_line_parser(description=__doc__)
    common.ParserArguments.filename(parser)
    common.ParserArguments.plot(parser)
    common.ParserArguments.set_defaults(parser, type='constant')
    args = parser.parse_args()

    sg = FFTGenerator(framerate=args.framerate,
                      verbose=args.debug)

    if args.plot:
        length = 0.05
    else:
        length = 2.0
    main_freqs = [440.0, 660.0]  # Hz
    harmony_freqs = [550.0]  # Hz (major third)

    main_track = sg.generate(main_freqs, length=length * 3)
    print("440 and 660HZ main track is %s seconds or %s frames" %
          (length * 3, len(main_track)))

    harmony_note = sg.generate(harmony_freqs, length=length)
    print("%sHz Harmony is audible for %s seconds or %s frames" %
          (harmony_freqs, length, len(harmony_note)))

    print("Insert the harmony note at the right place a zeroed track.")
    note_frames = seconds_to_frame(length)
    harmony_track = Waveform(scipy.zeros(len(main_track)))
    for index in range(note_frames, note_frames * 2):
        harmony_track._wavedata[index] = (
                harmony_note._wavedata[index - note_frames - 1])

    preprocessed_harmony_track = Waveform(harmony_track._wavedata.copy())
    for index, frame in enumerate(preprocessed_harmony_track.frames):
        preprocessed_harmony_track._wavedata[index] = 0.5 - (0.5 * frame)

    convolution_data = scipy.convolve(main_track.frames,
                                      preprocessed_harmony_track.frames,
                                      mode="full")
    print("Convolution (including mirrored data) is %s seconds or %s frames" %
          (frame_to_seconds(len(convolution_data), framerate=sg.framerate),
           len(convolution_data)))

    print("Normalizing Convolution Amplitude")
    convolution = Waveform(normalize(
        convolution_data[:int(len(convolution_data)/2)]))

    if args.plot:
        _, subplots = pyplot.subplots(4, 1)
        subplots[0].plot(main_track.frames)
        subplots[0].set_title('Main Track 440.0 and 660.0 Hz - Root and Fifth')
        subplots[1].plot(harmony_track.frames)
        subplots[1].set_title('Harmony Major Third (550.0 Hz)')
        subplots[2].plot(preprocessed_harmony_track.frames)
        subplots[2].set_title('Preprocessed Harmony Track')
        subplots[3].plot(convolution.frames)
        subplots[3].set_title('Convolved track of the two waveforms.')
        pyplot.show()
    else:
        from potty_oh.wav_file import wav_file_context
        with wav_file_context(args.filename) as fout:
            fout.write_frames(convolution.frames)

    return 0