알라딘MGG와이드바


Python 으로 펜타토닉 스케일 위치 구하기 개발 이야기

얼마 전에 기타 솔로가 어떤 펜타토닉 스케일로 되어 있는지를 알고 싶어서
플랫보드를 프린터해서 노트를 손으로 그려가며 펜타토닉 CAGED 모양을 비교해서 겨우 G minor 를 찾았다.


찾고 나서 보니 b 가 2개 붙어 있는 곡이라 Bb 장조 혹은 G 단조일테니 G minor 펜타토닉부터 찾아보면 빨랐겠지만
조성을 모른 상태로 펜타토닉 스케일을 좀더 쉽게 찾을 방법이 없을까 해서 파이썬으로 간단하게 만들어 보았다.
솔로 노트를 있는대로 입력하면 12개의 마이너 스케일과 얼마나 유사한지를 출력해 준다.
예외 처리 같은 건 생략한다. 나중에는 모드나 코드톤 같은 것도 분석해 주면 좋을 거 같다.
(여기까지 쓰고 보니 Guitar Pro 에 이런 비슷한 기능이 이미 있을 거 같다.)
(그리고 어느 정도 수준에 이르면 귀로 듣자마자 스케일을 알 수 있겠지. 이런 코드를 계속 쓰고 있으면 사실 안 되는 거다.)

from itertools import combinations

# A C D E G(0, 3, 5, 7, 10)
pentatonics = [0, 3, 5, 7, 10]
note_array = ['A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab']

# 입력값을 정리한다. (중복 제거, sort)
def GetInput():
while True:
input_str = input("Input 4~7 different notes as number. ex. A C D E Gb\ninput: ")
input_notes = [x for x in input_str.split(' ')] # 입력값을 list 로 만들기
input_notes = list(dict.fromkeys(input_notes)) # 중복 제거
input_notes.sort()
if len(input_notes) >= 4 and len(input_notes) <= 7:
return input_notes
else:
pass

# 12 개의 minor 펜타토닉 데이터를 준비한다.
def ReadyPentatonicData():
pentatonic_notes = []
for i in range(12):
p = [(a + i) % 12 for a in pentatonics]
p.sort()
p_note = [note_array[a] for a in p]
pentatonic_notes.append(p_note)
return pentatonic_notes

# 유사도 구하기
def CalcSimilarity(input_notes, index, penta_data):
input_notes_comb = combinations(input_notes, min(len(input_notes), 5)) # 최대 5개의 조합을 찾은 뒤
max_sum = -1
max_sum_list = []
for in_notes in list(input_notes_comb):
s = sum([1 for i, j in zip(in_notes, penta_data) if i == j]) # 노트가 몇 개 일치하는가 구하고 가장 많이 맞는 값을 출력한다.
if s > max_sum:
max_sum = s
max_sum_list = in_notes
print(note_array[index], "minor:", penta_data, " input:", max_sum_list, "Similarity:", max_sum / 5.0 * 100.0, '%') # 같은 아이템이 몇 개 있는가

def main():
input_notes = GetInput()

pentatonic_notes = ReadyPentatonicData()

for index in range(len(pentatonic_notes)):
penta_data = pentatonic_notes[index]
CalcSimilarity(input_notes, index, penta_data)

if __name__ == "__main__":
main()


결과는 다음과 같다.


Python 으로 타이타닉 승객의 생존율 구하기 개발 이야기

요근래 새로 파이썬 공부하면서 알게 된 문제. 찾아보니까 Kaggle 관련해서 이미 유명한 문제인 거 같다.

타이타닉 승객 데이터 csv 데이터는 여기에서 찾을 수 있다.
https://raw.githubusercontent.com/TeamLab/machine_learning_from_scratch_with_python/master/code/ch12/titanic/train.csv

1, 2, 3 등석에 탑승한 남, 여 승객은 각각 몇 % 생존했는가를 구하는 코드다.

import numpy as np
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/TeamLab/machine_learning_from_scratch_with_python/master/code/ch12/titanic/train.csv')
print(df.pivot_table(index='Sex', columns='Pclass', values='Survived', aggfunc=np.mean), "\n")

# Pclass 1 2 3
# Sex
# female 0.968085 0.921053 0.500000
# male 0.368852 0.157407 0.135447


