← 모든 글

Music Understanding 살펴보기: 온디바이스 오디오 분석

WWDC 2026에서 Apple의 Final Cut Pro 팀은 하나의 프레임워크 위에 구축된 두 가지 기능을 선보였습니다. 하나는 곡의 비트 그리드를 드러내어 편집자가 마디와 비트에 컷을 맞출 수 있게 해 주는 비트 감지 기능이고, 다른 하나는 클립을 음악에 자동으로 동기화하는 iPad용 몽타주 기능입니다.1 두 기능 모두 새로운 프레임워크인 Music Understanding 위에서 동작합니다. 이 프레임워크는 신호 처리나 머신러닝에 대한 지식을 전혀 요구하지 않으면서 곡의 음악적 인텔리전스(키, 리듬, 구조, 페이스, 악기 활동, 라우드니스)를 건네줍니다. 전적으로 온디바이스에서 실행되기 때문에 분석하는 오디오는 비공개로 유지되며 오프라인에서도 작동합니다.1 이 글에서는 프레임워크를 직접 만들어 가며 살펴봅니다. 여섯 가지 분석 영역, MusicUnderstandingSession이 이들을 어떻게 생성하는지, 그리고 오디오에 반응하는 시각 효과를 실용적으로 만들어 주는 스트리밍 라우드니스 AsyncSequence를 차례로 다룹니다.

핵심 요약

  • Music Understanding은 곡의 여섯 가지 영역(키, 리듬, 구조, 페이스, 악기 활동, 라우드니스)을 온디바이스에서 분석하며, 신호 처리나 머신러닝 전문 지식이 필요하지 않습니다.1
  • AVAsset이나 사용자 정의 오디오 제공자로부터 MusicUnderstandingSession을 생성한 다음, 모든 것을 얻으려면 analyze()를, 특정 유형만 대상으로 하여 불필요한 연산을 건너뛰려면 analyze(for:)를 호출합니다.1
  • 결과는 SessionResult 구조체에 도착하며, 각 특징은 옵셔널 필드로 표현됩니다. 일반 analyze()는 그 모두를 채우고, 대상을 지정한 analyze(for:)는 나머지를 nil로 남겨 둡니다.1
  • 시간을 다루는 두 가지 유형이 API 전반을 관통합니다. TimedValue는 값을 CMTime과 짝지으며, RangedValue는 값을 CMTimeRange와 짝짓습니다.1
  • MusicUnderstandingSession은 분석된 오디오 100ms마다 AsyncSequence로 값을 전달하는 스트리밍 라우드니스 API도 제공합니다. 이것이 실시간 오디오 반응형 애니메이션을 구동하는 토대가 됩니다.1

온디바이스 음악 인텔리전스가 중요한 이유

Watch on Apple Developer ↗

Apple Computational Music Team의 Conner가 1:39부터 프레임워크의 여섯 가지 분석 영역을 소개합니다.

이 프레임워크의 지향점은 좁고 정직합니다. 프레임워크는 “신호 처리와 모델 추론을 모두 대신 처리해 주므로, 사용하는 데 신호 처리나 머신러닝 전문 지식이 전혀 필요하지 않습니다”.1 이는 오디오 분석에서 대다수의 앱 개발자가 결코 떠맡고 싶어 하지 않았던 부분을 제거해 줍니다. 템포를 감지하거나, 곡을 후렴과 절로 나누거나, 지각되는 라우드니스를 측정하는 일은 예전에는 모두 서드파티 엔진을 라이선스하거나 DSP 파이프라인을 직접 구축하는 것을 의미했습니다.

온디바이스 실행은 프라이버시 계산도 바꿔 놓습니다. 프레임워크가 “전적으로 온디바이스에서 실행되기 때문에, 분석하는 오디오는 비공개로 유지되고 오프라인에서도 작동”하기 때문입니다.1 곡은 분석을 위해 결코 기기를 떠나지 않으며, 신호가 없는 비행기 안에서도 분석이 동작합니다. 라이브러리를 템포로 정렬하는 DJ 앱이나 컷을 비트에 맞추는 비디오 편집기에게는, 네트워크 의존성이 없고 오디오가 기기 밖으로 나가지 않는 이 조합이 바로 실용적인 돌파구입니다.

