Pulseaudioが起動しなくなった時の対処法

Windows 11で動かしていたPulseaudioが以下の通りエラーとなって起動しなかった。

W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on this platform.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on this platform.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on this platform.
E: [(null)] pulsecore/pid.c: Daemon already running.
E: [(null)] daemon/main.c: pa_pid_file_create() failed.

pidファイルが削除されず残っていることが、エラーの原因らしい。ctrl+cを使わずに×ボタンでウィンドウを閉じるとファイルが残ってしまうとのこと。

自分の環境では、他のサイトで指定されていたフォルダにpidファイルは無く、下記のフォルダにpidファイルが作成されていた。下記のファイルを削除したらPulseaudioが正常に起動するようになった。

%USERPROFILE%\.config\pulse\%USERDOMAIN%-runtime\pid

WSL2 UbuntuでUSB デバイスを使用する

  1. usbipd-win プロジェクトの最新リリースのページにあるmsiファイルをダウンロードする
  2. ダウンロードした usbipd-win_x.msiファイルを実行する

WSL2のコンソール上で以下のコマンドを実行する。インストールするバージョンは自身の環境とあわせる。

sudo apt install linux-tools-5.15.0-33-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/5.15.0-33-generic/usbip 20

PowerShellを管理者として実行する。下記のコマンドを実行し接続されているUSBデバイスのリストを取得する。

usbipd wsl list

BUSID  VID:PID    DEVICE 
3-4    328f:2013  HD Webcam eMeet C960, USB 入力デバイス 

使用したいUSBデバイスのBUSIDを、下記コマンドで割り当てする。

usbipd wsl attach --busid 3-4

WSL2のコンソール上で下記コマンドを実行し、先ほど割り当てたUSBデバイスが表示されることを確認する。

lsusb

Bus 001 Device 002: ID 328f:2013 SHENZHEN EMEET TECHNOLOGY CO.,LTD. HD Webcam eMeet C960

使用し終わったら、下記コマンドで割り当てを解除する。

usbipd wsl detach --busid 3-4

Ubuntu 22.04にpyopenjtalkをインストールする

pyopenjtalkの依存関係で使用しているライブラリがPython 3.10に対応していないため、インストール出来なかった。Ubuntu 22.04ではPython 3.10がデフォルトになっている。そこで、仮想環境を構築してPython 3.9で動くようにした。

まず、Python 3.9をインストールする。

sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install python3.9
sudo apt install python3.9-dev
sudo apt install python3.9-distutils

virtualenvをインストールして、Python 3.9の仮想環境を構築する。この時VSCODEの作業フォルダ内に作成すれば、VSCODE上でも認識されて使用することが可能になる。

pip install virtualenv
virtualenv -p python3.9 p39

Python 3.9の仮想環境を有効にして、pyopenjtalkをインストールする。

source vscode/p39/bin/activate
pip install --upgrade setuptools pip
pip install pyopenjtalk

仮想環境を抜ける場合は下記を実行する。

deactivate

MMVCを試してみる

MMVCというAIを使ったリアルタイムボイスチェンジャーなるものを見つけた。自分の声を収録して、それを別人の声に変換するとは、映画「ミッションインポッシブル3」で見たようなシーン(厳密には少し違うが)が実際に実行可能になるなんて、とても面白そうだったので試してみたくなった。

環境

公式ではgoogle colaboratoryを使っていて、そのまま何も変更することなく動かすことが出来る。しかし、自前のPCで実行したくなった。Windows WSL2環境で実行するのは結構面倒なのでおすすめはしません。

Windows 11
WLS2
Ubuntu 20.04
Python 3.8.10
cuda-toolkit-11-6 is already the newest version (11.6.2-1).
libnccl-dev is already the newest version (2.12.10-1+cuda11.6).
libcudnn8 is already the newest version (8.4.0.27-1+cuda11.6).
VSCODE 1.66.2

MMVCのライセンス情報

MMVCv1.2.0.2
Copyright (c) 2021 Isle.Tennos 
Released under the MIT license 
https://opensource.org/licenses/mit-license.php
git:https://github.com/isletennos/MMVC_Trainer
community(discord):https://discord.gg/PgspuDSTEc

MMVC_Trainerのインストール

公式からレポジトリをダウンロードして、VSCODEの作業フォルダに解凍する。

MMVC_Trainerの実行

自身の音声ファイルの準備

公式のページに書かれている通り、自分の音声を収録していく。(100文読み上げるのは結構大変だった)

インストールと環境設定

以下の通りインストールする。CUDAのインストールについてはこちらを参照のこと。

sudo apt install cmake
sudo apt install espeak

pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113
pip install pyopenjtalk

現時点での最新版をインストールしている。

cmake is already the newest version (3.16.3-1ubuntu1).
espeak is already the newest version (1.48.04+dfsg-8build1).
torch in ./.local/lib/python3.8/site-packages (1.11.0+cu113)
torchvision in ./.local/lib/python3.8/site-packages (0.12.0+cu113)
torchaudio in ./.local/lib/python3.8/site-packages (0.11.0+cu113)
pyopenjtalk in ./.local/lib/python3.8/site-packages (0.2.0)

