基于TensorFlow的歌曲曲风变换

背景:

在图像上的风格变换(Style Transfer,论文,基于Torch的代码实现:neural-style)同样可以应用于音频中。
本文采用的是英文TravelingLight.mp3和东风破.mp3作为音频源和参考源。考虑到内存有限,仅仅截取音频中的10s进行风格的变换。

代码:

# -*- coding: utf-8 -*-
__author__ = 'jason'
import tensorflow as tf
import librosa# 用来提取音频文件, 参看<中文语音识别>
import numpy as np
import os
import pdb
#import shlex  # python2 pipes
# 音频文件路径
content_audio = "TravelingLight.mp3"
style_audio = "东风破.mp3"
# 为英文歌曲<Traveling Light>添加周杰伦风味
# 剪辑一段音频, 默认取开头的10s, 太大内存吃不消
def cut_audio(filename, start_pos='00:00:00', lens=10):
    newfile = os.path.splitext(os.path.basename(filename))[0] + '_' + str(lens) + 's.mp3'
    # 确保系统中已安装ffmpeg,这是ffmpeg的命令行方式,更加详细的使用方法可以google
    cmd = "ffmpeg -i {} -ss {} -t {} -acodec copy {}".format(filename, start_pos, lens, newfile)
    os.system(cmd)
    return newfile

#上面的ffmpeg注意-acodec copy参数,否则会报错
content_audio_10s = cut_audio(content_audio, start_pos='00:00:33')
style_audio_10s = cut_audio(style_audio, start_pos='00:00:38')
#content_audio_10s = "TravelingLight_10s.mp3"
#style_audio_10s = "东风破_10s.mp3" 
# Short Time Fourier Transform音频转spectrogram(把1维信号转为2维, 可以被视作图像)
# https://en.wikipedia.org/wiki/Short-time_Fourier_transform
N_FFT = 2048
def read_audio(filename):
    x, fs = librosa.load(filename)
    S = librosa.stft(x, N_FFT)
    p = np.angle(S)
    S = np.log1p(np.abs(S[:,:430]))
    return S, fs
content_data, _ = read_audio(content_audio_10s)
style_data, fs = read_audio(style_audio_10s)
samples_n = content_data.shape[1]  # 430
channels_n = style_data.shape[0]   # 1025
style_data = style_data[:channels_n, :samples_n]
content_data_tf = np.ascontiguousarray(content_data.T[None,None,:,:])
style_data_tf = np.ascontiguousarray(style_data.T[None,None,:,:])
# filter shape "[filter_height, filter_width, in_channels, out_channels]"
N_FILTERS = 4096
std = np.sqrt(2) * np.sqrt(2.0 / ((channels_n + N_FILTERS) * 11))
kernel = np.random.randn(1, 11, channels_n, N_FILTERS)*std
# content and style features
g = tf.Graph()
with g.as_default(), g.device('/cpu:0'), tf.Session() as sess:
    # data shape "[batch, in_height, in_width, in_channels]",
    x = tf.placeholder('float32', [1, 1, samples_n, channels_n], name="x")
    kernel_tf = tf.constant(kernel, name="kernel", dtype='float32')
    conv = tf.nn.conv2d(x, kernel_tf, strides=[1, 1, 1, 1], padding="VALID", name="conv")
    net = tf.nn.relu(conv)
    content_features = net.eval(feed_dict={x: content_data_tf})
    style_features = net.eval(feed_dict={x: style_data_tf})
    features = np.reshape(style_features, (-1, N_FILTERS))
    style_gram = np.matmul(features.T, features) / samples_n
# Optimize
ALPHA= 0.01   # ALPHA越大,content越占主导; 如果ALPHA为0,表示没有content
result = None
with tf.Graph().as_default():
    learning_rate= 0.001
    x = tf.Variable(np.random.randn(1, 1, samples_n, channels_n).astype(np.float32)*learning_rate, name="x")
    kernel_tf = tf.constant(kernel, name="kernel", dtype='float32')
    conv = tf.nn.conv2d(x, kernel_tf, strides=[1, 1, 1, 1], padding="VALID", name="conv")
    net = tf.nn.relu(conv)
    content_loss = ALPHA * 2 * tf.nn.l2_loss(net - content_features)
    style_loss = 0
    _, height, width, number = map(lambda i: i.value, net.get_shape())
    size = height * width * number
    feats = tf.reshape(net, (-1, number))
    gram = tf.matmul(tf.transpose(feats), feats)  / samples_n
    style_loss = 2 * tf.nn.l2_loss(gram - style_gram)
    # loss
    loss = content_loss + style_loss
    opt = tf.contrib.opt.ScipyOptimizerInterface(loss, method='L-BFGS-B', options={'maxiter': 300})
    # Optimization
    init_op = tf.initialize_all_variables()#注意这里的初始化操作
    with tf.Session() as sess:
        #sess.run(tf.global_variables_initializer())#这是原来的初始化操作,会报错
        sess.run(init_op)
        opt.minimize(sess)
        result = x.eval()