생존률이 여성은 96%, 92%, 50%, 남성은 36%, 15%, 13% 라고 한다.
처음 타이타닉 영화 봤을 때는(그게 1997년이었네. 아련하다.) 어떤 기분이었는지는 기억이 안 나는데
지금은 세월호 때문에 이 영상을 보고 있기가 힘들다.
죽음을 눈앞에 두고도 의연한 모습을 보인 그 시대 사람들에게 존경을 보낸다.

Cubase drm xml 포멧 파일을 단순한 text 포멧으로 변경하는 python 코드 개발 이야기

저는 Cubase 에서 EZDrummer 와 Battery4 를 AKAI MPD218 에 매핑해서 쓰고 있습니다.
MPD218 Editor 는 미디 노트를 원하는 패드에 연결해 쓸 수 있는데,
드럼 가상악기들이 어느 미디 노트에 어떤 소리가 들어있는지 그다지 친절하게 표기하지 않아 어려움이 있습니다.

다행히 steinberg 포럼에서 EZdrummer 와 SD3 용 drum maps 을 구했는데 xml 포멧이 보기 쉽지 않더군요.

Python 3.8 (32bit) 에서 BeautifulSoup 를 이용해서 간단하게 xml 포멧으로 되어 있는 drm 파일을 단순화하는 코드를 만들었습니다. 어디 올릴만한 코드도 아니어서 블로그에 간단하게 기록 남깁니다.
Console 인자로 폴더 패스를 " " 로 묶어서 실행하면 그 폴더에 있는 모든 .drm 파일을 .drm.txt 파일로 convert 합니다.

# converting Cubase .drm file info text file for AKAI MPD218

import sys
import pathlib
from os import listdir
from os.path import isfile, join
from bs4 import BeautifulSoup

def ConvertDrm(filename):
print("Converting : " + filename)
with open(filename, "r") as infile:
with open(filename + ".txt", "w") as outfile:
contents = infile.read()
soup = BeautifulSoup(contents, 'xml')
item_listmap = soup.find('list', {"name": "Map"})
items = item_listmap.find_all('item')
for item in items:
inotes = item.find_all('int')
midi_note = -1
for inote in inotes:
if inote["name"] == "INote":
midi_note = int(inote["value"])
break

if midi_note == -1:
print("midi_note not found")
continue

name_tag = item.find('string')
midi_name = name_tag["value"]
if len(midi_name) == 0:
continue

