Windows 10 1809이상에서 벌어지는 일입니다.

특정 기기에서 특정게임에서만 일어나는 일이라 일종의 버그라고 볼 수 있습니다.

특정게임이라고 하면
1. 오래된 게임 (DirectX 9 이하)
2. 저해상도 전체화면(특히 640x480)
3. 디지털 사운드 인터페이스가 있는지도 모르는때에 만들어진 게임

대충 이렇습니다.

이런경우 아날로그 사운드카드가 없으면 오류가 나면서 소리가 안나는 경우가 있습니다.
방법은 HDMI로 직접 쏘지 않고 아날로그 사운드카드로 사운드를 보낸다음 이걸 스테레오믹스캡처로 다시 HDMI로 보내면 됩니다.

이런 무슨 거지같은 경우가 다 있나 싶긴한데 게임이 오래된 탓이니 어쩔수 없습니다.

기본 사운드장치를 아날로그 사운드로 잡고 HDMI를 기본통신장치로 설정합니다.

설정이 아닌 제어판의 소리 설정(설정-소리-사운드 제어판도 가능)으로 들어갑니다.
혹은 오른쪽 아래 소리 아이콘 오른쪽버튼을 누르고 소리를 클릭해도 됩니다.

우선 아날로그 출력 기기를 기본 장치로 설정하고 디스플레이 오디오를 기본통신장치로 설정합니다. 이러면 마이크를 통해들어오는 소리는 HDMI로 나가고 일반 소리는 아날로그로 나가게 됩니다.

그리고 진짜 핵심은 마이크(녹음)장치를 데스크탑사운드 혹은 스테레오믹스라 불리는 장치로 설정하는 겁니다.


Windows의 소리 설정에서 이렇게 바꿉니다.

이러면 아날로그로 쏜 소리가 캡처되어 HDMI로 다시 돌아오게됩니다.

좀 이상하다고요? 옛날게임들은 디지털출력의 개념이 없던시절이라 이렇습니다. 이리저리 돌려본결과 HDMI를 쓰면서 옛날게임을 돌리니 HDMI사운드가 사라집니다. 다른건 문제없는데 640x480정도의 저해상도를 쓰면 HDMI가 꺼졌다켜지는 탓인지 사운드 설정이 사라지네요.

최신빌드에서 일부게임은 해결됐다고 하던데 정작 제 PC에선 멀쩡하던 게임도 소리가 안 나는 사태가 벌어져서 구버전으로 돌린뒤에 이런식으로 우회했습니다.

만약 아날로그 활성화가 안 될경우 헤드셋이나 이어폰이 인식이 안 된것입니다. 제어판을 통해 강제인식시키거나 리얼텍 아날로그 제품은 Realtek Audio Console에서 장치 고급설정을 통해서 강제 활성화가 가능합니다.

이렇게 하면 이어폰잭이 무조건 연결된것으로 알아먹습니다.

인텔이나 다른 칩셋을 쓸 때는 다른방법을 쓰는것이 좋겠지요. 혹은 고전게임이 문제를 일으키는 것이니 고전OS를 가상머신으로 돌리는 것도 방법이겠지요.

,

https://github.com/MoorDev/Tacotron2-Wavenet-Korean-TTS

 

MoorDev/Tacotron2-Wavenet-Korean-TTS

Korean TTS, Tacotron2, Wavenet. Contribute to MoorDev/Tacotron2-Wavenet-Korean-TTS development by creating an account on GitHub.

github.com

지속적으로 기존에 있던 hccho2 님의 Tacotron2의 소스(https://github.com/hccho2/Tacotron2-Wavenet-Korean-TTS)로 수정중이다.
Tensorflow 1.x를 썼기에 그에 따른 구버전 설치 문제가 있었고 (그동안은 tensorflow.contrib 모듈로 인해 1.x 사용이 강제 되었지만 TFA(https://www.tensorflow.org/addons/overview?hl=ko)의 등장으로 2.x로의 포팅이 어렵지 않게 되긴했다.) Python 3.6~3.7 이외에서 오류가 발생하는 문제도 있었다.

하지만 이 코드가 제일 확실한 한국어 Tacotron 소스였고 제일 잘 돌아가는 코드였다. (무엇보다 학습속도가 빨랐다.)
다만 문제는 내가 만든 데이터셋을 적용하려 하니 고생이 많았다는 것.

KSS데이터셋https://www.kaggle.com/bryanpark/korean-single-speaker-speech-dataset 은 테스트하기 제일 좋은 물건이었고 이것을 이용해 만든 모델을 전이시켜서 새로운 목소리로 하는 글도 많이 있었는데 결과물은 어딘가가 계속 부족했다. 즉, 궁극적인 이유는 학습데이터가 부족한것.

그리하여 데이터 증강기법을 음성에 적용하기로 했고 sox의 tempo와 dither 기능을 사용해 목소리의 속도를 미묘하게 바꿔 데이터를 증강하였다. tempo 0.9 0.85 이 둘만 해도 사람 귀에는 크게 거슬리지 않는 소리가 나오며 1.05배도 큰 차이를 못 느낀다. 하지만 dither 기능으로 이 모든 음성은 Mel Spectrogram이 전혀 다른 녀석이 튀어나오며 데이터 증강효과가 발생한다. (하지만 속도만 조절한것이기에 문장자체는 동일하므로 데이터 증강 효과가 없을지도...)

 

#!/bin/bash
find ./audio/ | while read entry
do
    sox "${entry}" "${entry//.wav/_slow.wav}" -V tempo 0.8
done

위 bash 스크립트를 audio 폴더 밖에서 만들어서 실행하면 _slow가 붙은 wav파일이 추가된다. recognition.json파일은 어차피 이 글을 보고 있는 이상 dataset을 만들줄 알고 있다는 의미일테니 길게 설명하지는 않을 것이다. 해당 json파일에 추가된 slow파일 리스트를 추가하면 데이터 증강이 된다. 이 파일을 수정하면 0.8배 0.9배 1.1배(빠르게 만드는 것은 발음이 뭉개지기 때문에 추천하지 않음)데이터 증강을 할 수있다. 이건 응용하는 사람에 따라 다를 것이다.

본래 데이터셋이 말이 좀 빠르다면 0.7배까지도 문제 없을 것으로 생각된다.


그리하여 어느정도 괜찮은 결과는 나왔지만 문제는 데이터의 증가폭이 너무 큰 나머지 학습속도가 무지막지하게 느려졌다. 하지만 뭐.... 결과만 잘나오면 장땡이지.

이외에도 수정한 hparam을 정리한다. hparam.py를 열면 잔뜩 있는데 여기를 수정하면서 학습튜닝하는것이 노가다지만 의외로 재미있다.

griffin_lim_iters = 100,
#기본은 60이며 Mel-spectrogram을 Linear-spectrogram으로 바꾸고 이를 다시 시간영역으로 바꾸는 알고리즘. Wavenet이 등장해서 이걸로 대체하기도 하지만 속도면에서 아직 Griffin-Lim이 나에겐 더 맞는 방식이었다. Iters를 100이상으로 늘리니 조금 더 들어줄만한 음성이 나온다.

main_data_greedy_factor = 0.5,
main_data = ['./data/monika'], # 이곳에 있는 directory 속에 있는 data는 가중치를 'main_data_greedy_factor' 만큼 더 준다.

이 파라미터는 어느 목소리를 메인으로 할 것인가를 결정한다. Multi Speaker 는 말이좋아 multi-speaker지 엄밀히 말해서 부족한 데이터를 대신해 메인이 되는 것을 대량의 데이터가 도와주는 것에 가깝다. greedy_factor를 많이 주면 많이 줄 수록 메인 데이터 위주로 학습을 이뤄지며 보조데이터셋의 학습속도는 떨어진다. 적절한 값을 찾지 않으면 모두 학습이 느려지는 결과를 초래한다. 대신 Overfitting은 잘 이뤄지지 않는다.

silence_threshold = 1,
trim_silence = True, #Whether to clip silence in Audio (at beginning and end of audio only, not the middle)
기본은 0인데 무음부분을 삭제한다. 앞뒤의 무음만 삭제하므로 학습효과를 올려주는 효과가 있다.

Nvidia의 논문에 따르면 앞뒤에 무음이 있으면 Attention이 잘 잡히지 않아 학습속도가 떨어진다고 한다.

일단 이 정도로 파라미터를 수정하고 돌리니 1시간 음성을 3시간으로 뻥튀기 하고 200k STEP이 돌아가는 와중에도 attention은 아직 제대로 안 잡힌다. 그런데 조금씩조금씩 잡혀가는게 1000k쯤되면 문제 없을 듯.

뭔가 300k부터 align이 안 잡히는 것이 보인다. 이건 문제가 있다.
역시 dataset이 문제 아닐까 싶은데 자세히 보니 내 데이터는 stereo로 되어있었다. 혹시 이건가...?

일단 mono로 바꾸기 위해서 wav파일들이 있는 곳에서

find . -name '*.wav' -exec ffmpeg -i '{}' -ac 1 '{}' \;

위 명령을 이용했다. 어떻게든 되겠지.

그리고 https://github.com/carpedm20/multi-speaker-tacotron-tensorflow/issues/4#issuecomment-368457924

 

training이 잘 안됩니다. · Issue #4 · carpedm20/multi-speaker-tacotron-tensorflow

샘플로 주신 prepare_jtbc.sh을 실행해 만든 audio data를 가지고 single speaker로 20만 step이상 학습을 진행했는데도, 여전히 음성이 제대로 안 나옵니다. 문제가 뭔지 알 수가 없습니다. 혹시 제대로 음성

github.com

여기보니 reduction factor를 5로 바꾸니 더 잘 된다는 이야기가 있다. 이유는 여전히 모르겠지만... 일단 손을 대보는 중.

위의 방법이 확실히 효과가 있었다!
Reduction Factor 5
데이터의 Mono화(ffmpeg이용)
데이터 증강(sox이용)

이 3가지가 정답이었다!
물론 아직은 노이즈가 느껴지지만 Align이 확실히 잡힌다

12000Step의 Alignment 상황이다.
Hyper parameter와 데이터증강기술(?)그리고 데이터 셋 정리의 승리

 

 

이제 여기서 pb로 만들고 기타 정리를 더 하면 모바일에서 나만의 TTS를 만들 수 있을지도 모른다

https://github.com/keithito/tacotron/issues/95

 

Freezing and Optimising for Inference · Issue #95 · keithito/tacotron

I've been attempting today to create a frozen graph, and then optimise that graph for inference (to evaluate performance for an embedded device). This model lacks a placeholder node for inferen...

github.com

여기서 원본 코드를 만든 keithito의 말에 의하면 Output Node name은 "model/inference/dense/BiasAdd:0" 이거라고 하니까 ckpt를 pb로 만드는건 어렵지 않을지도

물론 결과물은 Griffin-Lim을 한번 해줘야 하니까 여기서 성능을 꽤 잡아 먹겠지만...

 

대충 이런식으로 하면 bazel로 pb할 수 있다고 한다.

./bazel-bin/tensorflow/tools/graph_transforms/transform_graph \ --in_graph="../TTSDataset_keith/tacotron-60k/freezed.pb" \ --inputs='import/datafeeder/input_queue' \ --outputs='model/inference/dense/BiasAdd:0' \ --out_graph='optimized_ta_keith_60k.pb' \ --transforms='strip_unused_nodes(type=float, shape="1,224,224,3")fold_constants(ignore_errors=true) fold_batch_norms fold_old_batch_norms quantize_weights quantize_nodes sort_by_execution_order' \

 

해보면 대충 뭐..알겠지

,

잉크스케이프, Blender, Gimp

이 셋은 오픈소스 CG 삼대장이라 불립니다.

 

벡터이미지의 잉크스케이프

비트맵이미지의 Gimp

3D의 Blender

 

이 중에서 제일 성능이 구리고 문제 많기로 소문난 것이 잉크스케이프 입니다.

 

하지만 벡터이미지를 만드는 것에는 Adobe Illustrator를 제외하면 이것밖에 없다고 해도 과언이 아닙니다.

아니면 CAD를 쓰는 방법도 있기는 한데 애초에 CAD는 그림그리라고 만든것이 아니라서 Spliine 처리하다보면 빡칩니다.

 

그리고 어차피 대부분 벡터 이미지 쓰는 곳이면 *.ai파일 아니면 *.svg인데 SVG야 잉크스케이프의 네이티브 파일이니 그렇다 치고 ai파일 읽어 들이는 것도 잉크스케이프에서는 문제가 없어서 간단한 작업에는 크게 문제가없습니다.

 

그래서 잉크스케이프가 잘 쓰이는 곳이 있습니다.

 

보통 회사 로고들은 ai파일로 제공합니다. 하지만 그 로고를 도면에 넣으려면 어찌 되었든 AutoCAD형식으로 바꿔야 합니다. (LibreCAD는 PDF형태로 된 것을 바로 읽는다고 하지만 그것도 완벽하지 않습니다.) 특히 공개된 포맷인 DXF가 여기저기 편리합니다. 그래서 잉크스케이프로 ai파일을 읽은 다음 DXF로 변환해서 넣으면 도면에 깔끔하게 들어가지요.

 

그런데 회사에서 쓰기 위해 잉크스케이프 1.0을 쓰던 도중에 ai나 PDF로 만든 DXF가 오류나더군요. AutoCAD에서 읽히지가 않아서 LibreCAD로도 해봤는데 마찬가지로 오류가 났습니다.

 

방법을 몰라서 이리저리 옵션을 바꾸면서 수많은 오류를 경험하고 그냥 잉크스케이프 버전을 0.92로 낮추니까 잘 되네요.

그냥 ai파일을 잉크스케이프로 읽은 다음에 dxf형태로 변환하는 것으로도 아무 문제가 없습니다.

아무래도 동봉된 Python이 문제된것이 아닐까 싶은데 잉크스케이프 0.92버전은 Python2.7을 사용하고 이후 버전은 Python3를 사용합니다. 그리고 저는 Python3을 버전별로 깔아두고 쓰고 있지요. (32비트, 64비트, 3.6 3.7 3.8...) 이게 원인일 가능성이 매우 높습니다.

 

리눅스야 시스템에 설치된 Python을 적극 활용하게 패키징을 하니 문제가 없지만 (정 안 되면 버전과 관련없이 쓸 수 있는 SNAP이 있지요.) 윈도우는 시스템에 Python을 추가로 설치하다보니 기존에 설치된 Python과 충돌이 난 듯 합니다.

 

예로부터 오픈소스 삼대장은 윈도우에서 성능이 그닥 잘 안나오긴 했는데 이번에 또 한번 실감하네요.

,

맑은 고딕은 굉장히 호평 받은 폰트입니다.

작아지면 잘 안보이고 크면 형상이 너무 구린 굴림과 다르게 작아도 잘 보이고 커도 글자 형태가 잘 보입니다.

 

그래서 애플 컴퓨터를 쓰는 사람들은 이를 엄청 부러워했었지요. 지금은 맑은 고딕과 비슷한 산돌 고딕이 들어갔지만요.

 

그런데 리눅스에선 Noto Sans(Source Han Sans)가 쓰이면서 UI는 신경을 아무도 쓰지 않아도 될 정도가 되었습니다.

 

그래서 맑은 고딕이 없던 XP 이전 시절에 일부 프로그램에서는 나눔바른고딕이나 Noto Sans를 내장해서 만들기도 하지만 윈도우에는 이미 맑은 고딕이라는 걸출한 기본 폰트가 있다보니 이젠 맑은 고딕을 다들 적극적으로 씁니다.

 

문제는... Wine에서 이런 프로그램을 쓰려고 하면 맑은 고딕이 없으니 대체 폰트를 써야 한다는 겁니다. 그런데 굴림시절에도 그랬는데 여기서도 맑은 고딕을 하드코딩 해버리는 만행을 저지르는 일이 일상적입니다. 대표적인 것이 카카오톡...입니다.

 

나눔고딕을 설치하면 나눔고딕이 맑은 고딕을 대체 할 수 있지만 이것조차 완벽하지 않지요.

그.래.서.

https://moordev.tistory.com/176

 

굴림 날리고 나눔고딕으로 대체하기

http://moordev.tistory.com/175 이 포스팅 바로전에 슬픈 굴림이야기라는 포스팅을 잠시 했었습니다. 내용은 대충 Wine으로 실행 되는 프로그램중에 굴림을 지정해서 사용하는 경우가 있으며 해당 프로

moordev.tistory.com

나눔고딕으로 가짜 굴림을 만들어서 대체했던 것처럼 Spoqa Han Sans(Noto Sans기반의 경량화 폰트)를 기반으로 가짜 맑은 고딕을 만들어서 이를 대체해 보는 것이지요.

 

방법은 굴림때와 똑같이 만들었으니 설명은 따로 안 하겠습니다.

malgun.ttf.7z
9.74MB

이 파일이 바로 이름은 맑은 고딕인데 내부는 Spoqa Han Sans인 폰트입니다. 이걸 설치하면 Wine 프로그램에서 하드코딩된 프로그램도 한글이 잘 뜨게 될겁니다.

 

그리고 NotoEmoji-Regula도 추가해 넣어서 이모지도 잘 뜨게 될겁니다. (다만 컬러 이모지가 아닌 흑백 이모지입니다.)

 

이런 가짜 폰트들이 많아지는게 좋은 일은 아니지만 그래도 쓸 수 있다는게 얼마입니까.

,

이전에 scrcpy를 유용하게 쓰고 있다는 이야기를 했었습니다.

https://moordev.tistory.com/323

 

scrcpy로 우분투에서 안드로이드 스마트폰 미러링하기

우분투에서 안드로이드 게임을 하거나 안드로이드 에뮬레이터를 돌리는 것은 꽤나 어렵습니다. 기껏해야 Genymotion정도가 안드로이드를 돌리는데 겨우 쓸만합니다. 그리고 대부분 안드로이드 게

moordev.tistory.com

 

실제로 미러링임에도 딜레이가 적었으며 디버그 모드를 활성화 해서 PC를 기억해두면 연결후에 바로 화면이 뜨는 등 매우 편리한 프로그램이었습니다.

 

그런데 사용하고 있는 PC가 아니라 오래된 랩탑에 scrcpy만 설치해서 필요에 따라 스마트폰 화면을 띄우는 독으로 만들면 어떨까라는 생각을 했습니다.

 

비슷한것으로 삼성Dex가 있고 더 옛날로 돌아가면 모토로라의 아트릭스가 있겠네요.

일단 Dex나 아트릭스나 있으면 좋겠지만 삼성 휴대폰이 아니더라도 넓은 화면으로 스마트폰을 쓰고 싶은 사람들도 있을 것이고 외부 모니터를 지원하지 않는 휴대폰도 있을 것이며 때에 따라서는 HDMI모니터 대신 오래되서 버려진 랩탑을 사용하는 또다른 방법이 될 수도 있겠다는 생각을 했습니다.

 

우선 만들어진 이미지는 

https://drive.google.com/file/d/1McZMh8MxRRkGEghZtrtM52wuuOyduZ1Y/view?usp=sharing

 

custom-live.iso

 

drive.google.com

여기서 다운로드 받을 수 있습니다. Debian 10 Buster 기반이고 필요에 따라 Debian 11 Bullseye의 패키지 일부를 백포트해서 설치했습니다.

MD5 2e2118cf81dcd620547bc14505a9a288 

 

해당 이미지를 balenaEtcher로 USB에 굽거나 CD로 구워서 PC로 부팅합니다.

 

그리고 디버그 모드가 설정된 안드로이드 휴대폰을 USB로 연결하면 끝입니다. 디버그 모드 설정은 여기서 굳이 설명 안 해도 찾아보면 많이 나오니 따로 설명은 안 하겠습니다. 참고로

https://4343282.tistory.com/267

 

USB디버깅 모드) 안드로이드 개발자 옵션 활성화 하기

 USB디버깅 모드는 프로그램을 개발하는 개발자, 마케팅을 진행하는 마케터들에게는 필수 기능입니다. 안드로이드 기기에서 기본적으로 제공하는 '안드로이드 개발자 옵션(USB 디버깅 모드)'를

4343282.tistory.com

여기 자세히 나와 있네요.

 

그러면..

https://youtu.be/QGEC9VW_tjM

이렇게 쓸 수 있습니다. 여기에 몇가지 단축키를 알아두시면 더 편리합니다.

 

왼쪽 Alt + O = 스마트폰 화면 꺼짐

왼쪽 Alt + Shift + O = 스마트폰 화면 켜짐

왼쪽 Alt + P = 전원 버튼

왼쪽 Alt + R = 화면 돌리기

왼쪽 Alt + 방향키 위아래 = 볼륨 조절

왼쪽 Alt + H = 홈버튼

마우스 오른쪽 버튼 = 뒤로가기

Ctrl+드래그 = 핀치투 줌

 

자세한 내용은 SCRCPY 설명서를 참조 하시면 됩니다.

 

이런 만드는 방법은 다음과 같습니다.

Virtualbox를 준비합니다.

Debian을 Virtualbox에 설치합니다.

설치가 끝난 뒤에 Debian에 xorg, nodm, openbox, adb, scrcpy 를 설치합니다. (scrcpy는 bullseye 이상에서 제공합니다. 그러므로 Debian 11 이상 사용을 추천)

/etc/default/nodm 파일에 

 

NODM_USER = "설치할때 정한 로그온계정"

 

이것을 안 하면 root로 로그인 되어버립니다. 보안상 문제가 있겠지요.

 

/etc/xdg/openbox/autostart

파일을 열고 마지막줄에 다음과 같이 적습니다.

 

while :; do adb wait-for-device && scrcpy; done

 

이제 openbox의 단축키를 일부 수정합니다.

/etc/xdg/openbox/rc.xml 파일을 수정합니다.

 

<keyboard>

  <keybind key="XF86PowerOff">

    <action name="Execute">

      <command>sudo shutdown -h now</command>

    </action>

  </keybind>

</keyboard>

 

<keyboard> 안을 이것으로 바꿔버립니다. (단축키 충돌 방지를 위함)

 

그리고 shutdown 시 암호를 묻지 않게 하기 위해서

(참고 : https://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/)

 

sudo visudo

%sudo ALL = NOPASSWD: /sbin/shutdown

 

위 내용을 추가합니다.

 

이제 이것을 LinuxRespin을 사용해서 백업합니다.

cd /tmp

wget gitlab.com/remastersys/LinuxRespin/-/raw/master/respin_4.0.0-2_all.deb

sudo dpkg -i respin*.deb

sudo apt install -f

 

이제 백업을 합니다.

 

sudo respin backup

(backup대신 dist를 해도 되나 nodm이 오류 날 수 있음)

이제 /home/respin/respin에 iso파일이 하나 있을 겁니다. 이것은 표준 iso이므로 이걸 하이브리드 iso로 만들어서 USB에 바로 심을 수 있게 만듭니다.

 

sudo apt-get install syslinux isolinux syslinux-utils syslinux-efi
cd /home/respin/respin

isohybrid *.iso

이제 해당 iso파일을 VM밖으로 꺼내와서 사용하면 끝. (VM밖으로 꺼내는 것은 네트워크를 사용하던지 아니면 알아서 하시면 됩니다.

,

라즈베리파이는 작은 컴퓨터입니다.

그리고 성능은 그 크기에 걸맞게 그리 좋지 못하지요.

 

하지만 그럭저럭 좋은 성능에 굉장히 저렴한 가격으로 쓸만한곳이 상당히 많습니다.

 

이전에 저는 Tacotron으로 무언가를 하나 만들었습니다. 어찌되었건 이를 다시 서빙해야 했는데 코드는 python의 기본 적인 웹서버로 웹페이지에서 받아볼 수 있게 어찌저찌 만들었습니다.

 

tacotron의 오픈소스를 만든 keithito의 demo_server 소스를 이용해서 hccho2의 한국어 tacotron을 데모를 쓸 수 있게 어찌저찌 잘 수정했습니다.

https://github.com/MoorDev/Tacotron2-Wavenet-Korean-TTS/blob/master/run.py

 

그런데 이걸 서비스할 방법이 마땅치 않습니다. 무료로 유명한 구글의 컴퓨트 엔진을 쓰려고 했는데 RAM이 모자란 탓인지 자꾸 멈춥니다. 심지어 pip도 제대로 안 되더군요.

 

서버를 구축하려면 pip freeze 된 것을 다시 설치해야 하는데 이거 자체가 안 되니 환장할 노릇입니다.

 

그래서 제 옆에 있던 라즈베리파이에 한번 넣어보기로 했습니다. 그래도 ARM칩셋이지만 램도 어느정도 충분하고 학습이 아닌 결과물만 뽑으면 되는 것이니까요.

 

 

우선 제가 개발한 파이썬 환경을 Freeze 합니다.

 

개발및 학습 PC에서

pip freeze > requirements.txt

 

그리고 만들어진 requirements.txt는 다른 곳에서 쓸 때도 그대로 환경을 구축하는데 쓰이게 됩니다. 

 

그 다음 라즈베리파이에 OS를 설치합니다.

이건 제가 따로 말 안 해도 방법이 워낙 많으니까 넘어갑니다. 대신 ssh를 활성화 해야 하는건 잊으면 안 됩니다.

ssh 활성화는 구운 SDCARD에 boot파티션에 ssh란 파일이름으로 아무 파일이나 하나 만들어주면 됩니다.

무선인터넷을 바로 잡는 법은 역시 boot파티션에 wpa_supplicant.conf 라는 이름으로 

내용을 다음과 같이 적으시면 됩니다.

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="공유기이름"
    psk="공유기비밀번호"
}

왜 국가가 US로 되어 있냐면 KR로 하니 라즈베리파이가 못 잡습니다. 그래서 그냥 호환되는 US로 했습니다. 일단 잡히면 되는거지요.

 

그 다음 개발환경이자 Python 폴더 자체를 통째로 넣어줍니다. 보통 Tensorflow 개발 PC는 리눅스고 라즈베리파이OS도 리눅스이니 충분히 복사가 가능할 것입니다.

 

이걸 통째로 SDCARD에 넣어줘야 합니다. 만약 필요하면 경로도 최대한 같게 해주는 것이 중요하지요.

 

그리고 라즈베리파이를 부팅하면... SSH로 접속할 수 있게 됩니다. IP주소를 모르겠다면 공유기설정에서 찾던가 아니면 다른 방법을 찾아야 합니다.

ssh pi@라즈베리파이주소

기본 비밀번호는 raspberry 인데 해킹 방지를 위해 꼭 sudo raspi-config에서 비밀번호를 바꾸는 작업을 해 줍시다.

 

이제 파이썬 버전을 맞추는 작업이 필요한데 제가 사용한 라즈베리파이OS는 데비안 10(Buster)기반입니다. 기본으로 Python 3.7을 사용합니다.

그에비해 저는 Python3.6을 기본으로 사용했습니다. 그래서 얼마나 다른가 봤는데... 예약어 차이정도라 크게 문제는 없을 정도네요. 그래서 그냥 쓰기로 했습니다. 만약 3.8이었다면 많이 차이나기 때문에 Python을 수동으로 설치하는 수고가 필요했을 겁니다.

 

그리고 requirements.txt를 사용해서 필요한 패키지를 설치합니다.

sudo pip3 install -r requirements.txt

 

이제 어마어마한 다운로드를 보일텐데 ARM칩과의 차이로 인해 일부 문제가 있었습니다.

 

저는 우선 LLVM문제가 일어났습니다. 데비안 Buster는 LLVM-7을 사용하는 반면 저는 LLVM-10을 사용했습니다.

그래서 LLVM-10을 설치했습니다.

 

그런데 수동으로 해야합니다.

https://releases.llvm.org/download.html

 

LLVM Download Page

If you'd like access to the "latest and greatest" in LLVM development, please see the instructions for accessing the LLVM Git Repository. The major changes and improvements that the development version contains relative to the previous release are listed i

releases.llvm.org

여기서 제 라즈베리파이는 ARM-32비트이므로 ARMv7을 선택합니다. 64비트 버전도 나오고 있으니 이를 확인해야합니다. 64비트라면 AArch64를 다운로드 받으세요.

라즈베리파이에서

wget github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-armv7a-linux-gnueabihf.tar.xz

tar -xvf clang*.xz

cd clang+llvm (탭)

sudo cp -R * /usr/local

 

이걸로 llvm-10의 설치를 끝냈습니다. 그러고나니 제일 중요한 Tensorflow가 문제가 생기더군요.

일단... 안 깔립니다. 원래 설치가 되어야 정상인데 간혹 거부가 일어나나 봅니다.

sudo pip3 install tensorflow==(원하는버전)

이걸로 설치가 되어야 정상이지만 설치가 제대로 안된다면

https://qengineering.eu/install-tensorflow-1.15.2-on-raspberry-pi-4.html

 

Install TensorFlow 1.15.2 on Raspberry Pi 4 - Q-engineering

A thorough guide on how to install TensorFlow 1.15.2 on your Raspberry Pi 4. Build from source code with Bazel for Python 3 and C++ API.

qengineering.eu

여기를 참고합니다.

 

sudo apt-get install libatlas-base-dev libatlas3-base

sudo apt-get install libhdf5-dev libc-ares-dev libeigen3-dev

sudo pip3 install h5py==2.10.0

wget github.com/Qengineering/Tensorflow-Raspberry-Pi/raw/master/tensorflow-1.15.2-cp37-cp37m-linux_armv7l.whl

 

sudo -H pip3 tensorflow-1.15.2-cp37-cp37m-linux_armv7l.whl

 

이걸로 Tensorflow 1.15.2를 구동할 수 있게 되었습니다.

 

그래서 결과는..?

 

잘 됩니다!!!

,

1. 제가 좋아하는 사람이 있습니다. 이 사람이 목소리 연기가 꽤 괜찮아서 어쩌다보니 목소리 데이터를 모을 수 있었습니다. 다만 쓸 만한 것이 다 합쳐서 2시간이 될까 말까 합니다.

 

2. 그리고 Tacotron이란 것이 있습니다. 딥러닝을 사용해서 일종의 TTS를 만드는 프로젝트인데 한국어 Tacotron이 오픈소스로 꽤 잘 나와 있습니다.

https://github.com/hccho2/Tacotron2-Wavenet-Korean-TTS

 

소스가 올라온지 2년 정도 되긴 했지만 제가 fork해서 일단 필요하면 계속 발전 시킬까 생각은 하고 있습니다. 기존 프로젝트에서 Requirement만 일단 모아놓고 추후에 가능하면 Tensorflow 2.x 로 가능할지 찾아보고 있습니다. 물론 제 성격상 언제 할 수 있을지 아무도 모릅니다.

 

3. KSS 데이터셋이라는 것이 있습니다. 한국어 음성 딥러닝을 공부하는 데에 있어서 정말 눈물나게 고마운 데이터입니다. 어떤 성우분인지 모르지만 12시간 분량의 문장을 녹음해 주었습니다.

https://www.kaggle.com/bryanpark/korean-single-speaker-speech-dataset

 

이걸 기반으로 음성인식도 하고 반대로 TTS도 만들고 하는데 쓰입니다. 연구소나 학교에서 정말 유용하게 쓰입니다. 대신

CC BY-NC-SA 4.0

이것 때문에 상업적인 이용은 불가능합니다.

 

그래서 위의 것을 다 합치면 무엇이냐...

 

Tacotron을 사용해서 제가 좋아하는 사람의 목소리를 TTS로 만들고 싶었습니다.

그래서 처음에는 제가 가지고 있던 2시간 분량의 좋아하는 사람의 목소리를 학습 시켜보았습니다.

결과는... 말을 하다 맙니다. 그래프를 보니 희미..합니다.

 

 

그래서 들어보니 한마디 나오려다가 옹알이를 합니다.

 

해결방법은 더 많은 학습데이터를 쏟아부으면 된답니다. 그런데 녹음을 부탁하기가 좀 껄끄럽습니다. 바쁠 수도 있고요.

그래서 다른 방법을 찾아보니 잘 만들어진 데이터셋과 함께 학습을 시키면 적은 데이터로도 괜찮은 품질이 나온다고 합니다.

 

그래서 Multi로 KSS데이터셋을 사용해 KSS와 그분의 목소리를 함께 학습을 시켰습니다.

 

결과는... KSS데이터셋으로 한 것만 멀정히 말합니다. 그런데 해당 학습 모델에서 KSS와 제가 모은 그분의 목소리가 섞이는 것이 보이더군요.

 

그분에게 제 TTS데이터를 보내봤습니다. 반응이 좋더군요. 자기 목소리랑 비슷하다고요.

근데...그거 KSS에 살짝 본인 목소리 데이터를 첨가한겁니다. (KSS12시간+그분2시간)

그래서 살짝 발상을 전환해서 제 데이터에 KSS데이터의 1시간분량을 첨가해봤습니다...

결과는... 꽤 만족스럽습니다. 전보다 발음도 괜찮고 일단 alignment는 잘 잡습니다. 대신 데이터셋을 새로 구성해서 처음부터 다시 학습 중입니다...

현재 데이터셋 설정
1. Multi-Speech
2. KSS Speech 12Hour
3. 그분+KSS 1hour

일단 현재는 만족

,

어마어마하게 작은 리눅스가 있습니다.

물론 작지만 그럭저럭 있을 것은 다 있습니다.

 

실제로 어마어마하게 작아서 GUI를 가진 이미지가 꼴랑 16MB입니다.

물론 16MB는 32비트용입니다. 64비트 버전도 있지만 이건 조금 용량이 큽니다.

http://tinycorelinux.net/

다만 역시 이것저것 없는 만큼 우분투 수준의 편리함은 없습니다.

그리고 패키지 매니저를 tce라는 별개의 것을 쓰다보니 호환성이 조금 떨어집니다.

 

하지만 이 정도면 똥컴의 희망이라 할 수 있습니다. 컴퓨터가 아직 죽지 않을 수 있는데 이것저것 안 돌아간다고 버릴 수는 없잖아요?

 

그래서 이 녀석을 써보기로 했습니다.

 

그리고 이렇게 작은 것은 그냥 쓰기 힘드니 약간의 커스터마이징으로 이것저것 추가한 다음 쓰는 것이 좋습니다.

https://github.com/elazarl/customize_tinycorelinux

 

elazarl/customize_tinycorelinux

Scripts to easily customize a tinycorelinux ISO. Contribute to elazarl/customize_tinycorelinux development by creating an account on GitHub.

github.com

여기 있는 스크립트를 이용하면 파일을 추가하고 이리저리 삽질하면 뭐라도 만들어 질 수 있겠지요.

대신 그만큼 고생은 하겠지만 이 정도면 상당히 훌륭합니다.

 

문제는 역시....이것만 가지고 뭘 하기가 어렵다는 것이겠네요.

 

우분투 환경에서 한번 Tiny Core Linux의 커스터마이징을 해봅시다.

 

우선 Tiny Core Linux의 iso파일을 다운로드 받습니다. 저는 Core버전 16MB짜리를 다운로드 받았습니다.

http://tinycorelinux.net/downloads.html

 

Downloads Tiny Core Linux

The Core Project, as suggested by our name, is not a turnkey desktop distribution. Instead we deliver just the core Linux from which it is quite easy to add what you want. We offer 3 different x86 "cores" to get you started: Core, TinyCore, and our install

tinycorelinux.net

그리고 다음 스크립트를 다운로드 받아서 압축을 풀어 놓습니다.

스크립트를 압축 푼곳에 다운로드 받은 ISO파일을 함께 위치 합니다.

 

그러면 이렇게 되겠지요.

 

그리고 터미널에서 이 위치에 들어 온다음 다음과 같이 명령을 칩니다.

tinycore-extract.sh TinyCore-current.iso

이러면...

 

이렇게 iso와 core라는 폴더가 만들어집니다.

이제 core쪽을 건드려서 이것저것 추가하고 다시 tinycore-repack.sh를 실행하면 커스터 마이징이 됩니다.

 

대신 Debian처럼 편리하게 패키지가 설치되는 것이 아니다보니 좀 어렵습니다.

 

그래서 Debian의 것을 TCZ화해서 가져오는 경우가 많더군요. 물론 이것도 녹록치는 않긴 합니다...

 

개인적으로 scrcpy를 실행시켜서 안드로이드 화면을 지속적으로 미러링 하는 것을 만들고 싶은데 이게 맘처럼 잘 안 되네요.

,

이 게임을 기억하시는 분이 있으려나 모르겠네요.

 

분명 이름은 쿠키샵인데 쿠키는 절대로 안 파는 경영게임 "쿠키샵"입니다. 그런데 이거 정말 오래된 게임인데 지금해도 꽤 난이도가 있습니다. RPG요소가 같이 섞여 있다보니 전투도 치뤄야하고 손님이 오면 후다다닥 처리도 해야하고 할일이 엄청 많습니다. 이걸로 마우스를 꽤나 망가뜨린 경우가 많다고 하네요.

 

PlaynLinux를 이용했고 Wine 5.7을 사용했습니다. 워낙 오래된 게임이라 딱히 설정은 필요없었습니다.

 

단 하나... 시디롬 인식이 잘 안 되서 gCDemu를 설치한 후에 gCdemu에서 iso 이미지를 마운트 했습니다.

이전에 프린세스 메이커3때도 그랬지만 이 당시에는 시디롬을 잘 활용했었습니다. 덕분에 시디가 없으면 안 돌아가는 경우가 많았습니다. 그런데 쿠키샵은 일단 시디롬이라고 인식되기만 하면 어찌되었든 돌아가서 복제방지가 허술한 축에 속합니다. 그리고 640x480으로 돌리니 상당히 눈이 아프네요. 이미 회사가 망해버려서 다시 리마스터링 한다거나 할 수도 없겠지요.

,

이전에 scrcpy를 써서 딜레이가 거의 없는 안드로이드 화면 미러링에 관하여 설명한 적이 있습니다.
https://moordev.tistory.com/323

그런데 PC야 원래 성능이 좋으니까 사실 wifi를 사용한 방법으로도 충분한 경우가 많습니다. 하지만 이보다 성능이 떨어지는 SBC(Single Board Computer)라면 어떨까요? 과연 이걸로도 scrcpy로 안드로이드 스마트폰 화면을 미러링 할 수있을까요?

그래서 한번 SBC의 가장 대표적인 보드인 라즈베리파이를 이용해봤습니다.

이번에 사용할 보드인 라즈베리파이3 B+ (쓴지 몇년 되었습니다.)와 저렴한 Waveshare사의 3.5inch LCD (A) 입니다.LCD는 그냥 라즈베리파이의 GPIO에 맞게 끼우면 바로 작동 됩니다.

물론 작동 된다는 것이지 바로 사용이 가능한 것은 아닙니다. 몇가지 설치절차가 필요합니다. 지금은 그냥 하얀 화면만 나올 뿐입니다.

우선 RaspberryPi OS가 설치된 SDCARD가 필요합니다. 이건 워낙 여기저기에서 방법을 잘 알려주고 있고 라즈베리파이를 본격적으로 쓰시는 분들이라면 이미 다들 알고 계시겠지요.

그리고 LCD에 바로 화면이 뜨지 않기 때문에 SSH를 활성화 하거나 HDMI 모니터와 USB키보드를 준비해야합니다. 저는 그냥 SSH를 활성화 한다음 유선랜을 공유기에 꽂아서 라즈베리파이에 접속했습니다.

SSH를 활성화 하는 방법은 간단합니다. RaspberryPi OS가 설치된 SDCARD를 PC에 꽂으면 boot라고 써있는 디스크가 보입니다. 여기에 SSH 라는 이름을 가진 파일을 하나 만들면 바로 SSH가 활성화 됩니다.

그 다음 SSH로 라즈베리파이에 접속합니다.

ssh pi@192.168.0.xx (192.168.0.xx는 라즈베리파이의 IP주소입니다. 공유기에 접속해서 확인 할 수있습니다.)
yes를 친다음 패스워드는 raspberry

기본 패스워드이니 sudo raspi-config 명령을 사용해서 이것저것 설정을 하고 이제 본격적으로 LCD에 화면을 띄워봅시다.

라즈베리파이를 설치하고 가장 먼저 해야할 것은 패키지 업데이트이고 그 다음이 바로 이 설정이다.

저는 waveshare사의 LCD를 사용했지만 Adafruit사의 것을 사용하시거나 기타 다른 업체를 이용하신다면 또 달라질 수 있습니다.

우선 해야할 것은 매뉴얼을 읽는 것입니다.
https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A)

3.5inch RPi LCD (A) - Waveshare Wiki

Introduction 3.5 inch Touch Screen TFT LCD Designed for Raspberry Pi Getting Started Hardware Connection There are 40 pins on Raspberry Pi but only 26 pins on the LCD, so you should pay attention to connecting the pins to your Pi accordingly. Install the t

www.waveshare.com

여기 보면 드라이버 설치방법이 써 있습니다. 드라이버를 이미 git을 통해 제공하고 있군요.
git clone https://github.com/waveshare/LCD-show.git

waveshare/LCD-show

Contribute to waveshare/LCD-show development by creating an account on GitHub.

github.com

cd LCD-show

이제 여기서 자신의 LCD에 맞는 것을 찾습니다. 저는 3.5인치 LCD A버전이므로 LCD-35입니다. 만약 LCD B버전이거나 다른 크기의 LCD라면 다른 것을 찾아야 합니다. 역시 매뉴얼을 보면 자세히 나와있으니 이를 이용하면 됩니다.

우선 실행옵션을 줘야하므로
sudo chmod +x LCD35-show
./LCD35-show

이러면 이제 필요한 소스를 다운받고 빌드를 해서 드라이버를 설치합니다. 그리고 자동으로 라즈베리파이가 부팅되는데 LCD에 X가 짠하고 뜹니다! 그리고 터치도 되므로 터치펜이나 손가락으로 꾹꾹 누르면 진행이 됩니다.

그냥 한번 화면을 90도로 돌려보았다. 그러니까 터치 좌표가 꼬인다...

이제 라즈베리파이 화면을 띄우는데에 성공했으니 한번 scrcpy를 빌드해봅시다.

우선 이 링크의 것을 참조했습니다. https://gist.github.com/RubenNL/e259f145371d2c16a3932fa39aa9a775

Install scrpy

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

그냥 scrcpy의 가이드대로 빌드하면 Android SDK가 필요한 경우가 있는데 Android SDK는 ARM위에서 돌아가지 않습니다. 따라서 미리 빌드된 것을 사용해야합니다.

우선 라즈베리파이에 접속을 한 후에

sudo apt install git wget meson libavformat-dev libsdl2-dev adb

위 명령으로 필요한 것을 설치합니다. 보통 libsdl2와 libavformat, adb만 설치하고 나머지는 이미 있을 가능성이 높습니다.

그리고 필요한 것을 다운로드 받습니다.
2020년 현재 최신 버전은 1.16버전이므로 이것을 사용합니다.

wget https://github.com/Genymobile/scrcpy/archive/v1.16.tar.gz
tar -zxvf v1.16.tar.gz
cd scrcpy-1.16
wget https://github.com/Genymobile/scrcpy/releases/download/v1.16/scrcpy-server-v1.16
meson x --buildtype release --strip -Db_lto=true -Dprebuilt_server=scrcpy-server-v1.16

이제 빌드를 위한 준비가 시작됩니다. 그리고 준비가 완료되면
ninja -Cx

이제 빌드가 될텐데 오류가 난다면 위의 사전설치 패키지를 확인해주시기 바랍니다.
빌드가 끝나면 인스톨

sudo ninja -Cx install

이제 안드로이드 스마트폰과 라즈베리파이를 USB로 연결하고 라즈베리파이에서 scrcpy 명령을 내리면 스마트폰 화면이 창으로 뜰겁니다. 대신 화면도 작고 창크기도 작은데다가 라즈베리파이의 성능 문제도 있다보니 매우매우 느립니다.

그리고 저는 라즈베리파이를 스마트폰 화면 미러링 전용으로 쓸 생각이라 이것을 scrcpy를 서비스로 등록해서 사용할 생각입니다. USB에 디버깅 옵션이 켜진 스마트폰이 연결되면 바로 화면을 띄우는 것이지요.

다시 라즈베리파이에서 터미널을 엽시다.
sudo nano /etc/systemd/system/scrcpy.service


이제 새로운 텍스트 에디터가 뜰텐데 다음과 같이 입력합니다.

더보기

[Unit]

Description=Start SCRCPY Android Screen

[Service]

Type=simple

User=pi

ExecStart=/usr/local/bin/scrcpy -b2M -m480 --max-fps 10 -f --rotation 1 -n

#Restart=always

Restart=on-failure

[Install]

WantedBy=graphical.target

#WantedBy=multi-user.target

위 명령 중에서 -b2M은 영상 비트레이트를 2M까지만 -m480은 최대 480p --max-fps는 10프레임 이하로 --rotation 1은 화면을 90도 돌리라는 의미입니다. 저는 주로 세로화면을 쓰기 때문에 이렇게 했습니다.

저장을 위해 Ctrl+O 그리고 엔터
이제 파일을 저장했으면

sudo systemctl daemon-reload
sudo systemctl enable scrcpy.service

위 명령어로 서비스에 등록합시다. 이제 USB로 스마트폰이 연결될때까지 라즈베리파이는 계속 연결을 시도할 것입니다.


그냥저냥 쓸 만한 속도가 나오네요. 제 보드는 라즈베리파이3니까 라즈베리파이4 이상이라면 fps를 높여서 더 빠르고 완벽한 속도를 보일 수 있을겁니다.

이제 필요하면 https://gitlab.com/larsfp/rpi-readonly

Projects · Ways / rpi-readonly

Make raspberry pi raspbian file system read-only

gitlab.com

여기의 것을 사용해서 SDCARD에 쓰기를 못하게 만들 수도 있습니다. 이러면 갑자기 Raspberrypi가 멈춰서 다시 시작해야 하는 일이 생기더라도 SDCARD를 보호 할 수 있습니다.

,