Apple은 이 여섯 가지 영역을 곡의 구성 요소로 설명합니다. 리듬은 맥박이며, 개별 비트가 모여 마디로 쌓입니다. 1분당 비트 수가 beats per minute, 즉 bpm입니다.1 마디는 프레이즈(음악적 문장)를 이루고, 프레이즈가 결합해 세그먼트가 되며, 세그먼트가 후렴, 절, 인트로, 브리지 같은 섹션을 구축합니다.1 드럼, 베이스, 보컬 같은 악기는 키라고 불리는 공통의 음 집합을 중심으로 서로 다른 타이밍과 강도로 연주됩니다.1 곡은 bpm을 일정하게 유지하면서도 부분에 따라 더 느리거나 빠르게 느껴질 수 있는데, Apple은 이를 페이스라고 부릅니다. 그리고 곡은 어떤 지점에서는 다른 곳보다 더 크게 울립니다.1 이 여섯 가지 개념은 프레임워크의 결과 유형과 일대일로 대응됩니다.

세션: 하나의 객체, 두 가지 질문 방식

앱은 MusicUnderstandingSession과 상호작용하며, 이를 “AVAsset 또는 사용자 정의 오디오 제공자 중 하나”로 초기화합니다.1 분석을 실행하려면 analyze를 호출하고 결과를 await합니다. 기본 동작은 모든 유형을 분석하는 것이지만, Apple은 성능 레버를 분명하게 짚어 줍니다. “최고의 성능을 얻으려면, 관심 있는 분석 유형을 지정하여 불필요한 연산을 피할 수 있습니다”.1 화면에 그리는 것만 연산하느냐 여부가 반응성 좋은 도구와 로드할 때마다 버벅이는 도구를 가르는 차이입니다.

샘플 앱 Music Understanding Lab은 파일 경로를 처음부터 끝까지 보여 줍니다. SwiftUI fileImporter가 곡을 선택해 그 URL을 반환하고, 그 URL이 AVURLAsset이 됩니다. Apple은 한 가지 설정이 결정적이라고 짚습니다. “가장 정확한 결과를 보장하기 위해” PreferPreciseDurationAndTimingKeytrue로 설정하세요.1 그런 다음 에셋으로부터 세션을 생성하고, analyze를 호출하여 세션 결과가 반환되기를 await합니다.

그 결과는 SessionResult 구조체에 도착하며, 여기서 “Music Understanding이 분석하는 모든 특징은 각자의 결과 필드를 가집니다. 이들은 모두 옵셔널입니다”.1 두 진입점은 무엇을 채우느냐가 다릅니다. 일반 analyze() API는 모든 결과를 사용할 수 있게 합니다. 대상을 지정한 analyze(for:) API는 요청한 결과만 반환하고 “나머지는 nil이 됩니다”.1 즉 옵셔널이라는 것은 API 설계의 우연이 아닙니다. 프레임워크가 실제로 어떤 작업을 했는지 알려 주는 방식입니다.

값에 시간을 붙이기 위해 두 가지 유형이 프레임워크 전반에 반복해서 등장합니다. TimedValue는 값을 CMTime(하나의 순간)에 연결하고, RangedValueCMTimeRange(하나의 구간)를 값에 연결합니다.1 아래의 거의 모든 결과가 이 두 가지 형태 중 하나로 표현되므로, 한 번 익혀 두면 여섯 가지 영역 전부에서 도움이 됩니다.

여섯 가지 결과 둘러보기

키. 키 분석에서 프레임워크는 KeyResult 구조체를 반환하며, 이는 “RangedValue를 사용해 KeySignature를 특정 시간 범위에 대응시키는 범위 배열을 담고 있습니다”.1 KeySignature는 토닉과 모드를 보유합니다. 토닉은 “표준 반음계 음 중 어느 것이든 될 수 있으며” 곡이 중심으로 삼는 으뜸음(C나 G 등)을 나타냅니다. 모드는 “장조 또는 단조 중 하나”입니다.1 결과가 단일 값이 아니라 범위 배열이기 때문에, 이 API는 도중에 키가 바뀌는 곡도 수용합니다.

리듬. 리듬을 분석하면 RhythmResult가 나옵니다. 이 구조체는 “모든 비트와 마디의 타임스탬프를 CMTime 배열로” 제공하며, 더불어 beatsPerMinute를 통해 전체의 글로벌 템포를 알려 줍니다.1 실시간 UI에 중요한 세부 사항이 하나 있습니다. beatsPerMinute는 옵셔널입니다. “프레임워크가 적어도 두 개의 비트를 찾기에 충분한 오디오를 아직 처리하지 못했다면, bpm이 nil로 설정되기” 때문입니다.1 간격을 재려면 두 개의 비트가 필요하므로, 이 nil은 프레임워크가 추측하기를 거부하는 것입니다.

구조. 구조 분석을 요청하면 세 가지 속성을 가진 StructureResult가 반환됩니다. “섹션, 세그먼트, 프레이즈”를 위한 것이며, 각각에 대해 CMTimeRange 배열을 얻습니다.1 세 층위는 중첩됩니다. 섹션은 하나 이상의 세그먼트로 이루어지고, 각 세그먼트는 프레이즈로 이루어집니다.1 이 위계 덕분에 편집자는 임의의 타임스탬프가 아니라 후렴 경계에 컷을 스냅할 수 있습니다.

페이스. 페이스는 “음악이 청자에게 얼마나 빠르게 느껴지는지를 알려 주며”, 더 활기찬 부분은 느린 부분보다 높은 값을 가집니다.1 이를 요청하면 PaceResult가 반환되는데, 이는 “범위가 지정된 값의 배열을 담은 단일 속성”을 가진 구조체입니다.1 페이스는 bpm과 다릅니다. 템포가 일정하게 유지되더라도 느껴지는 에너지는 오르내릴 수 있습니다.

악기 활동. 악기 활동을 요청하면 두 가지 속성을 가진 InstrumentActivityResult가 반환됩니다. 하나는 범위를 위한 것이고, 다른 하나는 활동을 위한 것입니다.1 Ranges API는 “각 Instrument를” 악기별 값에 “대응시키는 딕셔너리를 제공하며”(그 값의 유형이 명시되기 전에 트랜스크립트가 끊깁니다), Apple은 “악기가 존재하는지 여부만 알고 싶을” 때 범위가 적절한 선택지라고 설명합니다.1 activity 속성은 더 상세한 정보를 담습니다. 그것은 “악기를 Float의 TimedValue에 대응시키며”, 그 값들은 “악기가 시간에 따라 얼마나 강하게 연주되는지를 표현합니다”.1 Apple은 이 activity 결과를 “오디오 반응형 애니메이션을 구동하는 훌륭한 원천”이라고 부릅니다. 악기별, 순간별 강도야말로 시각화 도구가 바인딩하고 싶어 하는 바로 그것이기 때문입니다.1

라우드니스. 프레임워크는 라우드니스를 Loudness Units Full Scale(LUFS)로 측정합니다. 이는 “사람의 귀가 음량을 어떻게 지각하는지 모델링하는 업계 표준”입니다.1 라우드니스 분석을 요청하면 integrated, momentary, shortTerm 라우드니스를 지원하는 LoudnessResult 구조체가 생성됩니다.1 integrated는 오디오 전체의 라우드니스를 나타내는 단일 값입니다. momentary와 shortTerm은 둘 다 100밀리초마다 타임스탬프가 붙은 값을 제공하지만, 서로 다른 윈도우를 사용합니다. momentary는 400밀리초 윈도우를 써서 “라우드니스의 짧고 갑작스러운 스파이크”를 잡아내고, shortTerm은 3초 윈도우를 써서 “시간에 따른 라우드니스 추세를 더 매끄럽게 보여 줍니다”.1 결과는 피크 값도 담습니다. 이는 데시벨로 측정된, 오디오 음량의 절대적인 최댓값입니다.1

스트리밍 라우드니스 AsyncSequence

위의 배치 API는 완성된 파일을 분석합니다. 실시간 작업을 위해 MusicUnderstandingSession은 “라우드니스를 위한 스트리밍 API도 제공”하며, 여기서 “값은 프레임워크가 분석한 오디오 100ms마다 AsyncSequence를 통해 전달됩니다”.1 100ms마다 새로운 라우드니스 측정값이 나온다는 것은 실시간 시각화 도구가 돌아가는 바로 그 박자입니다. 그렇기에 배치 API가 아니라 이 API가 오디오 반응형 UI의 중심이 됩니다.

사용 패턴은 두 개의 동시 태스크입니다. 앞서와 같이 세션을 초기화한 다음, “두 개의 태스크를 설정합니다. 하나는 전달되는 라우드니스 결과를 소비하는 태스크이고, 다른 하나는 분석을 시작하는 태스크입니다”.1 한 태스크는 시퀀스에서 값을 await하여 애니메이션으로 밀어 넣고, 다른 하나는 분석을 앞으로 진행시킵니다. 생산자와 소비자는 서로를 막지 않고 나란히 동작합니다.

실시간 오디오를 공급하려면 AudioProvider를 마련해야 합니다. AudioProvider는 “AsyncSequence를 준수하며 AVReadOnlyAudioPCMBuffer 객체를 산출합니다”.1 Apple은 종료 규약을 명시적으로 짚습니다. 제공자가 “모든 오디오 버퍼를 보냈다면, 완료를 알리기 위해 마지막으로 nil을 보내야 합니다”.1 끝의 nil을 잊으면 소비 태스크는 결코 끝나지 않을 오디오를 영원히 기다립니다. 제공자 자체가 AsyncSequence라는 점이 이 설계의 우아한 부분입니다. 여러분의 오디오 소스와 프레임워크의 라우드니스 출력이 처음부터 끝까지 같은 비동기 반복 언어로 대화하는 것입니다.

두 가지 세션 기능이 그림을 마저 완성합니다. 모든 Music Understanding 결과는 Codable이므로, 전체 분석을 내보내는 일은 “그저 JSONEncoder를 만들어 세션 결과를 인코딩하면” 됩니다.1 그리고 샘플 앱의 Video 타일은 결과들이 어떻게 조합되는지 보여 줍니다. 그것은 “구조와 페이스를 사용해 음악에 동기화된 비디오를 만들고”, 섹션의 시간 범위를 식별한 뒤, 각 섹션의 페이스(1분당 이벤트 수를 60초로 나눈 값)를 사용해 그 범위에 몇 개의 클립이 들어갈지를 결정합니다. 활기찬 부분에는 더 짧고 빠른 클립을, 차분한 부분에는 더 길고 느린 클립을 배치합니다.1

핵심 정리

오디오 및 미디어 앱 개발자를 위해:

  • analyze()가 아니라 analyze(for:)에서 시작하세요. 요청하지 않은 결과는 어차피 nil로 돌아오니, 화면에 그리는 분석 유형만 지정하여 프레임워크가 나머지를 건너뛰게 하세요.1
  • UI에서 beatsPerMinute를 진정으로 옵셔널한 것으로 다루세요. nil은 프레임워크가 아직 두 개의 비트를 보지 못했다는 뜻이므로, 가짜 템포 대신 대기 중 상태를 표시하세요.1
  • 세션을 생성하기 전에 AVURLAssetPreferPreciseDurationAndTimingKeytrue로 설정하세요. Apple이 정확한 결과를 이 플래그에 묶어 두었기 때문입니다.1

실시간 및 시각화 작업을 위해:

  • 실시간 오디오 반응형 애니메이션은 라우드니스 AsyncSequence(100ms마다의 값)와, 각 악기를 시간에 따른 강도의 TimedValue에 대응시키는 악기 activity 속성 위에 구축하세요.1
  • 소비 태스크와 분석 태스크를 동시에 실행하고, 사용자 정의 AudioProvider가 마지막 AVReadOnlyAudioPCMBuffer 다음에 마지막 nil을 보내게 하여 스트림이 깔끔하게 종료되도록 하세요.1

카탈로그 및 도구 팀을 위해:

  • KeyResultRhythmResult를 사용해 음악 라이브러리를 키나 템포로 정렬하거나 클러스터링하고, Codable한 SessionResult를 JSON으로 인코딩해 분석 결과를 저장하여 재사용하세요.1

FAQ

Apple의 Music Understanding 프레임워크는 무엇을 분석하나요?

곡의 여섯 가지 영역, 즉 키, 리듬, 구조, 페이스, 악기 활동, 라우드니스를 분석합니다. 각각은 결과 유형(KeyResult, RhythmResult, StructureResult, PaceResult, InstrumentActivityResult, LoudnessResult)에 대응하며 SessionResult 안에서 반환됩니다. 프레임워크가 신호 처리와 모델 추론을 처리하므로 DSP나 머신러닝 전문 지식이 필요하지 않습니다.1

Music Understanding은 온디바이스에서 동작하나요, 아니면 클라우드에서 동작하나요?

온디바이스입니다. Apple은 프레임워크가 “전적으로 온디바이스에서 실행된다”고 밝혔으며, 따라서 분석하는 오디오는 비공개로 유지되고 오프라인에서도 작동합니다. 이 분석은 네트워크 의존성 없이 Apple의 플랫폼 전반에서 동작합니다.1

필요한 분석만 얻으려면 어떻게 하나요?