Create_Configfile.ipynbの実行

Create_Configfile.ipynbを実行して、環境ファイルを作成する。Googleドライブ、インストール部分の実行は不要。フォルダの指定はローカルの環境に合わせる。

Train_MMVC.ipynbの実行

モデルをトレーニングしていく。自前の環境には以下のものがインストールされている。本来は公式から指定されているバージョンをインストールするべき。下記のように違うバージョンを使う場合は自己責任で。

Cython in ./.local/lib/python3.8/site-packages (0.29.28)
librosa in ./.local/lib/python3.8/site-packages (0.9.1)
matplotlib in ./.local/lib/python3.8/site-packages (3.5.2)
numpy in ./.local/lib/python3.8/site-packages (1.21.6)
phonemizer in ./.local/lib/python3.8/site-packages (3.1.1)
scipy in ./.local/lib/python3.8/site-packages (1.8.0)
tensorboard in ./.local/lib/python3.8/site-packages (2.8.0)
Unidecode in ./.local/lib/python3.8/site-packages (1.3.4)
retry in ./.local/lib/python3.8/site-packages (0.9.2)
tqdm in ./.local/lib/python3.8/site-packages (4.64.0)

./monotonic_align/setup.pyを下記の通り実行して、core.cpython-38-x86_64-linux-gnu.soをビルドする。

python3 setup.py build_ext --inplace

train_ms.pyを以下の通り、修正する。

import warnings
warnings.simplefilter('ignore', FutureWarning)
warnings.simplefilter('ignore', UserWarning)
train_ms.py:50行目
  os.environ['MASTER_PORT'] = '8000'

train_config_zundamon.jsonを以下の通り修正する。自前のPCではOut of Memoryになってしまったため、batch_sizeを5に変更した。

"batch_size": 5,

後はTrain_MMVC.ipynbファイルの指示通り実行していく。Googleドライブ、インストール部分の実行は不要。フォルダの指定はローカルの環境に合わせる。実行に成功すれば下記のようにモデルのトレーニングが進んでいく。

Epoch 436:  90%|████████████████████████████▋   | 70/78 [00:51<00:05,  1.49it/s]

すべて実行し終わるにはかなり時間がかかると思うので、自分は適当なところで中断して、トレーニング途中のモデルを使用してVC処理を動かすことにした。

学習したモデルの検証

MMVC_Interface.ipynbファイルの指示通り実行して自分の音声が変換されることを確認する。学習が足りないとうまく変換されないかもしれないが、自分が実行したことろではそれなりに満足のいく結果だったので、次のリアルタイム変換に進むことにした。

※VSCODEだとIPython.display.Audioは使えないので、wavファイルをして書き出すように変更しておく。

ipd.display(ipd.Audio(audio1, rate=hps.data.sampling_rate))
write('converted.wav', hps.data.sampling_rate, audio1)

MMVC_Clientのインストール

公式からレポジトリをダウンロードして、VSCODEの作業フォルダに解凍する。

※2022/05/11追記 WSL2環境からマイクを使用することがまだ出来なくて未検証。出来るようになり次第追記予定。

※2023/04/01追記 MMVC_client v0.3.1.0が出て、簡単にクライアントを使用できるようになった。こちらでも解説している。

pulseaudioのインストールと実行

Windows側

default config filesフォルダにあるdefault.paファイルをコピーして、以下行を変更する。

load-module module-waveout sink_name=output source_name=input record=0
load-module module-native-protocol-tcp auth-ip-acl=127.0.01;10.0.0.0/8;172.16.0.0/12;192.168.0.0/16
E:\pulse\pulseaudio.exe -F E:\pulse\default.pa --exit-idle-time=600

初回起動時、外部からのアクセスを許可するか問われるので、「パブリックネットワーク」にチェックを入れてアクセスを許可する。

Ubuntu側
sudo apt install portaudio19-dev
pip install pyaudio
pip install noisereduce
echo 'export PULSE_SERVER=tcp:$(grep nameserver /etc/resolv.conf | awk '\''{print $2}'\'')' >> ~/.profile
source ~/.profile

output_audio_device_list.pyの実行

rec_environmental_noise.pyの実行

mmvc_client_GPU.pyの実行

  - ext_modules = cythonize("d:/code/monotonic_align/core.pyx"),
  + ext_modules = cythonize("core.pyx"),

wsl2の仮想ハード ディスク (VHD) ファイルの物理サイズを減らす

色々実験していたら、VHDファイルサイズがかなり大きくなってしまったため、以下のコマンドで物理ファイルを減らす対応を行った。

wsl --shutdown
diskpart

# open window Diskpart
select vdisk file="C:\Users\ユーザーID\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_~~~\LocalState\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

