데이터 관리
modernGraphTool에 표시할 측정 데이터(Phone)와 타겟 커브(Target)를 다루는 방법을 안내합니다.
데이터 목록은 data/phone_book.json으로 관리합니다. 경로를 따로 바꾸지 않았다면 측정 데이터 파일은 data/phones에, 타겟 커브 파일은 data/target 폴더에 들어갑니다.
modernGraphTool은 CrinGraph와 같은 데이터 구조를 그대로 따릅니다. 기존 CrinGraph 사용에 익숙하다면 이 페이지는 건너뛰어도 됩니다.
데이터 폴더 구조
dist/data 폴더는 다음과 같이 구성됩니다.
data/
├── phones/ # 측정 데이터 파일 (.txt) 저장 위치
│ ├── PhoneA L.txt
│ ├── PhoneA R.txt
│ └── PhoneB.txt
├── target/ # 타겟 커브 데이터 파일 (.txt) 저장 위치
│ ├── X Target.txt
│ └── Y Target.txt
└── phone_book.json # 측정 기기 목록 및 관련 데이터 정의 파일
phones폴더 — 각 Phone의 주파수 응답 측정 파일(.txt)을 저장합니다. 파일 이름은 자유지만,phone_book.json에는 정확히 같은 이름을 적어야 합니다. 좌/우 채널이 별도 파일이라면 파일명 끝에 공백을 하나 두고L,R을 붙여 구분합니다.target폴더 — 타겟 커브 파일(.txt)을 저장합니다.config.js의INITIAL_TARGETS나TARGET_MANIFEST에 적는 이름과 정확히 일치해야 합니다.phone_book.json— 기기 목록에 표시될 제품 이름과 부가 정보(리뷰 링크, 가격 등)를 JSON 형식으로 정의합니다.
JSON 문법 기초
JSON(JavaScript Object Notation)은 데이터를 구조적으로 표현하는 텍스트 형식입니다. 몇 가지 기본 규칙만 알면 쉽게 읽고 고칠 수 있습니다.
- 데이터는 이름(Key)과 값(Value)의 쌍으로 이루어지며, 이름은 항상 따옴표로 감싼 문자열입니다.
- 값은 문자열(따옴표), 숫자(따옴표 없음), 불리언(
true/false, 따옴표 없음), 배열([·]로 감싸고 쉼표로 구분), 또는 다른 객체({·}로 감쌈)가 될 수 있습니다. - 객체 안의 각 키-값 쌍은 쉼표(
,)로 구분합니다. 마지막 쌍 뒤에는 쉼표를 붙이지 않습니다. - 배열 안의 각 요소도 쉼표(
,)로 구분합니다. 마지막 요소 뒤에도 쉼표는 없습니다.
phone_book.json 구조
phone_book.json은 하나의 큰 배열([])로 시작해서 끝납니다. 그 안에 여러 브랜드 객체({})가 들어갑니다.
각 브랜드 객체는 name 키(예: "Sennheiser", "Sony")와 phones 키로 구성됩니다.
phones 키 안에는 해당 브랜드의 모델(Phone) 정보가 담깁니다. 모델 정보는 단순 문자열로도, 객체로도 정의할 수 있습니다.
[
{
"name": "Brand A",
"suffix": "(Audio)", // Optional: Suffix for the brand name
"phones": [
"ModelX_Simple", // Simple definition: Assumes files "ModelX_Simple L.txt" and "ModelX_Simple R.txt"
{
"name": "Model Y",
"file": "BrandA ModelY", // File name (without L/R and .txt)
"suffix": ["(Setting 1)", "(Setting 2)"], // Optional: Suffixes for different versions
"reviewLink": "https://example.com/review/modely", // Optional: Review link
"price": "$199", // Optional: Price (string)
"description": "Some description about Model Y" // Optional: Extra description
},
// ... more models for Brand A
]
},
{
"name": "Brand B",
"phones": [
// ... models for Brand B
]
}
// ... more brands
]
Brand 객체 키
name(문자열, 필수) — 브랜드 이름.suffix(문자열, 선택) — 브랜드 이름 뒤에 붙어 UI에 표시되는 접미사.phones(배열, 필수) — 해당 브랜드의 모든 Phone 정보를 담는 배열. 각 모델은 단순 문자열 또는 상세 객체로 정의합니다.
Phone 정의 형태
phones 배열에는 다음 형태로 데이터를 넣을 수 있습니다.
단순 문자열 정의
단순 문자열(예: "ModelX")을 넣으면 화면에는 "ModelX"라고 표시되고, 데이터 파일은 ModelX L.txt, ModelX R.txt라고 가정합니다.
{
"name": "BrandSimple",
"phones": [
"ModelS1", // Loads `~/ModelS1 L.txt`, `~/ModelS1 R.txt`
"ModelS2" // Loads `~/ModelS2 L.txt`, `~/ModelS2 R.txt`
]
}
상세 객체 정의
더 자세한 설정이 필요하다면 Phone을 다음 키를 가진 객체로 정의합니다.
name(문자열, 필수) — 화면에 표시될 Phone 모델 이름.file(문자열, 필수) — 측정 데이터 파일의 실제 이름(L/R 접미사와.txt확장자 제외). 예를 들어 파일이MyPhone L.txt,MyPhone R.txt라면"MyPhone"으로 설정합니다.suffix(문자열, 선택) — 선택 목록의 이름 뒤에 붙는 접미사. 실제 데이터 파일 이름에도 같은 접미사가 들어 있어야 합니다(예:MyPhone (Foam Tip) L.txt).reviewScore(문자열, 선택) — 리뷰 점수."A+", 0~5 사이 숫자("3") 등 자유롭게 표기.reviewLink(문자열, 선택) — Phone 리뷰 URL.shopLink(문자열, 선택) — 상점 또는 구매 페이지 URL.price(문자열, 선택) — 가격(예:"$299","€250"). 문자열이라 통화 기호가 다른 표기도 그대로 허용됩니다.description(문자열, 선택) — Phone과 함께 표시할 자유 서술 설명.
{
"name": "BrandDetailed",
"phones": [
{
"name": "Model D1",
"file": "ModelD1_Data",
"suffix": "Rev.2",
"reviewScore": "A+",
"reviewLink": "https://example.com/review/d1",
"shopLink": "https://example.com/shop/d1",
"price": "$299"
}
]
}
Variations (여러 데이터 파일을 하나로 묶기)
EQ 설정이나 이어팁에 따라 여러 버전의 측정값이 있다면, 이들을 하나의 이름으로 묶어 UI에 보여줄 수 있습니다.
{
"name": "BrandVariations",
"phones": [
{
"name": "Model V1", // Base name for variations
"file": ["ModelV1_Foam", "ModelV1_Silicone", "ModelV1_Hybrid"],
"suffix": ["(Foam Tip)", "(Silicone Tip)", "(Hybrid Tip)"],
"price": "$150" // Applies to all V1 variations
}
]
}
name,file,suffix배열을 함께 사용할 때name(문자열 배열, 필수) — 모든 Variation의 기본 이름이 되는 문자열 배열.file(문자열 배열, 필수) — 각 Variation의 기본 파일 이름 배열.suffix(문자열 배열, 필수) — 각 파일에 대응하는 접미사 배열. UI에는brand_name + name + suffix[i]형태로 표시됩니다.- 위 예시는 "BrandVariations Model V1 (Foam Tip)", "BrandVariations Model V1 (Silicone Tip)" 같은 항목으로 만들어집니다.
file과suffix배열 길이는 가급적 같아야 합니다. 다른 선택 키(reviewLink,price등)를 추가하면 모든 Variation에 똑같이 적용됩니다.
{
"name": "BrandPrefix",
"phones": [
{
"name": "Model P1", // Base display name
"file": [
"BrandP ModelP1 (Foam Tip)",
"BrandP ModelP1 (Silicone Tip)"
], // Actual files would be: BrandP ModelP1 (Foam Tip) L.txt, BrandP ModelP1 (Silicone Tip) L.txt, etc.
"prefix": "BrandP ModelP1", // Common file prefix
"description": "Uses different eartips"
}
]
}
prefix로 공통 파일 접두사 사용하기
Variation 파일들이 같은 접두사를 공유하지만 뒷부분이 명확히 구분된다면 prefix를 쓸 수 있습니다.
name(문자열 배열, 필수) — 모든 Variation의 기본 이름이 되는 문자열 배열.file(문자열 배열, 필수) — 각 Variation의 기본 파일 이름 배열.prefix(문자열, 필수) — 모든 파일에 공통으로 붙는 접두사.- UI에는
brand_name + name + suffix[i]형태로 표시됩니다(예: "BrandPrefix Model P1 (Foam Tip)", "BrandPrefix Model P1 (Silicone Tip)"). - 여러 이어팁이나 이어패드를 조합한 측정, 또는 착용 위치별 측정처럼 같은 기기에 속한 데이터를 한데 묶을 때 편리합니다.
다중 샘플 항목 (Multi-Sample Entries)
다중 샘플 항목은 같은 기기를 여러 번 측정한 결과를 하나의 phone으로 묶습니다. UI는 기본적으로 모든 측정의 평균을 표시하고, samples > 1일 때 자동으로 나타나는 샘플 선택기에서 개별 샘플을 켜고 끌 수 있습니다.
samples(숫자, 필수) — 측정 횟수. 도구가n = 1..samples에 대해{file} L{n}.txt와{file} R{n}.txt를 차례로 로드합니다.- 일반 phone 객체의 다른 키(
reviewLink,price,shopLink등)와 함께 써도 됩니다. - 측정 파일은 다른 항목과 마찬가지로
data/phones/에 그대로 둡니다.
{
"name": ["Multi Sample"],
"file": ["Multi Sample"],
"suffix": [""],
"samples": 3
}
위 예시는 다음 6개 파일을 로드합니다.
Multi Sample L1.txt, Multi Sample R1.txt, Multi Sample L2.txt, Multi Sample R2.txt, Multi Sample L3.txt, Multi Sample R3.txt
samples: N으로 선언한 variant에서 번호 파일 {file} L1.txt / {file} R1.txt를 찾지 못하면, 도구가 번호 없는 {file} L.txt / {file} R.txt 쌍으로 폴백하고 해당 variant를 단일 샘플 측정으로 취급합니다. 덕분에 같은 file 배열 안에서 번호 있는 샘플과 번호 없는 쌍을 자유롭게 섞어 둘 수 있고, 번호 샘플이 없는 variant도 오류 없이 로드됩니다.
config.js의 MULTI_SAMPLE.DEFAULT_DISPLAY로 다중 샘플 phone을 평균 한 곡선으로 열지, 모든 개별 샘플로 열지 정할 수 있습니다. MULTI_SAMPLE 설정 섹션을 참고하세요.
HpTF (Headphone Transfer Function) 항목
HpTF 항목은 서로 관련된 여러 측정 사이의 편차(variance)—예를 들어 약간씩 다른 착용 위치(Center, Front, Back, Up, Down)나 측정 장비 차이—를 그래프에 겹쳐진 음영 포락선으로 시각화합니다. 원하면 샘플별 곡선도 함께 표시할 수 있죠. 각 HpTF 세트는 그래프 자체가 포락선인 하나의 기기 variant가 됩니다. 비교하고 싶은 무엇이든 샘플로 만들 수 있으니, HpTF는 착용 위치에만 한정되지 않습니다.
하나의 기기에 hptfs 배열로 여러 개의 HpTF 세트를 선언할 수도 있습니다. 예를 들어 이어패드별(Leather / Suede)이나 착용 깊이별로 하나씩 둘 수 있습니다. 각 hptfs 항목은 기기 선택기에서 독립된 variant가 됩니다.
hptfs(객체 배열, 필수) — 하나 이상의 HpTF 측정 세트. 각 항목은 다음 키를 가집니다.files(문자열 배열, 필수) — 각 편차 샘플의 기본 파일 이름. 도구가 항목마다{name} L.txt와{name} R.txt를 로드합니다.labels(문자열 배열, 선택) — HpTF 토글 UI에 표시될 라벨. 생략하면files값이 그대로 사용됩니다.suffix(문자열, 선택) — 기기 선택기 드롭다운에 표시되는 variant 접미사(예:"Leather Pad"). 한 기기에 여러hptfs항목이 있을 때 사용자가 고르는 값이 바로 이 값입니다. 항목이 하나뿐이면 생략해도 됩니다.description(문자열, 선택) — 무엇이 달라지는지 설명하는 짧은 메모로, 음영 포락선과 함께 표시됩니다(예:"(Fit Position)","(Rig Variance)","(Insertion Depth)").fillOnly(불리언, 선택, 기본값true) —true이면 음영 포락선만 그립니다. 사용자가 UI에서 샘플별 편차 곡선을 켜고 끌 수 있게 하려면false로 설정하세요.
- 측정 파일은 다른 항목과 마찬가지로
data/phones/에 둡니다.
HpTF 세트 하나:
{
"name": ["HpTF Fill Only"],
"hptfs": [
{
"files": [
"HpTF Demo Center",
"HpTF Demo Front",
"HpTF Demo Back",
"HpTF Demo Up",
"HpTF Demo Down"
],
"labels": ["Center", "Front", "Back", "Up", "Down"],
"description": "(Fit Position)"
}
]
}
여러 HpTF 세트 (예: 이어패드별):
{
"name": ["HpTF Multi Pad"],
"hptfs": [
{
"suffix": "Leather Pad",
"files": ["Leather Center", "Leather Front", "Leather Back"],
"labels": ["Center", "Front", "Back"],
"description": "(Leather Pad Variance)"
},
{
"suffix": "Suede Pad",
"files": ["Suede Center", "Suede Front", "Suede Back"],
"labels": ["Center", "Front", "Back"],
"description": "(Suede Pad Variance)"
}
]
}
위 예시는 HpTF Multi Pad Leather Pad와 HpTF Multi Pad Suede Pad라는 두 독립 variant를 만듭니다. 기기 선택기의 variant 드롭다운에서 둘 사이를 전환할 수 있습니다.
하나의 phone 항목에 file / suffix variant와 hptfs를 함께 선언해도 됩니다. 둘은 한 평면 목록에서 각각 독립된 variant로 취급되며 서로 조합되지 않습니다. file variant 2개와 hptfs 항목 2개가 있는 phone이라면 variant 선택기에 4개 별개 항목(예: Stock, Modded, Leather Pad, Suede Pad)으로 표시됩니다.
음영 투명도와 기본 표시 모드(fill, fill+curves, curves, none)는 HPTF 설정 섹션에서 정할 수 있습니다.
측정 데이터 추가/수정 절차
- 새 Phone 측정 파일(.txt)을
data/phones폴더에 복사합니다. - 텍스트 에디터로
phone_book.json을 엽니다. - JSON 문법에 맞춰 새 Phone 정보를 추가하거나 기존 정보를 수정합니다.
phone_book.json을 저장합니다.- 웹 페이지를 새로고침해서 변경 사항이 잘 반영됐는지 확인합니다.
phone_book.json을 수정할 때는 JSON 문법(따옴표, 쉼표 등)을 정확히 지켜야 합니다. 오류가 있으면 페이지가 정상적으로 로드되지 않습니다. VS Code의 빨간색·주황색 오류 표시 기능을 함께 활용하면 문법 실수를 미리 잡기 쉽습니다.