midi_note_origin = midi_note - 12 # C0
octave = (midi_note_origin // 12) # AKAI 는 midi note 36 이 C2 다.
midi_note_alphabet_index = midi_note_origin % 12
midi_note_name = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']

outfile.write(str(midi_note) + "(" + midi_note_name[midi_note_alphabet_index] + str(octave) + ") " + midi_name + "\n")

def main(path):
fullpaths = [join(path, f) for f in listdir(path)]
drm_files = [f for f in fullpaths if isfile(f) and pathlib.Path(f.lower()).suffix == ".drm"]
for f in drm_files:
ConvertDrm(f)

if __name__ == '__main__':
main(sys.argv[1])


EA 피파 개발자가 말하는 “피파는 어떻게 위닝을 꺾었나” - ㅍㅍㅅㅅ 이승환님의 글입니다. 게임 이야기

출처 : 이승환 ㅍㅍㅅㅅ 페이스북

EA 피파 개발자가 말하는 “피파는 어떻게 위닝을 꺾었나”… EA 캐나다 외국인 노동자 허두회 (Dewey Hur) 님으로부터 재미있는 이야기를 들어서 공유. 라이선스 때문이라고만 생각했는데, 그보다는 디테일의 차이였다.

1. 혼이 담긴 노가다, 페이스온

가장 강조한 부분. 선수들 얼굴은 star head와 generic head로 나뉜다. generic head는 걍 데이터 가지고 피부색, 얼굴, 눈동자 등을 설정한다. 반면 star head는 예술이자 노가다이다. 아티스트 1명이 1주일을 써야 1명의 star head가 나온다. 골 넣으면 클로즈업되는데, 여기에서 리얼함이 엄청 갈린다. 그래도 한 번 만들면 은퇴할 때까지 써먹을 수 있다. EA가 이 돈 드는 노가다를 죽어라 할 때 코나미는 거의 돈을 안 들였다. 그래서 골 넣으면 밋밋하다. 스포츠는 디테일이 생명이다.

2. 기타 노가다…… 리얼함을 위한 혼…

선수 뿐 아니라 감독, 심판도 이름 좀 있는 사람이면 모델링한다. 심지어 대시보드까지 계약한다. 피파의 EPL 게임 화면은 실제 경기 중계 UI와 완전히 동일하다. 선수 소개, 스탯, 점수… EPL 심판들 보면 EA 로고 달고 있다. EA가 스폰서십을 맺고 화면을 제공하기 때문이다. 이런 디테일 하나하나가 다 몰입감과 연결된다.

3. 라이선스는 2차판권이다

라이선스는 좀 귀찮아도 로컬패치로 어떻게 할 수 있는 부분이다. 지금 와서 코나미가 피파(축구단체)와 단독계약해도 피파(게임)가 밀리기는 힘들다. 위에서 설명한 노가다 디테일 차이가 매우 크기 때문이다. 오히려 EA는 그 라이선스를 다른 회사에 파는데 쓴다. 이를 통해 몇몇 소수의 돈 있는 회사로부터 비용을 받고, 그들과 함께 경쟁자 진입을 막는다.

4. 엔진, 엔진, 엔진

2017부터 FIFA는 기존 엔진 Ignite를 버리고 Frostbite를 썼다. Ignite는 축구경기장에 최적화된 엔진이었지만 Frostbite는 범용이다. 져니(스토리모드)를 제대로 구현하기 위해서는 집, 컨퍼런스 홀 등도 표현해야 했기에 엔진을 교체해야 했다. 이런 디테일로 져니 모드 몰입감도 높아진다. 그리고 축구는 야구나 농구와 달리 22명이 동시에 뛰기 때문에 엔진빨이 꽤 중요하다. 렌더링은 쫓아가도 공의 움직임에 리얼하게 모든 선수가 반응하려면 엔진이 뒤따라줘야 한다.

5. 무슨 일이 있어도 FIFA를 적극적으로 민 EA

나름 경쟁자 소리 들을 때 위닝은 폭스엔진이 폭망했다. 이후 예산이 줄고 게임 퀄리티가 낮아지는 악순환이 일어났다. 반면 EA는 피파가 되든 안되든 본사에서 철저하게 밀어줬다. FIFA17은 당장 엔진 교체하느라 바빠서 좀 빵꾸가 많았지만, FIFA18에서 그 결실을 봤다.


Unreal4 에서 PVS-Studio 사용하는 방법 개발 이야기

라이센스 파일 등록
  • PVS-Studio.lic 파일을 '%USERPROFILE%\AppData\Roaming\PVS-Studio' 폴더에 둔다. 'PVS-Studio|Options|Registration' 페이지에 있는 것처럼 첫 번째 줄에는 이름, 두 번째 줄에는 Key 를 입력한 뒤 UTF-8 인코딩으로 저장한다.
  • UE4.20 부터는 따로 라이센스 파일을 폴더에 넣지 않아도 분석 가능하다고 한다.
CLMonitor
  • c:\Program Files (x86)\PVS-Studio\ 에서 관리자 권한으로 cmd 실행한 뒤 CLMonitor.exe 를 실행한다.
  • Visual Studio 에서 빌드를 실행한다.
  • Compiler invocations detected: 숫자... 가 보이는 걸 확인한다.
  • 빌드가 끝나면 다른 콘솔창을 관리자 권한으로 열어서 c:\Program Files (x86)\PVS-Studio\ 에서 CLMonitor.exe 를 다음과 같이 실행한다. (클라이언트 모드로 실행) CLMonitor.exe analyze -l "c:\Data\ptest.plog" -d c:\Data\monitoring.zip (폴더 위치는 아무 곳이나 상관없으나 c:\ 에 했더니 경로에 대한 액세스가 거부되었습니다라는 에러와 함께 아무런 데이터가 export 되지 않았으므로 주의.
  • Analysis complete (숫자/전체숫자): 파일.cpp 로그가 전부 출력될 때까지 기다린다.
  • VisualStudio -> PVS-Studio -> Open/Save -> Open Analysis Report... -> *.plog 파일 선택.
일반 빌드
  • Properties -> Configuration Properties -> NMake (Build Command Line / Rebuild All Command Line) 에서 맨 뒤에 -StaticAnalyzer=PVSStudio 플래그를 추가한 뒤 빌드한다.


1 2 3 4 5 6 7 8 9 10 다음


Yes24위대한게임의탄생3

위대한 게임의 탄생 3
예스24 | 애드온2