Vuexで検索条件を保持する

やりたいこと

検索条件を保持し、当該画面に戻ってきたときに、前回の検索条件を表示する。

コード例

Vuexで呼び出される処理を定義していく。
※細かいところは省略済み。

//ファイルパス:modules/novel/search.js
const state = {
  searchParameter: {
    title: '',
    writername: '',
    description: ''
  }
}

const getters = {
  getSearchParameter: state => state.searchParameter
}

const actions = {
  // 検索処理
  [NOVEL_SEARCH]: ({ commit }, param) => {
    return new Promise((resolve, reject) => {
      // 検索条件をstateに保存する処理を呼び出す(下記のcommitでmutationsのNOVEL_SEARCHが実行される)
      commit(NOVEL_SEARCH, param)
      novelRepository.get(searchParameterBuilder(param))
      .then(resp => {
        commit(NOVEL_SEARCH_SUCCESS, resp)
        resolve(resp)
      })
      .catch(err => {
        commit(NOVEL_SEARCH_ERROR)
        reject(err)
      })
    })
  }
}

const mutations = {
  [NOVEL_SEARCH]: (state, param) => {
    state.searchParameter = param
  }
}

export default {
  state,
  getters,
  actions,
  mutations
}
import { createStore } from 'vuex'
import novelSearch from './modules/novel/search'

export default createStore({
  modules: {
    novelSearch
  }
})

vueファイルから以下の通り呼び出して、使用する。(記事の都合上、分けて記載しているけど、本来1つのファイル)

<script setup>
import { reactive, computed } from 'vue'
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'

const store = useStore()
const { t } = useI18n()

// Vuexに保持されている検索条件を読み込む
const searchParameter = computed(() => store.getters.getSearchParameter)

const state = reactive({
  title: searchParameter.value.title,
  writername: searchParameter.value.writername,
  description: searchParameter.value.description
})

function search() {
  const { title, writername, description } = state
  // 検索処理を実行する(search.jsのactionsのNOVEL_SEARCHが実行される)
  store.dispatch(NOVEL_SEARCH, { title, writername, description }).catch(error => {
    ElMessage({
      message: error,
      grouping: true,
      type: 'error'
    })
  })
}
</script>
<template>
  <div class="novel-search">
    <el-card class="box-card box-card-wrapper">
      <el-row class="row-wrapper">
        <el-col
          class="col-wrapper"
          :span="6"
        >
          <el-input
            :placeholder="$t('title')"
            v-model="state.title"
            clearable
          />
        </el-col>

JenkinsでwarファイルをTomcatにデプロイする

前提

ビルドが成功して、warファイルが作成されること。

プラグインのインストール

JenkinsのPlugin ManagerでDeploy to container Pluginをインストールする。

ビルド後の処理の追加

Deploy war/ear to a containerを追加する。

Warファイルのパス、コンテキスト名を設定する。

Built-in Tomcat manager rolesで、manager-scriptに設定した、ユーザー名、パスワードをCredentialsに設定する。

JenkinsでMavenの実行結果のレポートを作成する

Mavenのインストール

sudo apt install maven
mvn --version

レポート作成でよく使うプラグインをインストールする

JaCoCo plugin: JaCoCoコードカバレッジレポートをJenkinsに統合する。

Warnings Next Generation Plugin: 静的分析ツールによって報告されたコンパイラの警告または問題を収集し、結果を視覚化する。(自分はspotbugs、checkstyleで使用)

Jenkinsの設定

ビルドにMavenの呼び出しを追加する。

package site

ビルド後の処理に以下の項目を追加する。

1.JUnitテスト結果の集計
target/surefire-reports/*.xml


2.JaCoCoカバレッジレポートを記録


3.Javadocの保存


4.CheckStyleとSpotBugsの解析結果を保存

GithubにコミットしたらJenkinsで自動的にビルドされるようにする

Jenkins側の設定

グローバルセキュリティの設定

ログインしていない場合でも、jenkinsにリードオンリーでアクセスできるように設定する。

ジョブを作成する

GitHub projectにチェックし、GitHub上のプロジェクトのURLを設定する。同時にソースコード管理にもURLを設定する。公開レポジトリであれば認証情報は入力不要。

GitHub hook trigger for GITScm pollingにチェックを入れる。

上記でジョブを作成する。これでジョブを自動的に起動する準備が出来たので、後はプロジェクトの要件に合わせてビルドやテストが起動するように、カスタマイズすれば良い。

GitHub側の設定

連携するプロジェクトのSettingsを開きWebhookを作成する。Payload URLにはJenkinsのURL+「/github-webhook/」を指定する。Content typeにはJSONを指定する。

動作確認

GitHubに変更がpushされると、Jenkinsのジョブが起動することが確認できる。

Mavenでのビルド、そのビルド後の処理について

Mavenのビルド、Mavenのビルド処理で作成したJavadoc等をJenkinsプロジェクトのメニューに表示されるようにする方法はこちら