Как сделать?
…
n3m0,
я не видел зависимости между объёмом записываемых в массив данных и просадками. Хотя можно устроить небольшой тест и прогнать циклом заполнение 100 тыс элементов массива простыми числами и строками текста в пару тысяч символов и посмотреть на разницу в скорости заполнения.
Я пока что не совсем понимаю, зачем записывать данные в массив с помощью dynamic. dynamic обычно используют, когда нужно сам код сгенерировать, но оправданность его применения я без кода оценить не смогу.
n3m0:
как долго по времени, примерно, будет откликаится плеер если данные массива содержат в себе HTML теги выводимые с помощью *p
А вот тут надо чётко понимать, что ты имеешь дело с двумя совершенно разными типами задержки. И об этом сказал выше dmvikar. Когда выполняется код QSP - плеер тратит время только на его выполнение. Даже оператор *p съедает не так уж много времени, поскольку он работает с обычным текстом. Более того, все операторы вывода текста на самом деле не выводят текст, а только отправляют его в специальный буфер, из которого рендер плеера уже этот текст забирает и выводит на экран. Если у тебя до кучи включён html-рендер (usehtml = 1), то плееру дополнительно нужно обработать текст из буфера перед выводом на экран, и вот тут уже появляется вторая задержка. Если у тебя много html-кода при выводе на экран, то ты заметишь, что отрисовка подтормаживает игру. И уже не важно, в массиве твоя разметка записана, или просто в виде строки ты её выводишь, это будет подвешивать вывод.
То есть при работе с картой тебе нужно учитывать:
* скорость выполнения кода (большие многоуровневые циклы и множество операций присваивания подвешивают выполнение кода)
* скорость обработки HTML-разметки рендером (много HTML-кода подвешивает вывод на экран).
Для классического плеера последнее очень критично, а вот для qSpider уже не так. Там более быстрый браузерный HTML-рендер.
Отсюда вывод: нужно уменьшать число циклов в коде до минимума, и нужно уменьшать объёмы HTML-разметки.
В идеале с твоим проектом нужно переходить на qSpider. Он работает на qsplib версии 5.8.0, где есть настоящие циклы, которые сразу делают прирост производительности в 1,5-2 раза даже без сокращения количества циклов. А ещё у qSpider полностью браузерный HTML-рендер, который отрисовывает экран гораздо быстрее классического плеера.
Aleks Versus,
Спасибо за столь развёрнутый ответ и советы. Только у меня появился ещё один вопрос. Qspider сильно отличается от классического плеера? В том плане что, есть ли что-то ещё что нужно изучать по мимо того что есть в классическом плеера. Просто я не углублялся в другие плееры и не знаю всех, так сказать подводных камней. Сейчас подумываю перепрыгнуть на другой Qspider, но мне кажется, просто копипастнуть мой код и чтобы он работал не получиться. Это пока единственное что меня останавливает. Ещё раз спасибо.
n3m0,
Запусти и проверь). Делов-то! В основном будет проблема в форматировании, т.к. есть некоторые различия по тексту и таблицам.
Заходи в дискорд. Там легче общаться.
n3m0,
есть некоторые отличия в qSpider от классики 5.7.0, но их не так уж много. В плане кода все отличия перечислены в этой статье https://vk.com/@qsplayer-novovvedeniya-v-qsp-580
Проверил внесение данных в массив. Разница есть, и большая. Для чисел на 100 тыс элементов заполнение массива занимает у меня 250-300 мс. Фрагментом текста в 2000 знаков - 1600-1800 мс. Фрагментом текста в 4000 знаков - 3000-3200 мс. Это довольно медленно. Если есть возможность избегать заполнения таким объёмом данных, то лучше избегать.
Оффтоп: Самое обидное, что присваивания переменным кортежей из двадцати элементов дают такую же задержку, как строка в 2000 знаков. Более того. Если вместо кортежа просто присваивать подобную строку переменной, или ячейке массива, это происходит в пять раз быстрее. (
webp есть возможность использовать? из 3 GB графики в webp 700 MB
Дамир Белялов,
если проверяешь в 5.8.0 и не пашет, значит в dynamic передаёшь неверный код. У меня твой цикл работает:
max_Y = 10
max_X = 10
$src_gen_sym = {*pl $str(y_a) + ':' + $str(x_a)}
loop y_a=1 while y_a<=max_Y step y_a+=1:
loop x_a=1 while x_a<=max_X step x_a+=1:
dynamic $src_gen_sym
end
end
Понимаешь, ошибка выдается на строчке со словом “loop”. Меня напрягает, что это слово даже не подсвечивается синим, как у остальных операторов. Вот полное содержимое моей локации:
! Общая генерация границ мира
max_X[1]=24 & !допустим это максимальные границы карты №1
max_Y[1]=24
x_a=1
y_a=1
!Случайное наполнение
$scr_gen_sym={
type_sym=rand(1,5)
if type_sym=1: $x[x_a,y_a,map,'символ']='<font color="gray">.</font>' & $x[x_a,y_a,map,'описание']='камушки' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=2: $x[x_a,y_a,map,'символ']='.' & $x[x_a,y_a,map,'описание']='пол' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=3: $x[x_a,y_a,map,'символ']='ш' & $x[x_a,y_a,map,'описание']='куст' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=4: $x[x_a,y_a,map,'символ']='Т' & $x[x_a,y_a,map,'описание']='дерево' & $x[x_a,y_a,map,'тип']='стена'
if type_sym=5: $x[x_a,y_a,map,'символ']='.' & $x[x_a,y_a,map,'описание']='пол' & $x[x_a,y_a,map,'тип']='поверхность'
}
loop y_a=1 while y_a<=max_Y step y_a+=1:
loop x_a=1 while x_a<=max_X step x_a+=1:
dynamic $scr_gen_sym
end
end
Если слово не подсвечивается синим в QGen, значит его нет в keywords.xml. Можешь взять здесь: https://mega.nz/folder/jLBCQaST#RhLC2SPD9BEAIbD3hcKSXg и разместить рядом с QGen.
Вынужден спросить, ты точно запускаешь игру в QSP версии 5.8.0? Потому что у меня твой код никаких ошибок не вызывает. Если запускаешь в 5.7.0, то естественно новый синтаксис там работать не будет.
Как сделать перфект луп звука в FMOD (3.31+) без вызовов API?
“А чё, такое разве можно?”
Оказывается, что можно…
Ниже приводится пример содержимого .wav файла в хексе. Волна очень короткая: всего два гребня, примерно 1.1 мсек, разрезано через середину, концы не нули! Если воспроизвести без цикла, то никто и не поймет, что же это было. В цикле, но без идеальной стыковки, вместо чистого тона будут слышны треск/щелчки.
В любом хекс-редакторе сохраняем содержимое как *.wav и проверяем. В “обычных” QuestSoftPlayer 5.7 и 5.8, использующих FMOD Ex, можно набрать (как пример) [play ‘test.wav’, 50] и услышать…
…чистый тон! (значит FMOD чётко и без разрыва соединил концы волны) Естественно, этот способ подойдет и для полноразмерных файлов (моно 22kHz и столь малый размер, были взяты просто чтобы пример был короче).
524946469A00000057415645666D7420
10000000010001002256000044AC0000
0200100064617461320000009A19F018
B716F112F80D1108A4011AFBE7F464EF
05EBF5E789E6B7E69BE8F9EBB3F060F6
BFFC43039E094E0F03146B174319736D
706C3C000000000000000000000027B1
00003C00000000000000000000000000
00000100000000000000000000000000
00000000000018000000000000000000
0000
RIFF(150 байт)”WAVE” (как всем хорошо известно, в RIFF в размер чанка не входят идентификатор и сама величина)
“fmt “(16 байт) моно 22kHz 16-бит.
“data”(50 байт) 25 сэмплов на единственном канале, от 0 до 24 по 2 байта (по 16 бит).
[и на этом должен быть конец, однако…]
“smpl”(60 байт) чудо инженерной мысли.
Кастомное мумбо-юмбо для RIFF WAVE от создателей SoundForge, а потом ещё и от создателей FMOD (в документации к FMOD переводят стрелки - “как в SoundForge”). Чанк “smpl” был придуман для MIDI и всего такого, в WAVE его не должно быть от слова “спецификация”, но разве это кого-то волнует? (теперь уже риторический вопрос, можно не отвечать, “кузнецы” ответили). Конечно же есть чанки специально придуманные для метаданных (в LIST INFO), но умельцами был выбран именно самодельный вариант…
Разбор чанка:
x00 (736D706C) [FCC идентификатор чанка] “smpl” точно так же как это будет в ASCII.
x04 (3C) [размер чанка] 60, каждый знает что в RIFF размер считается без FCC идентификатора и самого числа, 68-4-4=60.
x10 (27B1) [период сэмпла] 45351 наносекунда = 22kHz (только для SoundForge, а для FMOD можно нули).
x14 (3С) [MIDI нота] 60я нота “средняя C” (только для SoundForge, а для FMOD можно нули).
x24 (01) [число записей о циклах в чанке] всего 1 и есть.
x2C [записи о циклах] просто всё нулями, кроме x38.
x34 (00) [кастомные данные] начало по версии SoundForge, ноль т.к. сэмплы считаются с нулевого.
x38 (18) [кастомные данные] конец по версии SoundForge, 18 hex = 24 dec
Т.е. получается, луп пойнты на нулевом и самом последнем (24й в этом файле) сэмплах (хотя можно было расставить и не так, а для FMOD можно было назначить конец хоть на FFFFFF, там всё само подправится).
В этом чанке предусмотрено еще много других стандартных величин, но их даже SoundForge не задает, т.к. это вовсе и не MIDI файл (хотя как мы знаем, у кое-кого свое мнение на этот счёт), и практического смысла в этом нет.
Очевидно, что ЭТО издевательство над *.wav файлами работает только для FMOD и SoundForge, откуда эта забава (виоляция общепризнанных спецификаций WAVE) и появилась. Всё остальное П.О. просто !должно! проигнорировать этот чанк в RIFF WAVE.
PS: Т.е. в QuestSoftPlayer 5 всё-таки можно делать идеальные циклы фоновых звуков (раз 5.7 идет с FMOD Ex 4.30, значит с момента выхода 5.7 в каком-то там году? так получается?).
(Злой Механик)
Злой Механик,
погоди, я правильно понял? Грубо говоря wav зациклится самостоятельно, если мы добавим к нему чанк “smpl” c указанными данными? Не знаю, кто привёл тебя сюда, но храни господь этого человека!
Привет, если очень коротко: 1) да, 2) сам пришел (где хочу, там и хожу).
Если же развёрнуто:
Я вроде всё чётко выше описал, но если показалось сложным, то попробую “на пальцах”. В FMOD, который используют классические QSP 5.7 и 5.8, внутри есть нетипичный код. Инженеры-программисты написали движок так, что когда FMOD читает .wav файл, то помимо всего прочего, он ещё ищет кусочек данных (чанк) “smpl”, хотя по-задумке в .wav ничего подобного не должно быть! Если он есть и внутри всё “как надо”, код внутри движка FMOD !автоматически назначит! тип автоповтора, и при воспроизведении, звук будет повторяться, даже если вызов воспроизведения не подразумевал повторение (например QSP всегда делает воспроизведение “на раз”).
Самый простой и универсальный пример чанка “smpl” в хексе (для FMOD, не для SoundForge):
736D706C3C0000000000000000000000
00000000000000000000000000000000
00000000010000000000000000000000
0000000000000000FFFFFFFF00000000
00000000
Конечный сэмпл повтора задан просто наугад: FFFFFFFF, но даже если он выходит за реальные пределы (а этот индекс МАКСИМАЛЬНО возможный), в FMOD всё скорректируется на последний (т.е в этом способе не нужно считать сэмпы для каждого отдельного случая, и ДА, это потому что так написали FMOD).
Просто в хекс редакторе добавляем чанк в самый конец .wav файла. Однако FMOD при чтении .wav четко учитывает размер родительского чанка “RIFF” (структура контейнера RIFF подразумевает понятие иерархии). Поэтому идем в самый верх .wav файла. В хексе видно, что он начинается на “RIFF”, а вот сразу за ним и идут 4 байта величины размера (для примера A1B2C300). Теперь считаем. Чанк “smpl” имеет размер (полный, вместе в FCC) 44 hex = 3С+4+4 (смотри пост выше, почему так). Просто складываем 44 и (как пример C3B2A1) в 16-системе (C3B2A1+44=C3B2E5 - значит меняем A1B2C300 в файле на E5B2C300). Почему наоборот? Если и правда спросил, ответ: “По кочану!” - в настольных системах используется Интеловское направление записи от младших разрядов к старшим (а не как у людей принято от старших к младшим). Связано это с устройством электрических цепей Интел-подобных процессоров.
Вот теперь, если этот .wav файл запустить в QSP, он будет крутиться до “второго пришествия”. Притом движок FMOD написали так, что он еще и концы волны попробует соединить без разрыва (однако если перепад у концов уж слишком большой, обязательно появится дисторция сигнала, но это должно быть очевидно. Хотя и совсем другая тема).
И есть еще один способ зацикливания, но он выглядит как перемотанный изолентой да ещё с торчащими гвоздями.
FMOD (тот что идёт с QSP) умеет читать .xm/.it/.s3m/.mod файлы - это как раз трекеры/аудио секвенсоры.
Если супер-коротко: качаем трекер, вставляем наш звуковой файл как сэмпл секвенсора на “среднюю С” ноту (чтобы тон не поменялся) и пишем композицию на бесконечный повтор одного инструмента на одной ноте, состоящего только лишь из одного сэмпла - нашего файла.
Проблема метода - в странных уровнях громкости на QSP, притом что в других .MOD проигрывателях всё норм.
По второму вопросу: Уважаю людей и сообщества которые что-то сами реально делают, а не только беконечно пи***ят “о котиках”. Я подумал, что если кто-то использует звуки в своих работах, эта инфа может быть очень полезной. Учитывая что FMOD - это все-таки не ерунда, в QSP можно делать озвучку вполне на уровне “больших игр”.
(супер-странно что зацикливание не добавили в комманду QSP play, типа : play $path, volume, loop. Каналы звука и объектные обработчики сложных звуков в QSP можно написать и самому, а вот повтор без дисторции сигнала - никак)
PS. Если ещё есть желание “хлебнуть мудрости из-горла”, там выше пост был про генерацию. Могу кое-что показать/рассказать про R.N.G.2D (да 2D, нет не простой последовательный) именно для (вот сюрприз) QSP. (~27 операций)
(Злой Механик)
Я ступил, тут можно файлы вкладывать… Вот 2 файла - попробуй их в QSP запустить. Погляди в хексе, чем они отличаются.
snd.rar
С такими тонами на начале и конце этот звук тольно нативно зацикливается, все прочие танцы с бубном бесполезны. И в QSP он-таки зацикливается на 5 из 5.
да, у меня 5.7.0 - версию я поменяю
Вот вопрос: я в основном для телефона квест пишу, а на андроид версии проблем не будет, как думаешь?
Злой Механик,
спасибо большое. Обязательно погляжу.
Дамир Белялов,
на андроиде пока что только 5.7.0 версия работает.
Возможно в скором времени появится qSpider для Андроид, он на 5.8.0, так что если у тебя долгострой, можешь сразу для qSpider делать. Можно запускать, например, с размером экрана 320х600 и смотреть, как на нём будет игра выглядеть.
