Erstellen Sie mit python3 eine WAV-Datei aus dem GLSL-Shader

Ich habe mit Music Shader experimentiert, aber es wird schwieriger, mit WebGL zu entwickeln, weil es nicht funktioniert. Also habe ich ein Skript erstellt, um eine WAV-Datei aus dem GLSL-Shader mit Python zu erstellen. Ich denke, es wird einfacher sein, detaillierte Einstellungen anzupassen, wenn Python beteiligt ist.

Dinge notwendig

Bitte installieren Sie Pyopengl und Pyaudio mit Pip. Wenn es nicht funktioniert http://www.lfd.uci.edu/~gohlke/pythonlibs/ Das Herunterladen des Pakets von hier funktioniert normalerweise.

Dies ist das Skript

Die Erklärung hier ist schwierig, verwenden Sie sie daher bitte als Bibliothek. Die Abtastrate ist auf 48000 eingestellt. Wenn Ihnen der Unterschied gefällt, beheben Sie ihn bitte entsprechend.

from OpenGL.GL import *
from OpenGL.WGL import *
from ctypes import *
import numpy
import pyaudio
import wave
import array

def shader2data(duration, src): #Ausgabezeit, Shader-Musikquelle
    sampleRate = 48000
    numSamples  = duration*sampleRate
    numSamplesC = numSamples*2
    samples = (c_float * numSamplesC)()
    hWnd = windll.user32.CreateWindowExA(0,0xC018,0,0,0,0,0,0,0,0,0,0)
    hDC = windll.user32.GetDC(hWnd)
    pfd = PIXELFORMATDESCRIPTOR(0,1,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0)
    SetPixelFormat(hDC,ChoosePixelFormat(hDC, pfd), pfd)
    hGLrc = wglCreateContext(hDC)
    wglMakeCurrent(hDC, hGLrc)
    program = glCreateProgram()
    shader = glCreateShader(GL_VERTEX_SHADER)
    glShaderSource(shader, src)
    glCompileShader(shader)
    if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
      raise RuntimeError(glGetShaderInfoLog(shader).decode())
    glAttachShader(program, shader)
    outs =  cast((c_char_p*1)(b"gain"), POINTER(POINTER(c_char)))
    glTransformFeedbackVaryings(program, 1, outs, GL_INTERLEAVED_ATTRIBS)
    glLinkProgram(program)
    glUseProgram(program)
    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, sizeof(samples), None, GL_STATIC_DRAW)
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo)
    glUniform1f(glGetUniformLocation(program, "sampleRate"), sampleRate)
    glEnable(GL_RASTERIZER_DISCARD)
    glBeginTransformFeedback(GL_POINTS)
    glDrawArrays(GL_POINTS, 0, numSamples)
    glEndTransformFeedback()
    glDisable(GL_RASTERIZER_DISCARD)
    glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(samples), byref(samples))
    wglMakeCurrent(0, 0);
    wglDeleteContext(hGLrc);
    windll.user32.ReleaseDC(hWnd, hDC);
    windll.user32.PostQuitMessage(0);
    return numpy.frombuffer(samples, dtype=numpy.float32)

def writeWav(filename, data):    
    sampleRate = 48000
    w = wave.Wave_write(filename)
    w.setnchannels(2)
    w.setsampwidth(2)
    w.setframerate(sampleRate)
    w.writeframes(array.array('h', data*32767).tobytes())
    w.close()

def readWav(filename): 
    w = wave.open(filename, 'rb')
    print("params  :", w.getparams())
    print("duration:", w.getnframes() / w.getframerate(), "sec")
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(w.getsampwidth()),
                channels=w.getnchannels(),
                rate=w.getframerate(),
                output=True)
    stream.write(w.readframes(w.getnframes()))
    stream.close()
    p.terminate()

def playSound(data):    
    sampleRate = 48000
    p = pyaudio.PyAudio()
    stream = p.open(rate=sampleRate, channels=2, format=pyaudio.paFloat32, output=True)
    stream.write(array.array('f', data).tobytes())
    stream.close()
    p.terminate()

Einfache Regeln zum Schreiben von Shader

Es verwendet denselben Funktionsnamen und Argumentnamen wie mainSound (), die Hauptfunktion von Shadertoys Musik-Shader. Sie können also den Shadertoy-Musik-Shader für diesen Teil kopieren und einfügen. Ändern Sie nicht andere Uniform, out, main () usw.

src = """
#version 300 es

out vec2 gain; 
uniform float sampleRate;    

vec2 mainSound( float time )
{
  return vec2(sin(6.2831*440.0*time)); ;
}

void main() {
  float time = float(gl_VertexID) / sampleRate;
  gain =mainSound(time); 
}
"""

