Last active
May 11, 2020 11:54
-
-
Save ngxson/a3690cde1103e27f591160041d4d4e25 to your computer and use it in GitHub Desktop.
Music Transpose.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "Music Transpose.ipynb", | |
"provenance": [], | |
"collapsed_sections": [], | |
"mount_file_id": "https://gist.github.com/ngxson/a3690cde1103e27f591160041d4d4e25#file-music-transpose-ipynb", | |
"authorship_tag": "ABX9TyNTWuOBmHnImTU5eleV+wHN", | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/ngxson/a3690cde1103e27f591160041d4d4e25/music-transpose.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "-FutfdIeJQ-U", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"import wave\n", | |
"import numpy as np" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "UdBJKea2JtfS", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"wr = wave.open('drive/My Drive/ha-noi-mua-vang-nhung-con-mua-trang.wav', 'r')\n", | |
"trans_semitones = 1 # số nửa cung muốn chuyển. Số dương là cao lên, âm là giảm đi" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "MiUhk5XuVFMJ", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# copy thông số file wav này, để phục vụ việc tái tạo file mới\n", | |
"par = list(wr.getparams())\n", | |
"par[3] = 0\n", | |
"par = tuple(par)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "YqF6zrcDVHOB", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# tạo một file wav mới để ghi dữ liệu vào\n", | |
"ww = wave.open('my-song.wav', 'w')\n", | |
"ww.setparams(par)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "zGk29q3BUM5D", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"fractions = 20 # chia 1 giây thành bao nhiêu phần\n", | |
"frame_size = wr.getframerate() // fractions\n", | |
"count_frames = int(wr.getnframes() / frame_size)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "K7x9z1EToLFR", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"def transpose_freq(freq):\n", | |
" new_freq = np.zeros(np.shape(freq)).astype('complex128')\n", | |
" for f in range(len(freq)):\n", | |
" new_f = f * (2 ** (trans_semitones/12)) # tấn số mới = tấn số cũ nhân 2 mũ N/12\n", | |
" new_f = round(new_f)\n", | |
" if (new_f < len(freq)):\n", | |
" new_freq[new_f] = freq[f] # copy dữ liệu ở tần số cũ vào tần số mới\n", | |
" return new_freq" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "K2yd_5osb7aT", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"def process_frame():\n", | |
" # lấy samples của frame này\n", | |
" samples = np.frombuffer(wr.readframes(frame_size), dtype=np.int16)\n", | |
" # phân tích Fast Fourier Transform để cho ra các tần số\n", | |
" freq = np.fft.rfft(samples)\n", | |
" # chuyển giọng bằng các chuyển các tần số\n", | |
" freq = transpose_freq(freq)\n", | |
" # dùng Inverse Fast Fourier Transform để chuyển tần số về samples\n", | |
" new_samples = np.fft.irfft(freq, len(samples))\n", | |
" new_samples = np.rint(new_samples)\n", | |
" new_samples = new_samples.astype('int16')\n", | |
" # ghi samples vào file mới\n", | |
" ww.writeframes(new_samples.tobytes())" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "_2Qx_xLTWNvY", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# lặp lại với tất cả các frame\n", | |
"for i in range(count_frames):\n", | |
" process_frame()" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "Av_EhlsEcLta", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# xong việc, đóng file, đi về nhà\n", | |
"wr.close()\n", | |
"ww.close()" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment