Conheça o Music Understanding: análise de áudio no dispositivo
Na WWDC 2026, a equipe do Final Cut Pro da Apple lançou dois recursos construídos sobre um único framework: um recurso de detecção de batidas que revela a grade de batidas de uma música para que os editores possam alinhar os cortes a compassos e batidas, e um recurso de montagem no iPad que sincroniza clipes à música automaticamente.1 Ambos rodam sobre o Music Understanding, um novo framework que entrega a você a inteligência musical de uma música (tonalidade, ritmo, estrutura, andamento, atividade de instrumentos e loudness) sem exigir que você saiba nada sobre processamento de sinais ou aprendizado de máquina. Ele roda inteiramente no dispositivo, então o áudio que você analisa permanece privado e funciona offline.1 Este post percorre o framework em formato mão na massa: as seis áreas de análise, como uma MusicUnderstandingSession as produz e o AsyncSequence de loudness em streaming que torna viáveis os visuais reativos ao áudio.
Resumo
- O Music Understanding analisa seis áreas de uma música (tonalidade, ritmo, estrutura, andamento, atividade de instrumentos e loudness) no dispositivo, sem exigir conhecimento em processamento de sinais ou aprendizado de máquina.1
- Você cria uma
MusicUnderstandingSessiona partir de umAVAssetou de um provedor de áudio personalizado e, em seguida, chamaanalyze()para tudo ouanalyze(for:)para mirar tipos específicos e pular cálculos desnecessários.1 - Os resultados chegam em uma struct
SessionResultna qual cada característica é um campo opcional; oanalyze()geral preenche todos eles, e oanalyze(for:)direcionado deixa o restante comonil.1 - Dois tipos cientes do tempo permeiam a API: um
TimedValueassocia um valor a umCMTime, e umRangedValueassocia um valor a umCMTimeRange.1 - A
MusicUnderstandingSessiontambém expõe uma API de loudness em streaming que entrega valores por meio de umAsyncSequencea cada 100 ms de áudio analisado, o que é a base para impulsionar animações reativas ao áudio ao vivo.1
Por que inteligência musical no dispositivo importa
Conner, da Computational Music Team da Apple, enumera as seis áreas de análise do framework a partir de 1:39.
A proposta é restrita e honesta: o framework “cuida de todo o processamento de sinais e da inferência de modelos para você, de modo que você não precisa de nenhuma especialização em processamento de sinais ou aprendizado de máquina para usá-lo”.1 Isso elimina justamente a parte da análise de áudio que a maioria dos desenvolvedores de apps nunca quis assumir. Detectar um andamento, segmentar uma música em refrão e estrofe, ou medir o loudness percebido costumavam significar ou licenciar um motor de terceiros ou construir um pipeline de DSP na mão.
Rodar no dispositivo também muda a conta da privacidade. Como o framework “roda inteiramente no dispositivo, o áudio que você analisa permanece privado e funciona offline”.1 Uma música nunca sai do telefone para ser analisada, e a análise funciona em um avião sem sinal. Para um app de DJ que ordena uma biblioteca por andamento, ou um editor de vídeo que combina cortes com batidas, essa combinação de zero dependência de rede e de áudio que não sai do dispositivo é o ganho prático.
A Apple apresenta as seis áreas como os blocos de construção de uma música. O ritmo é a pulsação, conduzida por batidas individuais que se acumulam em compassos; o número de batidas em um minuto é o número de batidas por minuto, ou bpm.1 Compassos formam frases (sentenças musicais), frases se combinam em segmentos, e segmentos constroem seções como um refrão, uma estrofe, uma introdução ou uma ponte.1 Instrumentos como bateria, baixo ou vocais tocam em momentos e intensidades diferentes em torno de um conjunto comum de notas chamado tonalidade.1 Uma música pode manter um bpm estável enquanto diferentes partes parecem mais lentas ou mais rápidas, o que a Apple chama de andamento (pace), e a música fica mais alta em alguns trechos do que em outros.1 Esses seis conceitos mapeiam um a um nos tipos de resultado do framework.
A sessão: um objeto, duas formas de pedir
Os apps interagem com uma MusicUnderstandingSession, inicializando-a “com um AVAsset ou um provedor de áudio personalizado”.1 Para executar a análise, você chama analyze e aguarda os resultados. O comportamento padrão é analisar todos os tipos, e a Apple é explícita quanto à alavanca de desempenho: “Para o desempenho mais alto, você pode especificar quais tipos de análise lhe interessam para evitar cálculos desnecessários.”1 Calcular apenas o que você renderiza é a diferença entre uma ferramenta responsiva e uma que trava a cada carregamento.
O app de exemplo, Music Understanding Lab, mostra o caminho do arquivo de ponta a ponta. Um fileImporter do SwiftUI seleciona uma música e retorna sua URL, e essa URL se torna um AVURLAsset. A Apple sinaliza uma configuração como decisiva: defina PreferPreciseDurationAndTimingKey como true “para garantir os resultados mais precisos”.1 Em seguida, você cria a sessão a partir do asset, chama analyze e aguarda o retorno dos resultados da sessão.
Esses resultados aterrissam em uma struct SessionResult, na qual “cada característica que o Music Understanding analisa ganha seu próprio campo de resultado. Esses campos são todos opcionais.”1 Os dois pontos de entrada diferem no que preenchem. A API geral analyze() disponibiliza todos os resultados. A API direcionada analyze(for:) retorna apenas os resultados que você pediu, e “o restante será nil”.1 A opcionalidade, portanto, não é um acaso do design da API; é como o framework informa qual trabalho ele de fato realizou.
Dois tipos se repetem por todo o framework para anexar tempo a um valor. Um TimedValue associa um valor a um CMTime (um único instante), e um RangedValue associa um CMTimeRange a um valor (um intervalo).1 Quase todo resultado abaixo é expresso em uma dessas duas formas, então aprendê-las uma vez compensa nas seis áreas.
Percorrendo os seis resultados
Tonalidade. Para a análise de tonalidade, o framework retorna uma struct KeyResult, que “contém um array de intervalos, mapeando uma KeySignature para um intervalo de tempo específico usando um RangedValue”.1 Uma KeySignature contém uma tônica (tonic) e um modo (mode). A tônica “pode ser qualquer uma das alturas cromáticas padrão” e representa a nota fundamental (como dó ou sol) em torno da qual a música é construída; o modo “é maior ou menor”.1 Como o resultado é um array de intervalos em vez de um único valor, a API acomoda músicas que mudam de tonalidade no meio do caminho.
Ritmo. A análise de ritmo produz um RhythmResult. A struct fornece “os timestamps de cada batida e cada compasso como arrays de CMTime”, além do andamento global geral por meio de beatsPerMinute.1 Um detalhe importa para UIs ao vivo: beatsPerMinute é opcional, “porque, se o framework não tiver processado áudio suficiente para encontrar pelo menos duas batidas, o bpm será definido como nil”.1 São necessárias duas batidas para medir um intervalo, então o nil é o framework se recusando a chutar.
Estrutura. Solicitar a análise de estrutura retorna um StructureResult com três propriedades, “para sections, segments e phrases”, e para cada uma você recebe um array de CMTimeRanges.1 Os três níveis se aninham: uma seção é feita de um ou mais segmentos, e cada segmento é feito de frases.1 É essa hierarquia que permite a um editor ajustar um corte ao limite de um refrão em vez de a um timestamp arbitrário.
Andamento (pace). O andamento “diz a você o quão rápida a música parece para o ouvinte”, com as partes mais enérgicas carregando um valor mais alto do que as mais lentas.1 Solicitá-lo retorna um PaceResult, uma struct com “uma única propriedade contendo um array de ranged values”.1 O andamento é distinto do bpm: o tempo pode permanecer estável enquanto a energia sentida sobe e desce.
Atividade de instrumentos. Solicitar a atividade de instrumentos retorna um InstrumentActivityResult com duas propriedades, uma para intervalos (ranges) e uma para atividade (activity).1 A API de Ranges “fornece um dicionário, mapeando cada Instrument para” um valor por instrumento (a transcrição é interrompida antes de nomear o tipo desse valor), e a Apple apresenta ranges como a escolha certa quando “você só quer saber se um instrumento está presente ou não”.1 A propriedade activity carrega mais detalhe: ela “mapeia um instrumento para um TimedValue de Floats”, e esses valores “expressam o quão intensamente um instrumento está tocando ao longo do tempo”.1 A Apple chama o resultado de atividade de “uma excelente fonte para impulsionar animações reativas ao áudio”, porque uma intensidade por instante e por instrumento é exatamente aquilo a que um visualizador quer se vincular.1
Loudness. O framework mede o loudness em Loudness Units Full Scale (LUFS), “o padrão da indústria para modelar como o ouvido humano percebe o volume”.1 Solicitar a análise de loudness produz uma struct LoudnessResult que oferece suporte a loudness integrated, momentary e shortTerm.1 Integrated é um único valor para o loudness geral do áudio. Momentary e shortTerm fornecem ambos valores com timestamp a cada 100 milissegundos, mas em janelas diferentes: momentary usa uma janela de 400 milissegundos e captura “picos curtos e repentinos de loudness”, enquanto shortTerm usa uma janela de 3 segundos para “uma visão mais suave da tendência do loudness ao longo do tempo”.1 O resultado também carrega um valor peak, o volume de áudio absoluto mais alto medido em decibéis.1
O AsyncSequence de loudness em streaming
As APIs em lote acima analisam um arquivo finalizado. Para trabalho ao vivo, a MusicUnderstandingSession “também fornece uma API de streaming para loudness”, em que “os valores são entregues por meio de um AsyncSequence a cada 100 ms de áudio analisado pelo framework”.1 Uma nova leitura de loudness a cada 100 ms é a cadência em que um visualizador em tempo real opera, e é por isso que essa API, e não a em lote, é a peça central para uma UI reativa ao áudio.
O padrão de uso são duas tarefas concorrentes. Você inicializa a sessão como antes e então “configura duas tarefas: uma para consumir os resultados de loudness conforme eles são entregues, e outra para iniciar a análise”.1 Uma tarefa aguarda valores vindos da sequência e os envia para sua animação; a outra impulsiona a análise adiante. O produtor e o consumidor rodam lado a lado em vez de bloquearem um ao outro.
Para alimentar áudio ao vivo, é preciso fornecer um AudioProvider. Um AudioProvider “está em conformidade com AsyncSequence e produz objetos AVReadOnlyAudioPCMBuffer”.1 A Apple destaca o contrato de término de forma explícita: quando o provedor “tiver enviado todos os buffers de áudio, ele deve enviar um nil final para sinalizar a conclusão”.1 Esqueça o nil final e a tarefa consumidora espera para sempre por um áudio que nunca termina. O fato de o próprio provedor ser um AsyncSequence é a parte elegante: sua fonte de áudio e a saída de loudness do framework falam a mesma linguagem de iteração assíncrona de ponta a ponta.
Mais duas capacidades da sessão completam o quadro. Todo resultado do Music Understanding é codable, então exportar uma análise completa é “apenas criar um JSONEncoder e codificar os resultados da sessão”.1 E o bloco de Vídeo do app de exemplo mostra os resultados se compondo: ele “usa estrutura e andamento para criar um vídeo sincronizado à música”, identificando os intervalos de tempo das seções e então usando o andamento de cada seção (uma taxa de eventos por minuto dividida por 60 segundos) para decidir quantos clipes cabem nesse intervalo, com clipes mais curtos e rápidos nas partes enérgicas e clipes mais longos e lentos nas calmas.1
Principais conclusões
Para desenvolvedores de apps de áudio e mídia:
- Comece por
analyze(for:), não poranalyze(): nomeie apenas os tipos de análise que você renderiza para que o framework pule o restante, já que resultados não solicitados voltam comonilde qualquer forma.1 - Trate
beatsPerMinutecomo genuinamente opcional na sua UI; umnilsignifica que o framework ainda não viu duas batidas, então mostre um estado de espera em vez de um andamento falso.1 - Defina
PreferPreciseDurationAndTimingKeycomotruenoAVURLAssetantes de criar a sessão, porque a Apple vincula resultados precisos a essa flag.1
Para trabalho em tempo real e com visualizadores:
- Construa animação reativa ao áudio ao vivo sobre o
AsyncSequencede loudness (um valor a cada 100 ms) e sobre a propriedadeactivitydo instrumento, que mapeia cada instrumento para umTimedValuede intensidade ao longo do tempo.1 - Rode uma tarefa consumidora e uma tarefa de análise concorrentemente, e faça seu
AudioProviderpersonalizado enviar umnilfinal após o últimoAVReadOnlyAudioPCMBufferpara que o stream termine de forma limpa.1
Para equipes de catálogo e ferramentas:
- Ordene ou agrupe uma biblioteca de música por tonalidade ou andamento usando
KeyResulteRhythmResult, e persista as análises codificando oSessionResultcodable em JSON para reutilização.1
FAQ
O que o framework Music Understanding da Apple analisa?
Ele analisa seis áreas de uma música: tonalidade, ritmo, estrutura, andamento, atividade de instrumentos e loudness. Cada uma mapeia para um tipo de resultado (KeyResult, RhythmResult, StructureResult, PaceResult, InstrumentActivityResult e LoudnessResult) retornado dentro de um SessionResult. O framework cuida do processamento de sinais e da inferência de modelos, então nenhuma especialização em DSP ou aprendizado de máquina é necessária.1
O Music Understanding roda no dispositivo ou na nuvem?
No dispositivo. A Apple afirma que o framework “roda inteiramente no dispositivo”, então o áudio que você analisa permanece privado e funciona offline. A análise funciona em todas as plataformas Apple sem dependência de rede.1
Como obtenho apenas a análise de que preciso?
Chame analyze(for:) em vez do analyze() geral. A chamada geral preenche todos os campos do SessionResult; a chamada direcionada retorna apenas os tipos que você solicitou e deixa o restante como nil. A Apple recomenda especificar tipos “para o desempenho mais alto”, a fim de evitar cálculos desnecessários.1
Qual é a diferença entre TimedValue e RangedValue?
Um TimedValue associa um valor a um único instante CMTime, enquanto um RangedValue associa um valor a um intervalo CMTimeRange. Ambos os tipos aparecem por todo o framework: armaduras de clave chegam como ranged values, por exemplo, e a atividade por instrumento chega como timed values.1
Como construo um visualizador reativo ao áudio ao vivo com ele?
Use a API de loudness em streaming na MusicUnderstandingSession, que entrega valores por meio de um AsyncSequence a cada 100 ms de áudio analisado. Rode duas tarefas concorrentes (uma consumindo resultados, outra impulsionando a análise) e alimente áudio ao vivo por meio de um AudioProvider personalizado que esteja em conformidade com AsyncSequence, produza objetos AVReadOnlyAudioPCMBuffer e envie um nil final para sinalizar a conclusão.1
A análise de áudio no dispositivo se posiciona ao lado da outra inteligência de mídia que a Apple lançou neste ano: veja como a IA no dispositivo chega ao Spotlight e à mídia no iOS 27 e como o framework Speech se compara ao SFSpeechRecognizer para o lado áudio-para-texto do mesmo problema. Quando você superar de vez os modelos integrados da Apple, rodar seus próprios modelos no Apple silicon com o Core AI é o próximo passo. O hub completo da série é a Apple Ecosystem Series.
Referências
-
Apple, sessão 253 da WWDC 2026, Meet the Music Understanding framework. Fonte para o enquadramento de execução no dispositivo, privacidade e offline; os recursos de detecção de batidas do Final Cut Pro e de montagem no iPad; as seis áreas de análise (tonalidade, ritmo, estrutura, andamento, atividade de instrumentos e loudness) e as definições dos blocos de construção da música; a
MusicUnderstandingSessioninicializada a partir de umAVAssetou provedor de áudio;analyze()versusanalyze(for:)e oSessionResultde campos opcionais; a configuração doAVURLAssete doPreferPreciseDurationAndTimingKeyviafileImporterdo SwiftUI; os tiposTimedValue/CMTimeeRangedValue/CMTimeRange; os tiposKeyResult/KeySignature(tonic e mode),RhythmResult/beatsPerMinute(opcional abaixo de duas batidas),StructureResult(sections, segments, phrases),PaceResult,InstrumentActivityResult(ranges e activity, activity como umTimedValuede Floats) eLoudnessResult(LUFS, janelas integrated/momentary/shortTerm, peak em decibéis); oAsyncSequencede loudness em streaming entregando valores a cada 100 ms com duas tarefas concorrentes; oAudioProviderem conformidade comAsyncSequence, produzindo objetosAVReadOnlyAudioPCMBuffere enviando umnilfinal; os resultados codable e a exportação comJSONEncoder; e o algoritmo do bloco de Vídeo baseado em estrutura e andamento. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