add pyaudio

This commit is contained in:
wataru 2023-02-17 13:10:17 +09:00
parent 63d58b82b5
commit be9695307a
5 changed files with 899 additions and 40 deletions

View File

@ -1 +1,10 @@
<!doctype html><html style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>Voice Changer Client Demo</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div></body></html> <!DOCTYPE html>
<html style="width: 100%; height: 100%; overflow: hidden">
<head>
<meta charset="utf-8" />
<title>Voice Changer Client Demo</title>
<script defer src="index.js"></script></head>
<body style="width: 100%; height: 100%; margin: 0px">
<div id="app" style="width: 100%; height: 100%"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,31 +0,0 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

View File

@ -124,4 +124,20 @@ export class ServerConfigurator {
}) })
return await info return await info
} }
// Local Mic
getServerMicrophones = async () => {
const url = this.serverUrl + "/microphone"
const info = await new Promise<ServerInfo>((resolve) => {
const request = new Request(url, {
method: 'GET',
});
fetch(request).then(async (response) => {
const json = await response.json() as ServerInfo
resolve(json)
})
})
return info
}
} }

View File

@ -1,6 +1,8 @@
import base64, struct import base64
import struct
import numpy as np import numpy as np
import traceback import traceback
import pyaudio
from fastapi import APIRouter from fastapi import APIRouter
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
@ -10,17 +12,50 @@ from voice_changer.VoiceChangerManager import VoiceChangerManager
from pydantic import BaseModel from pydantic import BaseModel
import threading import threading
class VoiceModel(BaseModel): class VoiceModel(BaseModel):
timestamp: int timestamp: int
buffer: str buffer: str
class MMVC_Rest_VoiceChanger: class MMVC_Rest_VoiceChanger:
def __init__(self, voiceChangerManager:VoiceChangerManager): def __init__(self, voiceChangerManager: VoiceChangerManager):
self.voiceChangerManager = voiceChangerManager self.voiceChangerManager = voiceChangerManager
self.router = APIRouter() self.router = APIRouter()
self.router.add_api_route("/test", self.test, methods=["POST"]) self.router.add_api_route("/test", self.test, methods=["POST"])
self.router.add_api_route("/microphone", self.get_microphone, methods=["GET"])
self.tlock = threading.Lock() self.tlock = threading.Lock()
def get_microphone(self):
audio = pyaudio.PyAudio()
audio_input_devices = []
audio_output_devices = []
audio_devices = {}
host_apis = []
for api_index in range(audio.get_host_api_count()):
host_apis.append(audio.get_host_api_info_by_index(api_index)['name'])
for x in range(0, audio.get_device_count()):
device = audio.get_device_info_by_index(x)
try:
deviceName = device['name'].encode('shift-jis').decode('utf-8')
except (UnicodeDecodeError, UnicodeEncodeError):
deviceName = device['name']
deviceIndex = device['index']
hostAPI = host_apis[device['hostApi']]
if device['maxInputChannels'] > 0:
audio_input_devices.append({"kind": "audioinput", "index": deviceIndex, "name": deviceName, "hostAPI": hostAPI})
if device['maxOutputChannels'] > 0:
audio_output_devices.append({"kind": "audiooutput", "index": deviceIndex, "name": deviceName, "hostAPI": hostAPI})
audio_devices["audio_input_devices"] = audio_input_devices
audio_devices["audio_output_devices"] = audio_output_devices
json_compatible_item_data = jsonable_encoder(audio_devices)
return JSONResponse(content=json_compatible_item_data)
def test(self, voice: VoiceModel): def test(self, voice: VoiceModel):
try: try:
@ -38,7 +73,7 @@ class MMVC_Rest_VoiceChanger:
# unpackedData.astype(np.int16)) # unpackedData.astype(np.int16))
self.tlock.acquire() self.tlock.acquire()
changedVoice = self.voiceChangerManager.changeVoice( unpackedData) changedVoice = self.voiceChangerManager.changeVoice(unpackedData)
self.tlock.release() self.tlock.release()
changedVoiceBase64 = base64.b64encode(changedVoice).decode('utf-8') changedVoiceBase64 = base64.b64encode(changedVoice).decode('utf-8')
@ -55,6 +90,3 @@ class MMVC_Rest_VoiceChanger:
print(traceback.format_exc()) print(traceback.format_exc())
self.tlock.release() self.tlock.release()
return str(e) return str(e)