Перевод из byte массива в звук
f (this.chatSocket) { let context = new AudioContext(); let buf; this.chatSocket.onmessage = function (e) { let data = JSON.parse(e.data); let message = data['message']; let byteArray = Array(); for (let key in message) { byteArray.push(message[key]) } var arrayBuffer = new ArrayBuffer(byteArray.length); var bufferView = new Uint8Array(arrayBuffer); for (let i = 0; i < byteArray.length; i++) { bufferView[i] = byteArray[i]; } context.decodeAudioData(arrayBuffer, function (buffer) { buf = buffer; play() }); }; function play() { var source = context.createBufferSource(); source.buffer = buf; // Connect to the final output node (the speakers) source.connect(context.destination); // Play immediately source.start(0); } Здравствуйте. Пытаюсь перевести массив байтов в звук, но выдает ошибку Uncaught (in promise) DOMException: Unable to decode audio data Подскажите как решить эту проблему |
А в message какое значение получается? Судя по дальнейшей логике, там должен быть массивоподобный объект чисел 0-255:
{ 0: 8, 1: 12, 2: 19, ... } |
А почему Вы пытаетесь декодировать массив байт, он как-то закодирован? Если нет, то его бы загнать напрямую в source.buffer без декодирования, только с определённым преобразованием. А decodeAudioData() предназначена для декодирования последовательности байт, которая представляет собой полное содержимое аудиофайла какого-то стандартного формата - MP3, OGG, WAV и т. п. У них есть заголовок со служебной информацией, сколько байт занимает один семпл, моно или стерео, и т. д., чтобы было известно, как его следует декодировать.
|
Опан1,
Массив байт нельзя загнать напрямую в source.buffer, потому что массив байт это ArrayBuffer, а source.buffer это AudioBuffer. |
Я же сказал - с преобразованиями. Если я правильно помню, перед воспроизведением все семплы должны быть в пределах от -1 до 1 с запятой.
|
Опан1,
Есть всего два способа получить AudioBuffer это decodeAudioData() и createBuffer(), но для последнего аргументы неизвестны, потому что имеется только ArrayBuffer. Непонятно что тут преобразовывать... Массивы семплов тоже нельзя загнать напрямую в source.buffer, всё равно нужен экземпляр AudioBuffer. |
<button onclick="bytes_to_sound()"> Перевести из byte массива в звук </button> <script> var myarray = [], // тут будут байты для превращения в звук a = b = 0, c = 1; for(i = 0; i < 44100; i ++){ myarray.push(Math.floor(a + b)); a += c; b += c * 0.75; c /= 1.000003; if(a > 127) a = 0; if(b > 127) b = 0; } // байты готовы. ( звук сирены ) function bytes_to_sound(){ var context = new AudioContext(); var myBuffer = context.createBuffer(1, context.sampleRate, context.sampleRate); var nowBuffering = myBuffer.getChannelData(0); // наверно, екземпляр, о котором Вы говорили for (var i = 0; i < myBuffer.length; i ++) nowBuffering[i] = myarray[i] / 128 - 1; // преобразование, о котором я говорил // другими словами, чтобы пределы значений от 0 до 255 превратились в пределы значений от -1 до 1 var source = context.createBufferSource(); source.buffer = myBuffer; source.connect(context.destination); source.start(0); } </script> Это пример, показывающий, как можно массив байт перевести в звук. Ни decodeAudioData(), ни ArrayBuffer для этого не нужны. А в Вашем, symbians60v5, случае попробуйте так: <button onclick="bytes_to_sound()"> Перевести из byte массива в звук </button> if (this.chatSocket) { this.chatSocket.onmessage = function (e) { let data = JSON.parse(e.data); let message = data['message']; byteArray = new Array(); for (let key in message) { byteArray.push(message[key]); } } } function bytes_to_sound(){ let context = new AudioContext(); var myBuffer = context.createBuffer(1, byteArray.length, context.sampleRate); var nowBuffering = myBuffer.getChannelData(0); for (var i = 0; i < myBuffer.length; i ++) nowBuffering[i] = byteArray[i] / 128 - 1; var source = context.createBufferSource(); source.buffer = myBuffer; source.connect(context.destination); source.start(0); } |
Цитата:
Цитата:
|
Самый первый аргумент указывает на количество каналов. В данном случае - 1. (моно) Второй аргумент - количество семплов. Тут выходит 44100. Третий - частота семплирования воспроизведения, которая тут определяется, как частота семплирования по умолчанию. У вас, видимо, 48000, наверно зависит от звуковой карты или драйвера звуковухи. Раньше у меня была материнка с картой AC-97 и там частота по умолчанию была 44100. Третьим аргументом может быть число, задающее частоту семплирования.
|
Опан1,
Я понимаю что значат аргументы, вопрос не в этом, а в том что данные очевидно приходят от другого пользователя чата, невозможно знать какое аудио он отправит, это может быть 32 канала 98000 Гц или 10 каналов 8000 Гц, и тд. Это мы подошли к изначальному вопросу из поста 3 про зачем декодировать массив. |
Часовой пояс GMT +3, время: 16:40. |