일반 analyze() 대신 analyze(for:)를 호출하세요. 일반 호출은 SessionResult의 모든 필드를 채우지만, 대상을 지정한 호출은 요청한 유형만 반환하고 나머지는 nil로 남깁니다. Apple은 불필요한 연산을 피하기 위해 “최고의 성능”을 얻을 목적으로 유형을 지정할 것을 권장합니다.1

TimedValue와 RangedValue의 차이는 무엇인가요?

TimedValue는 값을 하나의 CMTime 순간에 연결하고, RangedValue는 값을 CMTimeRange 구간에 연결합니다. 두 유형 모두 프레임워크 전반에 등장합니다. 예를 들어 키 시그니처는 범위 값으로 도착하고, 악기별 활동은 시간 값으로 도착합니다.1

이것으로 실시간 오디오 반응형 시각화 도구를 어떻게 만드나요?

MusicUnderstandingSession의 스트리밍 라우드니스 API를 사용하세요. 이 API는 분석한 오디오 100ms마다 AsyncSequence로 값을 전달합니다. 두 개의 동시 태스크(하나는 결과를 소비하고, 하나는 분석을 구동)를 실행하고, AsyncSequence를 준수하며 AVReadOnlyAudioPCMBuffer 객체를 산출하고 완료를 알리는 마지막 nil을 보내는 사용자 정의 AudioProvider를 통해 실시간 오디오를 공급하세요.1


온디바이스 오디오 분석은 Apple이 올해 선보인 다른 미디어 인텔리전스와 나란히 자리합니다. 온디바이스 AI가 iOS 27에서 Spotlight와 미디어에 도달하는 방식과, 같은 문제의 오디오-텍스트 변환 측면에 대한 Speech 프레임워크와 SFSpeechRecognizer 비교를 살펴보세요. Apple의 내장 모델을 완전히 넘어설 때는, Core AI로 Apple silicon에서 직접 모델 실행하기가 다음 단계입니다. 전체 시리즈 허브는 Apple Ecosystem Series입니다.

참고 문헌


  1. Apple, WWDC 2026 session 253, Meet the Music Understanding framework. 온디바이스, 프라이버시, 오프라인 위치 설정, Final Cut Pro 비트 감지 기능과 iPad 몽타주 기능, 여섯 가지 분석 영역(키, 리듬, 구조, 페이스, 악기 활동, 라우드니스)과 곡 구성 요소 정의, AVAsset 또는 오디오 제공자로 초기화되는 MusicUnderstandingSession, analyze()analyze(for:) 및 옵셔널 필드로 구성된 SessionResult, SwiftUI fileImporter를 통한 AVURLAssetPreferPreciseDurationAndTimingKey 설정, TimedValue/CMTimeRangedValue/CMTimeRange 유형, KeyResult/KeySignature(토닉과 모드), RhythmResult/beatsPerMinute(두 비트 미만이면 옵셔널), StructureResult(섹션, 세그먼트, 프레이즈), PaceResult, InstrumentActivityResult(ranges와 activity, activity는 Float의 TimedValue), LoudnessResult(LUFS, integrated/momentary/shortTerm 윈도우, 데시벨 단위 피크) 유형, 두 개의 동시 태스크로 100ms마다 값을 전달하는 스트리밍 라우드니스 AsyncSequence, AsyncSequence를 준수하며 AVReadOnlyAudioPCMBuffer 객체를 산출하고 마지막에 nil을 보내는 AudioProvider, Codable 결과와 JSONEncoder 내보내기, 그리고 구조와 페이스를 활용한 Video 타일 알고리즘의 출처. 

관련 게시물

WWDC26 랩에서 Apple Swift 팀이 한 이야기

Apple의 WWDC26 Swift Group Lab은 자막 없이 공개됐습니다. 직접 로컬에서 받아쓰기해, 동시성과 ~Sendable, 로드맵에 관한 엔지니어들의 솔직한 답변을 정리했습니다.

10 분 소요

Swift의 새로운 기능 (2026): WWDC26 업데이트

WWDC26에서 발표된 Swift 6.3과 6.4: anyAppleOS 가용성, 모듈 선택자, borrow/mutate 접근자, Iterable 프로토콜, Swift Testing 상호 운용, 그리고 MLX.

13 분 소요

Loop Engineering: Loops Win Where Verification Is Cheap

Loop engineering, checked against Boris Cherny's full transcripts: every loop he names has cheap verification. That cons…

19 분 소요