;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Fale e eu te escuto: como funciona o reconhecimento por voz

Rodrigo Lara

Colaboração para Tilt

12/03/2020 04h00

Você já falou com o seu smartphone hoje? Não estou me referindo a fazer ou receber ligações, mas comandar o celular via comandos de voz. No início é um pouco estranho, mas uma vez que a gente se acostuma a executar tarefas em assistentes como o Alexa, da Amazon, usar a voz se mostra, muitas vezes, algo mais rápido e prático do que apertar botões ou telas sensíveis ao toque.

Mas você sabe o que acontece entre você falar com o seu gadget e ele fazer o que você quer? De maneira geral, o reconhecimento de voz segue alguns os básicos, partindo da transformação das ondas sonoras em dados.

A conversão de voz em dados é assim: a amostra de voz é comparada a padrões em uma base de dados. Havendo um "match" entre a amostra recolhida e as registradas, o comando é "entendido" pelo aparelho e, em seguida, executado.

Por exemplo, um "Ok, Google" vindo de sua voz fará sentido ao assistente porque sua base de dados tem gravada essa sequência de fonemas, vai comparar com o vindo de sua voz, e se houver semelhança, o assistente é ligado.

Os algoritmos que atuam no reconhecimento de voz usam complexos modelos estatísticos, como o Hidden Markov Model (HMM) —aplicado em reconhecimento de padrões. Eles combinam informações acústicas e determinam quais frequências estão presentes em qual instante de tempo para calcular qual a palavra mais provável que a pessoa está falando.

Eles também levam em conta outros aspectos, como informações de linguística e sintaxe para determinar quais sequências de palavras são as mais prováveis.

Isso é especialmente útil quando usamos palavras que são idênticas foneticamente, mas têm diferentes sentidos, como por exemplo "pelo", que pode ser tanto um substantivo quando uma contração.

Nos últimos anos, o reconhecimento de voz ganhou precisão e rapidez. Isso tem uma explicação: em alguns assistentes, as amostras de voz não são processadas nos aparelhos em si — no caso, o seu smartphone, ou o Amazon Echo, ou o Google Home etc.

Ao serem "recolhidas", as amostras de voz são enviadas para centrais de processamento, onde supercomputadores fazem todos os cálculos necessários para interpretar o comando de voz e executar a sua demanda.

Como os computadores "aprendem" a falar?

O segredo disso tudo é o aprendizado de máquina. No reconhecimento de voz, esse tipo de aprendizado leva algoritmos a analisar enormes quantidades de dados para identificar padrões e "aprender" usando exemplos.

Para isso, cria-se uma arquitetura de rede neural —um sistema parecido com o sistema nervoso humano— e depois alimenta-se essa rede com arquivos de áudio com falas gravadas. Após processar nossas perguntas, o sistema precisa devolver uma resposta ao usuário. Assim, busca nesse banco de áudios os sons que correspondem à transcrição dessa resposta. Os erros nesse processo são usados para fazer ajustes e treinar essa rede, para que ela fique cada vez mais precisa.

Como é feito o reconhecimento de vozes específicas?

Alguns assistentes por voz podem ser treinados para reconhecer apenas a voz do usuário. Neste caso, é criada uma espécie de , que permitirá ao aparelho identificar o dono da voz e responder (ou não) aos comandos.

E no caso dos sotaques? Como se entende a mesma palavra pronunciada de formas distintas?

As redes neurais acabam ajudando. Para isso, é preciso haver exemplos de gravações nos mais diversos sotaques. A partir daí, a máquina "aprende" a reconhecer esses sotaques.

Fontes:

Bruno Masiero, professor da Faculdade de Engenharia Elétrica e de Computação da Universidade Estadual de Campinas (Unicamp)
Helton Marinho, CEO da NinSaúde
Raphael Avellar, especialista em marketing digital e CEO da Avellar Media

Toda quinta, Tilt mostra que há tecnologia por trás de (quase) tudo que nos rodeia. Tem dúvida de algum objeto? Mande para a gente que vamos investigar.

SIGA TILT NAS REDES SOCIAIS