# 把spectrogram转回wav音频
audio = np.zeros_like(content_data)
audio[:channels_n,:] = np.exp(result[0,0].T) - 1
p = 2 * np.pi * np.random.random_sample(audio.shape) - np.pi
for i in range(500):
    S = audio * np.exp(1j*p)
    x = librosa.istft(S)
    p = np.angle(librosa.stft(x, N_FFT))
librosa.output.write_wav("output.mp3", x, fs)

结果:

运行后的数据结果下载

### 回答1: 建议你听《My Chemical Romance - Welcome to the Black Parade》、《My Chemical Romance - I Don't Love You》、《Fall Out Boy - I Don't Care》、《The Used - The Taste of Ink》和《The Used - All That I've Got》。 ### 回答2: 1. My Chemical Romance - Welcome to the Black Parade: 这是一首充满情感和能量的歌曲,歌词和旋律都非常引人入胜,能够展示出emo音乐的特点。 2. Dashboard Confessional - Hands Down: 这首歌曲中的歌词表达了情感的纠结和内心世界的不安,旋律深入人心,对于感情失落或迷茫的人来说十分合适。 3. Paramore - Decode: Paramore乐队的歌曲通常都是带有一些emo元素的,这首歌表达了内心的矛盾和对爱情的迷失,同时有着强烈的旋律。 4. Fall Out Boy - Sugar, We're Goin Down: 这是一首经典的emo摇滚歌曲,极富激情和魅力,歌词诠释了青春期的情感起伏和挣扎。 5. Brand New - The Quiet Things That No One Ever Knows: 这首歌诠释了品牌新曲风的独特之处,旋律忧郁而深情,歌词深入人心,能够让人们对自己内心的情感有更深的体会。 这些歌曲都具有典型的emo风格,旋律激情且深入人心,歌词充满情感和内心的矛盾。无论是对于喜欢emo音乐的人来说,还是对于想要了解和感受emo音乐的人来说,这些歌曲都是不错的选择。 ### 回答3: Emo(情绪核)是一种情绪化的音乐流派,通常以其深情的歌词和情感的音乐风格而闻名。以下是几首值得推荐的emo歌曲: 1. "Welcome To The Black Parade" - My Chemical Romance:这首歌曲是My Chemical Romance最著名的作品之一,以其强烈的情绪和史诗般的音乐给人深刻的印象。 2. "I'm Not Okay (I Promise)" - My Chemical Romance:这首歌描述了内心的痛苦和挣扎,是emo音乐的代表之一。 3. "Helena" - My Chemical Romance:这首歌曲表达了对逝去的亲人的思念和痛苦,通过强烈的情感演绎了emo音乐的特点。 4. "The Ghost of You" - My Chemical Romance:这首歌曲描述了失去爱人的深情和痛苦,表达了对逝去的人的无尽怀念。 5. "Savior" - Rise Against:这首歌曲是Rise Against的代表作之一,充满力量的旋律和扣人心弦的歌词体现了emo音乐的特性。 6. "The Diary of Jane" - Breaking Benjamin:这首歌曲描述了内心的挣扎和痛苦,具有强烈的情感表达。 7. "I Miss You" - Blink-182:这首歌曲以其深情的歌词和旋律表达了对失去爱人的思念与难过。 8. "I Write Sins Not Tragedies" - Panic! At The Disco:这首歌曲以其醉人的旋律和戏剧化的歌词展现了emo音乐的独特魅力。 这些歌曲不仅具有浓厚的情绪感,还通过深情动人的歌词和旋律抓住了听众的心弦,让人们能够在其中找到共鸣。无论是以释放情感还是享受音乐,这些歌曲都值得一听。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值