Design de Som para Apps
Toma as decisões de design sobre quando, o que e como os sons devem aparecer em aplicações. Isso não é sobre engenharia de áudio (isso é sound-engineer) ou efeitos sonoros retrô (isso é win31-audio-design). Este skill responde à pergunta mais difícil sobre som em UI: essa interação deve fazer barulho? E se sim, que tipo?
Quando Usar
Use para:
- Decidir quais interações em um app web ou mobile devem ter feedback sonoro
- Selecionar características sonoras apropriadas para notificações, confirmações, erros
- Criar sons de UI gerados por IA com ElevenLabs, AudioCraft ou Stable Audio
- Implementar sons processuais com Web Audio API
- Parear feedback háptico com áudio em iOS/Android
- Estabelecer uma identidade de marca sônica para um produto
- Auditar o design de som existente de um app quanto à irritação vs. utilidade
NÃO use para:
- Mixagem/masterização de áudio profissional -> use sound-engineer
- Sons de sistema temáticos do Windows 3.1 -> use win31-audio-design
- Composição musical ou trilha sonora -> use sound-engineer
- Áudio de leitor de tela de acessibilidade -> use accessibility-expert
- Sistemas de áudio de jogos (posicional 3D, música dinâmica) -> use sound-engineer
A Pergunta Fundamental: Essa Interação Deve Fazer Som?
A interação precisa de FEEDBACK?
|
+-- Ação iniciada pelo usuário (toque, clique, envio)?
| +-- O resultado é visível na tela?
| | +-- SIM e óbvio --> Som é OPCIONAL (geralmente pule)
| | +-- SIM mas sutil --> Som AJUDA (confirmação suave)
| | +-- NÃO (processo em segundo plano) --> Som RECOMENDADO
| +-- A ação é destrutiva?
| +-- SIM --> Som RECOMENDADO (tom de aviso distinto)
| +-- NÃO --> Som OPCIONAL
|
+-- Evento iniciado pelo sistema (notificação, alerta)?
| +-- O usuário está no app?
| | +-- SIM --> Som sutil no app
| | +-- NÃO --> Som de notificação (siga convenções do SO)
| +-- É sensível ao tempo?
| +-- SIM --> Som mais urgente/chamativo
| +-- NÃO --> Pode ser silencioso ou ambiente
|
+-- Ambiente/atmosférico (estado de fundo)?
+-- O app se beneficia de presença? --> Ambiente sutil
+-- O usuário está trabalhando/focado? --> SILÊNCIO
O Vocabulário de Som de UI
Cada aplicação precisa de sons dessas categorias. Nem todas as categorias são obrigatórias — a maioria dos apps precisa de 3 a 5.
Nível 1: Essencial (A Maioria dos Apps Precisa)
| Tipo de Som | Propósito | Caráter | Duração | Exemplo |
|---|---|---|---|---|
| Confirmação | Ação bem-sucedida | Brilhante, tom ascendente | 100-300ms | Mensagem enviada no Slack |
| Erro | Ação falhou | Grave, plano ou descendente | 200-400ms | Falha na validação de formulário |
| Notificação | Nova informação chegou | Distintivo, energia média | 300-600ms | Mensagem recebida no Slack |
Nível 2: Polimento (Apps que se Importam)
| Tipo de Som | Propósito | Caráter | Duração | Exemplo |
|---|---|---|---|---|
| Transição | Navegação entre telas | Sussurro ou toque sutil | 50-150ms | Virar página no iOS |
| Alternância | Mudança de estado binário | Clique ou estalo nítido | 50-100ms | Ligar/desligar interruptor |
| Hover | Feedback ao passar o mouse | Tique quase inaudível | 20-50ms | Hover em item de menu |
| Seleção | Item escolhido em lista | Pop ou pluck suave | 50-150ms | Seleção em dropdown |
| Excluir | Remoção destrutiva | Baque oco ou swoosh | 150-300ms | Ação de lixeira |
Nível 3: Encanto (Apps com Personalidade)
| Tipo de Som | Propósito | Caráter | Duração | Exemplo |
|---|---|---|---|---|
| Conquista | Marco atingido | Musical, celebratório | 500ms-2s | Lição concluída no Duolingo |
| Ambiente | Presença de fundo | Em loop, atmosférico | Contínuo | Noisli, app Forest |
| Marca Sonora | Abertura/fechamento do app | Icônico, memorável | 500ms-1.5s | Ta-dum da Netflix |
| Easter Egg | Prazer escondido | Divertido, inesperado | Variável | Recompensa do código Konami |
Convenções de Plataforma
Apple (iOS / macOS)
As HIG da Apple determinam comportamentos de áudio específicos:
- Sons do sistema são sagrados: Nunca substitua ou sobrescreva sons de alerta do sistema
- Respeite o botão de mudo: Se o botão físico de mudo estiver ativado, seus sons do app PARAM (exceto reprodução de mídia)
- Categorias de sessão de áudio importam:
ambient— mistura com outro áudio, respeita o botão de mudosoloAmbient— silencia outro áudio, respeita o botão de mudoplayback— ignora o botão de mudo (apenas para apps de mídia)
- Hápticos pareiam com sons: Use
UIImpactFeedbackGeneratorjunto com áudio
Características de Som da Apple:
- Ondas senoidais limpas e tons filtrados
- Mínimos harmônicos (puro, não zumbido)
- Decaimento curto (sons não perduram)
- Volume consistente em relação aos sons do sistema
// iOS: Tocar um som do sistema
import AudioToolbox
AudioServicesPlaySystemSound(1057) // Clique de teclado padrão
// iOS: Háptico + som personalizado
let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()
// Toque seu som personalizado simultaneamente
Material Design (Android)
Princípios de design de som do Google:
- Funcional primeiro: O som deve informar, não decorar
- Sutil por padrão: Sons de UI devem ser mais baixos que mídia
- Háptico primeiro no Android: Prefira feedback háptico; adicione som apenas quando os hápticos forem insuficientes
- Som LIGADO apenas quando significativo: O estado padrão deve ser silencioso para a maioria das interações
Características de Som do Material:
- Sons percussivos curtos e nítidos
- Conteúdo harmônico sutil (não ondas senoidais puras)
- Ligeiramente mais quente que Apple (mais frequência média)
- Projetados para funcionar em alto-falantes de celular de baixa qualidade
Apps Web
A web tem as convenções de som MAIS FRACAS, o que significa mais liberdade, mas também mais risco de irritação.
- Nunca reproduza som automaticamente — navegadores bloqueiam e usuários odeiam
- Exija gesto do usuário primeiro: A Web Audio API requer uma interação do usuário antes de tocar
- Forneça controle de volume: Sempre permita que os usuários mutem ou ajustem
- Considere usuários de fone de ouvido: O que soa bem em alto-falantes de laptop pode ser chocante em fones
Criando Sons com IA
Efeitos Sonoros ElevenLabs
Melhor para: Sons de UI realistas e de alta qualidade com descrições de caráter específicas.
# Gerar um toque de confirmação
curl -X POST "https://api.elevenlabs.io/v1/sound-generation" \
-H "xi-api-key: SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"text": "Short bright upward chime, digital, clean sine wave, 200ms, UI confirmation sound",
"duration_seconds": 0.5
}'
Prompts eficazes para ElevenLabs:
- Confirmar: "Short bright ascending two-note chime, clean digital, warm, 200ms"
- Erro: "Low hollow thud with slight buzz, digital, 300ms, not harsh"
- Notificação: "Gentle three-note xylophone melody, friendly, 400ms"
- Alternância: "Crisp mechanical click, plastic switch, 50ms"
- Excluir: "Soft hollow swoosh moving downward, 200ms"
- Conquista: "Bright ascending arpeggio, sparkly, celebratory, 1 second"
Meta AudioCraft (Código Aberto)
Melhor para: Desenvolvedores que querem controle total e sem custos de API.
from audiocraft.models import AudioGen
from audiocraft.data.audio import audio_write
model = AudioGen.get_pretrained('facebook/audiogen-medium')
model.set_generation_params(duration=0.5)
# Gerar sons de UI
descriptions = [
"short digital confirmation beep, ascending pitch, clean",
"low error buzz, brief, not harsh, digital",
"gentle notification chime, two notes, pleasant",
]
wav = model.generate(descriptions)
for i, w in enumerate(wav):
audio_write(f'ui_sound_{i}', w.cpu(), model.sample_rate)
Stable Audio Open
Melhor para: Sons ambientes mais longos, texturas de fundo, marcas sonoras.
import torch
from stable_audio_tools import get_pretrained_model
from stable_audio_tools.inference.generation import generate_diffusion_cond
model, model_config = get_pretrained_model("stabilityai/stable-audio-open-1.0")
# Gerar ambiente de fundo
conditioning = [{
"prompt": "calm ambient digital texture, warm low hum, suitable for productivity app background, loopable",
"seconds_total": 10
}]
Checklist de Pós-Processamento
Sons gerados por IA precisam de limpeza antes do lançamento:
- Cortar silêncio — remova ar morto no início/fim
- Normalizar volume — todos os sons de UI devem ter volume percebido consistente
- Fade in/out — 5-10ms de fade evitam artefatos de clique
- Comprimir faixa dinâmica — sons de UI devem ter volume consistente
- Exportar como WAV (para nativo) ou OGG/MP3 (para web, abaixo de 50KB por som)
- Testar nos alto-falantes alvo — alto-falantes de celular cortam frequências abaixo de 200Hz
Web Audio API: Sons Processuais
Para apps web, gerar sons processualmente elimina a necessidade de arquivos de áudio completamente. Pacotes menores, disponibilidade instantânea.
class UISound {
private ctx: AudioContext | null = null;
private getContext(): AudioContext {
if (!this.ctx) {
this.ctx = new AudioContext();
}
return this.ctx;
}
/** Confirmação ascendente brilhante */
confirm(): void {
const ctx = this.getContext();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'sine';
osc.frequency.setValueAtTime(600, ctx.currentTime);
osc.frequency.linearRampToValueAtTime(900, ctx.currentTime + 0.15);
gain.gain.setValueAtTime(0.15, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.2);
osc.start(ctx.currentTime);
osc.stop(ctx.currentTime + 0.2);
}
/** Tom de erro descendente grave */
error(): void {
const ctx = this.getContext();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'triangle';
osc.frequency.setValueAtTime(400, ctx.currentTime);
osc.frequency.linearRampToValueAtTime(200, ctx.currentTime + 0.3);
gain.gain.setValueAtTime(0.12, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.35);
osc.start(ctx.currentTime);
osc.stop(ctx.currentTime + 0.35);
}
/** Clique sutil para alternâncias e seleções */
click(): void {
const ctx = this.getContext();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'square';
osc.frequency.setValueAtTime(800, ctx.currentTime);
gain.gain.setValueAtTime(0.08, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.05);
osc.start(ctx.currentTime);
osc.stop(ctx.currentTime + 0.05);
}
/** Melodia de notificação de três notas */
notify(): void {
const ctx = this.getContext();
const notes = [523, 659, 784]; // C5, E5, G5
notes.forEach((freq, i) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'sine';
osc.frequency.setValueAtTime(freq, ctx.currentTime);
const start = ctx.currentTime + i * 0.12;
gain.gain.setValueAtTime(0, start);
gain.gain.linearRampToValueAtTime(0.12, start + 0.02);
gain.gain.exponentialRampToValueAtTime(0.001, start + 0.15);
osc.start(start);
osc.stop(start + 0.15);
});
}
}
// Uso
const sound = new UISound();
document.querySelector('#submit')?.addEventListener('click', () => sound.confirm());
Pareamento Háptico-Áudio (Mobile)
Em mobile, hápticos e áudio devem ser projetados como uma UNIDADE. O háptico chega primeiro (feedback físico imediato), o som chega depois (confirmação e caráter).
Guia de Pareamento
| Interação | Háptico | Som | Tempo |
|---|---|---|---|
| Tocar botão | Impacto leve | Clique curto | Simultâneo |
| Alternar interruptor | Impacto médio | Estalo nítido | Háptico 10ms antes do som |
| Puxar para atualizar | Tique de seleção durante puxada; notificação ao completar | Som de esticamento sutil; toque de confirmação | Háptico lidera por 20ms |
| Deslizar para excluir | Impacto pesado no limite | Swoosh oco | Háptico no ponto de confirmação |
| Pressionar longo | Rígido contínuo | Zumbido baixo crescente | Háptico começa com o som |
| Sucesso | Padrão de sucesso (triplo toque) | Arpejo ascendente | Alinhado ao ritmo |
Implementação iOS
import UIKit
import AVFoundation
class FeedbackManager {
static let shared = FeedbackManager()
private let lightImpact = UIImpactFeedbackGenerator(style: .light)
private let mediumImpact = UIImpactFeedbackGenerator(style: .medium)
private let heavyImpact = UIImpactFeedbackGenerator(style: .heavy)
private let notificationFeedback = UINotificationFeedbackGenerator()
func tapConfirm() {
lightImpact.impactOccurred()
SoundPlayer.play(.confirm)
}
func errorShake() {
notificationFeedback.notificationOccurred(.error)
SoundPlayer.play(.error)
}
func deleteCommit() {
heavyImpact.impactOccurred()
SoundPlayer.play(.delete)
}
}
A Psicologia dos Sons Satisfatórios
Por que alguns sons de UI parecem "certos" e outros parecem "baratos":
Propriedades de Sons Satisfatórios
| Propriedade | Por Que Funciona | Exemplo |
|---|---|---|
| Tom sobe | Sinaliza progresso, otimismo, conclusão | Toques de confirmação SOBEM |
| Decaimento curto | Parece responsivo e controlado | Sons de menu do Nintendo |
| Riqueza harmônica | Parece orgânico e quente | Som de "batida" do Slack |
| Volume consistente | Parece profissional e previsível | Sons do sistema Apple |
| Alinhamento rítmico | Parece intencional e projetado | Contador de sequência do Duolingo |
Propriedades de Sons Irritantes
| Propriedade | Por Que Incomoda | Evite |
|---|---|---|
| Repetitivo sem variação | Humanos se habituam, depois ficam irritados | Mesmo som exato 100x/dia |
| Muito alto em relação ao contexto | Quebra a concentração |
...
[truncado para tradução]