Dies ist die Quelle für den Shader. Wenn Sie dies und shader2data (Dauer, src) mit der Ausgabezeit als Argument eingeben, werden Beispieldaten ausgegeben. Geben Sie diese Beispieldaten und den Dateinamen in writeWav (Dateiname, Daten) ein, um eine WAV-Datei zu erstellen. Sie können den Ton mit readWav (Dateiname) hören. Wenn Sie den Sound unverändert ausgeben möchten, ohne eine Datei zu erstellen, verwenden Sie playSound (Daten).

data = shader2data(2,src)
filename = "output.wav"
writeWav(filename, data)
readWav(filename)
playSound(data)

Ich benutze es so.

Schließlich

Ich glaube nicht, dass es eine Nachfrage gibt, aber ich habe einen Artikel geschrieben, der gleichzeitig als Memorandum dient. Ich habe die Ipython-Datei hier abgelegt. https://gist.github.com/gaziya/e5d40b0df1a65510af81b124c4ecf4cc

Recommended Posts

Erstellen Sie mit python3 eine WAV-Datei aus dem GLSL-Shader
Erstellen Sie eine Deb-Datei aus einem Python-Paket
Erstellen Sie eine GIF-Datei mit Pillow in Python
Führen Sie Python-Dateien mit Django aus HTML aus
Erstellen Sie eine MIDI-Datei in Python mit pretty_midi
Erstellen Sie eine Bilddatei mit PIL (Python Imaging Library).
Erstellen Sie Ihre erste GDSII-Datei in Python mit gdspy
Python-Skript, das eine JSON-Datei aus einer CSV-Datei erstellt
Mit Python abflachen
Erstellen Sie JIRA-Tickets mit Python
Führen Sie das Python-Skript aus der Batchdatei aus
Verwenden von Rstan aus Python mit PypeR
Hinweise zur Verwendung von MeCab aus Python
Verwenden von Cloud-Speicher aus Python3 (Einführung)
Extrahieren Sie die Targz-Datei mit Python
Führen Sie Ansible über Python mithilfe der API aus
Vorsichtsmaßnahmen bei der Verwendung von Phantomjs aus Python
Greifen Sie mit OAuth 2.0 von Python aus auf Tabellenkalkulationen zu
Greifen Sie über Python auf die Shader-Knoten von Blender zu
[Python] Dateivorgang mit der if-Anweisung
Versuchen Sie es mit Amazon DynamoDB von Python
Von Python bis zur Verwendung von MeCab (und CaboCha)
Erstellen Sie mit python3 eine Wortwolke aus Ihrem Tweet
Verwenden Sie boto, um die Datei von S3 herunterzuladen.
Erstellen Sie schnell eine Excel-Datei mit Python #python
Erstellen Sie mit Mecab aus Python3 ein Tool, das Furigana automatisch mit HTML schüttelt
[Python] Erstellen Sie eine Stapelumgebung mit AWS-CDK
Ich habe versucht, die UnityCloudBuild-API von Python zu verwenden
Erstellen Sie eine Excel-Datei mit Python + Ähnlichkeitsmatrix
[GPS] Erstellen Sie eine kml-Datei mit Python
Erstellen Sie mit Pandas einen Datenrahmen aus Excel
[Hyperledger Iroha] Erstellen Sie ein Konto mit der Python-Bibliothek
Bearbeiten Sie Excel in Python, um eine Pivot-Tabelle zu erstellen
[Python] Teilen Sie eine große Flask-Datei mit Blueprint
Erstellen Sie ein C-Array aus einer Python> Excel-Tabelle
Excel-Datei aus Python importieren (in DB registriert)
[Python-Pandas] Erstellen Sie einen leeren DataFrame aus einem vorhandenen DataFrame
Ich möchte mit Python eine E-Mail von Google Mail senden.
Von der Datei zur Diagrammzeichnung in Python. Grundstufe Grundstufe
So erstellen Sie eine JSON-Datei in Python
Erstellen Sie eine neue Todoist-Aufgabe aus Python Script
[Python] Erstellen Sie eine Tabelle von Pandas DataFrame zu Postgres
Erstellen Sie mit ClustalW2 einen phylogenetischen Baum aus Biopyton
Erstellen Sie mit CadQuery 3D-Druckerdaten (STL-Datei)
Erstellen Sie eine Webmap mit Python und GDAL
Ich habe versucht, eine CSV-Datei mit Python zu lesen
Erstellen Sie mit Python einen Entscheidungsbaum von 0 (1. Übersicht)
Erstellen Sie ein Datum / Uhrzeit-Objekt aus einer Zeichenfolge in Python (Python 3.3).
Laden Sie Bilder von der URL mit Pillow in Python 3
Erstellen Sie mit Python eine Datei im Photoshop-Format (.psd)
Lesen Sie mit Python Zeile für Zeile aus der Datei
Führen Sie Python-Skripte in Excel aus (mit xlwings).
Skript-Python-Datei
Starten Sie Python
SQL zu SQL