2014-12-22 8 views
10

Ho dati audio nel formato di dati-uri, quindi ho convertito questo uri di dati in un buffer ora ho bisogno di questi dati di buffer in un nuovo samplerate, attualmente i dati audio sono in 44.1khz e I ho bisogno di dati in 16khz, e se ho registrato l'audio utilizzando l'API RecordRTC e se registro l'audio con bassa frequenza di campionamento, ho ottenuto una voce audio distorta, quindi non riesco a ricampionare il mio buffer audio,ricampionare il buffer audio da 44100 a 16000

Se qualcuno di voi qualsiasi idea riguardo questo, per favore aiutami.

Grazie in anticipo :)

risposta

13

è possibile utilizzare un OfflineAudioContext per fare il ricampionamento, ma è necessario convertire i dati-uri a un ArrayBuffer prima. Questa soluzione funziona nel browser, non sul server, poiché è meglio inviare audio di qualità inferiore (frequenza di campionamento inferiore) sulla rete, piuttosto che inviare molti dati e ricampionare sul server.

Supponiamo che sia fatto e che i dati siano in un Float32Array chiamato YourBufferAt44100. Se si dispone di numeri interi, invece di galleggiare, di convertirli in questo modo:

for (var i = 0; i < count; i++) { 
    ints[i] = floats[i] * Math.pow(2, 16)/2; 
} 

Poi:

/* Get an OfflineAudioContext at 16000Hz (the target sample rate). 
* `durationInSamples` is the number of audio samples you have. 
* `channels` is the number of channels (1 for mono, 2 for stereo). */ 
var o = new OfflineAudioContext(channels, durationInSamples, 16000); 

/* Get an empty AudioBuffer at 44100Hz */ 
var b = o.createBuffer(channels, durationInSamples, 44100); 

/* Copy your data in the AudioBuffer */ 
for (var channel = 0; i < channels; channels++) { 
    var buf = b.getChannelData(channe); 
    for (var i = 0; i < durationInSamples; i++) { 
     buf[i] = yourBufferAt44100[i]; 
    } 
} 

/* Play it from the beginning. */ 
var source = o.createBufferSource(); 
source.buffer = b; 
source.connect(o.destination); 
source.start(0); 
o.oncomplete = function(audiobuffer) { 
    /* audiobuffer contains audio resampled at 16000Hz, use 
    * audiobuffer.getChannelData(x) to get an ArrayBuffer for 
    * channel x. 
    */ 
} 

/* Start rendering as fast as the machine can. */ 
o.startRendering(); 
+0

rapida Qn relavant. Qual è l'algoritmo di ricampionamento utilizzato internamente da FF? – notthetup

+2

Usiamo il resampler dal codec speex: http://dxr.mozilla.org/mozilla-central/source/media/libspeex_resampler/src/resample.c#35, che è ottimizzato per la velocità e una buona qualità percettiva. – padenot

+0

Un piccolo nitpick, ma importante: si noti che questo 'floats [i] * Math.pow (2, 16)/2' produrrà un valore errato quando float [i] = 1. Suggerendo usando:' ints [i] = floats [i] <0? floats [i] * 32768: floats [i] * 32767; '(o ovviamente, il caching floats [i] può aiutare le prestazioni ad evitare la ricerca di double array). – K3N