Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Синхронное воспроизведение звуков (http://www.flasher.ru/forum/showthread.php?t=166846)

Vasyaga 06.09.2011 08:12

Синхронное воспроизведение звуков
 
Работаю над онлайн сексенсером и, как многие здесь, столкнулся с проблемой синхронного воспроизведения звуков. Итак, исходные данные: Есть 3 одинаковых объекта Sound, загруженных из одного MP3. Я воспроизвожу их одновременно по таймеру каждые 500 миллисекунд.
Вариант I: Используем Sound как есть. В этом случае звуки не проигрываются синхронно. Постоянно кто-то отстает, кто-то убегает вперед.
Вариант II: Прочитал, что подобная задержка может быть вызвана тем, что звук в MP3 и необходимо процессорное время для декодирования. Воспользовался волшебным методом Sound.extract() из FlashPlayer10 Sound API и залил содержимое MP3 в ByteArray. После этого создал 3 звука и при помощи события SampleDataEvent напрямую записывал несжатое содержимое звука:
Код AS3:

private function sampleDataHandler(evt:SampleDataEvent) : void {                        
                        var writeCount:int = (pos + SOUND_BUFFER_SIZE) > ba.length ? (ba.length - pos) : SOUND_BUFFER_SIZE;
                        if(writeCount > 0) {
                                evt.data.writeBytes(ba, pos, writeCount);                                       
                        } else {
                                pos = 0;
                                //trace('stopped');
                        }
 
                        pos += writeCount;
                }

Размер буфера (SOUND_BUFFER_SIZE) использовал максимальный для уменьшения задержек - 65536. Стало лучше, но всё равно звук сбивается!!!
Есть ли способ синхронного воспроизведения динамически подгруженных звуков?

Gaen 06.09.2011 09:52

Про внутреннюю реализацию работы флэшплеера со звуком: http://www.actionscript.org/resource...ing/Page1.html
Статья старая, но похоже до сих пор актуальна.

Genzo 06.09.2011 10:53

Цитата:

FlashPlayer10 Sound API и залил содержимое MP3 в ByteArray. После этого создал 3 звука и при помощи события SampleDataEvent напрямую записывал несжатое содержимое звука:
нужно смотреть в сторону записи всех 3х звуков в 1 дорожку(объект Sound)

Vasyaga 06.09.2011 12:55

Цитата:

Сообщение от Genzo (Сообщение 1028612)
нужно смотреть в сторону записи всех 3х звуков в 1 дорожку(объект Sound)

Идея отличная, но будет слишком много вычислений на этапе проигрывания и как следствие - тормоза. Либо нужно будет все пересчитывать каждый раз при добавлении/удалении трека. В общем от большого количества вычислений где-то в коде не уйти. Должно же быть более простое решение!!!

Genzo 06.09.2011 13:12

Код AS3:

Идея отличная, но будет слишком много вычислений на этапе проигрывания и как следствие - тормоза.

Получив 3 Sound'a вы смешиваете их в 1 ByteArray , а потом уже 1му Sound'у скармливаете этот ba через SampleDataEvent. Вычисления только 1 раз после получения всех 3х Саундов

Vasyaga 06.09.2011 13:24

Genzo, дело в том, что у меня 2 мини-секвенсера 8x16 и 84x16 и один большой секвенсер, который состоит из мини-секвенсеров. Размерность большого секвенсера - 16x25. Представьте, сколько пересчетов нужно будет сделать при замене одного звука/секвенсера.

Genzo 06.09.2011 13:37

Цитата:

Genzo, дело в том, что у меня 2 мини-секвенсера 8x16 и 84x16 и один большой секвенсер, который состоит из мини-секвенсеров. Размерность большого секвенсера - 16x25. Представьте, сколько пересчетов нужно будет сделать при замене одного звука/секвенсера.
Представляю , но как по мне единственно правильный вариант это сводить все в 1 дорожку программно и воспроизводить ибо 100 Sound'ов тоже не вариант.

Добавлено через 1 минуту
Сводить все в 1 дорожку правильнее со всех сторон :
++Так проще сохранить , меньше ресурсов тратиться
--При каждом воспроизведении или изменении необходимо "пере-сводить"

Vasyaga 06.09.2011 13:53

С кучей Sound'ов работает более-или менее прилично и без тормозов. Только не синхронно :) Тем более, что я не пложу ByteArray, а храню их отдельно в Dictionary, используя в качестве ключа путь к mp3. Т.е. если я добавляю один и тот же звук несколько раз, то будет использован один ByteArray.
В случае вашего варианта - конкретный 4-х секундный звук после extract-а занимает 160 Кб. Соответственно, чтобы сложить 2 таких звука я должен сделать около 50 тыс. операций только сложения (2 канала по 32 бита) + еще нужно делить для выравнивания громкости. А если таких звуков хотя бы 10? Да и для юзера всё станет не так прозрачно - перетащил ячейку в секвенсере - получи прогресс бар и несколько секунд задержки ;) Нет, с микшированием идея интересна, но не вариант :(

Genzo 06.09.2011 14:01

Цитата:

Да и для юзера всё станет не так прозрачно - перетащил ячейку в секвенсере - получи прогресс бар и несколько секунд задержки
Делать микширование только после нажатия кнопки play и только в случае если были изменения.

alatar 06.09.2011 14:09

Сводить динамически в обработчике SamplerDataEvent.

Vasyaga 06.09.2011 15:17

Пытаюсь сводить динамически. Но это точно скажется на использовании памяти ибо я должен буду иметь byte array на каждый 'тик' таймера. То есть планирую сводить по вертикали. Может есть еще другие варианты?

alatar 06.09.2011 15:35

Зачем? У тебя уже есть ByteArray — event.data. В него и сливай данные из семплов.

P.S. Если семплы короткие, то особого смысла хранить их в mp3 нет, можно сразу грузить сырые данные.

Vasyaga 07.09.2011 19:33

Да, семплы короткие и я уже их храню в сыром виде. А вот сразу грузить в event.data будет проблемно - слишком много операций при микшировании дадут тормоза при проигрывании.

alatar 07.09.2011 19:46

Много это сколько? Возьмите буфер меньше. В конце-концов, не долго и экспериментально проверить. Это будет продуктивнее рассуждений.

Vasyaga 08.09.2011 08:21

Уже проверяю, обязательно отпишусь по результатам ;)

Добавлено через 56 часов 12 минут
Итак, как результат: при микшировании в SampleDataEvent даже 3 звуков тормозит, сбивается таймер и т. д. Но самое главное - возникает проблема регулировки уровня звука/баланса для треков в отдельности при проигрывании - ведь нужно всё снова пересчитывать, а звук уже был запущен и блок данных уже записан и его не вернуть ;(
Может есть еще какие-либо варианты? Гуру, отзовитесь!

Добавлено через 59 часов 51 минуту
Попытался написать простой тест: Беру массив из 3 объектов типа Sound. Загружаю в них одинаковые звуки. Когда у всех сработает LoadComplete, запускаю таймер и на каждый тик запускаю Sound.play() в цикле для каждого звука массива, т.е. одновременно. Рассинхрон налицо - слышно невооруженным ухом :) Люди, предлагайте еще идеи ибо фантазия иссякает! Или все-таки синхронного воспроизведения добиться невозможно?

alatar 11.09.2011 02:05

http://www.kaourantin.net/2008/10/au...el-bender.html

Vasyaga 11.09.2011 09:46

alatar, спасибо за ссылку. Я вообще-то не силен в PixelBlender, но вижу, что там количество миксуемых треков статично - 15 шт. Есть ли возможность сделать его динамическим?

Добавлено через 3 минуты
Вот нашел: http://www.blixtsystems.com/2010/10/...c-track-count/
Буду пробовать ;) Еще раз спасибо!


Часовой пояс GMT +4, время: 00:39.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.