Просмотр полной версии : AY-player для linyx?
чем пользуются линуксоиды для прослушивания AY-музык (или им не надо?). сейчас просто сделал библиотечку для эмуляции ковоксов, биперов, AY-ков и т.п. получилась очень маленькая, совсем не жрущая cpu (в отличие от известных winamp-плагина и плейера), легкая в использовании. как пример я сделал консольный VTX-плейер (приинклюдив исходники архиватора AR для распаковки LHA, 89-го года, полдня фиксил баги после перекомпиляции его в 32 бита)
это я к чему. плейер играет музыку через единственную функцию "отдать блок на воспроизведение", что можно заменить в линуксе на свою (даже запись семплов в спец-файл /dev/<чего-то-там> подойдёт). пока вместо плей-листов можно использовать shell-скрипт, запустив плейер по очереди с разными файлами
дальше, если прилепить любое ядро эмуляции Z80, можно проиграть и PT3/STP/STC/PT2... всё, что умеет, к примеру, ZX-Amp (если загрузить в эмулятор его плейер)
интересно услышать, насколько нужен полноценный плейер (для windows-то уже есть), с определением времени воспроизведения AY и SNA-файлов, перемоткой и пр.
если появятся желающие, можно будет начать делать на 2 платформы - универсальная билиотека + на её основе плагины к винампу и там не знаю к чему на линуксе плагины есть
вот версия для win32 с исходниками и набором музык
Электрик
29.01.2006, 20:41
Плагин для XMMS под один AY-формат уже есть - SquareTone. Там правда PT3, а тут VTX - и там и там надо конвертить, а это suxx. :mad: Вот чего бы мне хотелось - плагин с синтезом от AY_Emul и всеми его фишками прилепленный к винампу, foobar2000 или линуксовому XMMS. Всёж таки приятнее, когда всё в одной программе. :rolleyes:
Кстати, AY_Emul прекрасно пашет под Wine.
По поводу быстродействия кстати поясни - как может эмуляция AY и CPU (я правильно понял?) быть быстрее только эмуляции AY?
чем пользуются линуксоиды для прослушивания AY-музык (или им не надо?). ехем... aylet'om, который только .ay файлы играет... довольно малорадостная штука ))
сейчас просто сделал библиотечку для эмуляции ковоксов, биперов, AY-ков и т.п. получилась очень маленькая, совсем не жрущая cpu (в отличие от известных winamp-плагина и плейера), легкая в использовании. как пример я сделал консольный VTX-плейер (приинклюдив исходники архиватора AR для распаковки LHA, 89-го года, полдня фиксил баги после перекомпиляции его в 32 бита)
о, здорово, сталбыть не придется сорцы US корежить, чтобы нормальную AYку сделать в эмуле :)
если появятся желающие, можно будет начать делать на 2 платформы - универсальная билиотека + на её основе плагины к винампу и там не знаю к чему на линуксе плагины есть
вот версия для win32 с исходниками и набором музыкя -- желающий.
попробовал скомпилить само ядро (sndrender) под линухом, через пять минут правки кода собралось (ессно, работает ли -- не проверял, для этого еще и сам плеер нужно портировать или плагин к xmms писать, но не вижу причин, чтоб не работало).
пристегиваю измененное файло -- интересно, под виндами теперь соберется? ,)
не соберётся - другой смысл у прагмы pack с 2-мя параметрами
pack(push, 1) на MSVC будет ждать парный pack(pop, 1), т.е. 1 тут - просто идентификатор
самое странное - замена
union SNDSAMPLE
{
DWORD sample; // left/right channels in low/high WORDs
struct { WORD left, right; }; // or left/right separately
};
на
union SNDSAMPLE
{
DWORD sample; // left/right channels in low/high WORDs
struct rl { WORD left, right; }; // or left/right separately
};
как оно скомпилировалось? ведь 2-й вариант определяет описание класса rl внутри пространства имён SNDSAMPLE, но не объявляет внутри SNDSAMPLE экземпляр rl. т.е. код sample.left - ошибочный (не компилируется MSVC)
предлагаю
struct SNDCHANNELS
{
WORD left, right;
};
union SNDSAMPLE
{
DWORD sample; // left/right channels in low/high WORDs
SNDCHANNELS ch; // or left/right separately
}; - должно везде собираться
странно, почему const не работает. на самом деле те константы типа unsigned, они передаются в unsigned-параметры функций (хотя msvc не выдаёт warning'ов и при int), но они могут вдруг использоваться и в сравнениях
вариант
const unsigned TICK_FF=6; компилируется gcc?
я -- желающий
ну попробуй LHA-депакер портировать..
Кстати, AY_Emul прекрасно пашет под Wine.а, значит, не особо нужно
По поводу быстродействия кстати поясни - как может эмуляция AY и CPU (я правильно понял?) быть быстрее только эмуляции AY?так сделать медленнее - не проблема ;-) особенно когда надо сделать чтобы быстрее заработало
попробовал скомпилить само ядро (sndrender) под линухом, через пять минут правки кода собралось (ессно, работает ли -- не проверял, для этого еще и сам плеер нужно портировать или плагин к xmms писать, но не вижу причин, чтоб не работало).
а ты раскомментируй запись семплов в файл и сотри запись в звукарту. потом открой эти raw data каким-нить звуковым редактором
не соберётся - другой смысл у прагмы pack с 2-мя параметрами
pack(push, 1) на MSVC будет ждать парный pack(pop, 1), т.е. 1 тут - просто идентификатор а GCC этот параметр воспринимает как новый alignment. и прагму пуш без параметра GCC (по крайней мере 3.3.2) не ест. сталбыть ifdef'ами это хозяйство...
самое странное - замена
union SNDSAMPLE
{
DWORD sample; // left/right channels in low/high WORDs
struct { WORD left, right; }; // or left/right separately
};
на
union SNDSAMPLE
{
DWORD sample; // left/right channels in low/high WORDs
struct rl { WORD left, right; }; // or left/right separately
};
как оно скомпилировалось? ведь 2-й вариант определяет описание класса rl внутри пространства имён SNDSAMPLE, но не объявляет внутри SNDSAMPLE экземпляр rl. т.е. код sample.left - ошибочный (не компилируется MSVC)
да, глючу %)...
чтобы пропер вариант с именованным экземпляром структуры, объявлять ее отдельно не надо. (но в коде придется вместо sample.left писать sample.ch.left)
вариант
const unsigned TICK_FF=6; компилируется gcc?
ага, главное, чтоб тип был.
ну попробуй LHA-депакер портировать..
ок, займусь
+sndrender: сейчас собирается MSVC?
а ты раскомментируй запись семплов в файл и сотри запись в звукарту. потом открой эти raw data каким-нить звуковым редакторомготово. все вроде ок, но форма волны какая-то странная (см картинку) -- ужатая в половину диапазона.
Кто-нибудь может написать простейшую DLL для проигрывания
VTX? (ну или PSG).
Для c64 есть, а для AY все никто не может написать, обидно.
насчет формы волны -- хм, оказывается, она во всех плеерах и эмуляторах такая... почему, интересно? звук 8и битным по сути выходит...
upd. даа, спать надо больше... не 8и битным, а 15и )
готово. все вроде окв глюкалке я подсмотрел, что запись в семплов в файл /dev/dsp даёт звук. правда, перед этим там делается ioctl для установки частоты оцифровки
там, кстати, ошибка: SOUND_ARRAY_LEN=1000, когда теоретически за кадр пентагон может сделать 71680t/7t > 10000 записей в регистры, в турбе - вдвое больше. просто повезло, что нет программы, состоящей подряд из одних out'ов в порт AY
и там в каждом кадре выдаётся одинаковое число семлов (SOUND_TICKS_PER_FRAME), когда SNDRENDER может выдавать переменное число (в пределах +-1), причём разное для разных источников (AY, beeper, ...) сейчас вот думаю, сделать чтоли класс, суммирующий такие потоки
ужатая в половину диапазона
сам чип однополярный (питается 0,+5). эмулятор даёт диапазон от 0 до global volume (в плейере #7FFF). хотелось совместить "тишину" чипа с нулевой громкостью
раньше в unreal использовался диапазон -#8000..#7FFF - были щелчки на макс. громкости (переход -#8000 <--> 0) при входе в отладчик, диалоги и т.п.
если так важно, попробуй прикрутить дифференцирование и усиление к сигналу
сейчас собирается MSVC?
да, вот
в-общем, надо вынести в отдельный файл различия, чтобы по 10 раз не менять
вот, прикрутил линуховый звук... заодно сделал цикл по именам файлов, чтоб "vtxplay *" можно было делать. слушаю :)
блин, SMT, РЕСПЕКТ! наконец-то музыку можно послушать нормально.
напишу плагин к xmms (или beep?), ей-ей напишу ;)
DLL с каким интерфейсом?
Я в этих делах не очень шарю.
Хватит вполне что-то типа Midas11.Dll
Play, Volume, ну и чтобы перемотать можно было в произвольный отрезок.
надо будет ещё такую фишку сделать:
прикрутить туда ядро z80 и бульбовский плеер для zx, чтоб PT2 PT3 можно было слушать.
ну или как нибудь по другому (может так сделать как в AyEmul-e ?) чтоб не только vtx-ы можно слушать было.
ибо ломает конвертить.
вот думаю сделать класс Song с методами load_from_file (с авто-определением формата), getlenght, get/set_property (такие, как автор, год, название и т.п.)
и класс Player с методами load(Song), seek, PlayToBuffer (выдаёт небольшой кусок звука в буфер, периодически вызывая, можно собрать всю песню), get_position
правда, такой интерфейс будет доступен только из c++, заворачивать в dll - это написать переходник для каждого метода, включая конструкторы/деструкторы. думаю, при реальной необходимости это сделает тот, кому это надо (если не захочет юзать c++) - писанины будет много, но вся она однотипная
думаю, при реальной необходимости это сделает тот, кому это надо
Короче как всегда.
вот думаю сделать класс Song с методами load_from_file (с авто-определением формата)
а можно автоопределение формата в отдельный метод вынести? и добавить выдирание метаинформации из файла (автор, название, tracker, с плеером или без и т.д.) отдельным методом
правда, такой интерфейс будет доступен только из c++, заворачивать в dll - это написать переходник для каждого метода, включая конструкторы/деструкторы.
а автогенерировать такую plain C обертку нельзя?
автогенерировать такую plain C обертку нельзя?
например, чем? для метода int Player::LoadSong(Song *song) сделать
__declspec(dllexport) __stdcall int Player_LoadSong(int hPlayer, int hSong)
{
return ((Player*)hPlayer)->LoadSong((Song*)hSong);
}написать генерилку сложнее, чем самому всё проделать. и есть большие сомнения, что dll-вариант окажется кому-то нужным
например, чем?
perl/python/javascript или любой другой скриптовый язык. когда/если C++ интерфейс опубликуешь, я могу попробовать...
и есть большие сомнения, что dll-вариант окажется кому-то нужным
если будут методы которые я просил, то как минимум я к фарским плагинам эту dll'ку прикручу
ты же на с/с++ пишешь плагины? можно и статически слинковать. правда DLL хорош тем, что можно независимо обновлять плагины и плейер
легче всего классы пометить как экспортируемые, чтобы автоэкспортировались функции вроде
?render@SNDRENDER@@QAEIPAUSNDOUT@@IIPATSNDSAMPLE@@ @Z
вместо
public: unsigned int __thiscall SNDRENDER::render(struct SNDOUT *, unsigned int,unsigned int,union SNDSAMPLE *)хотя этот вариант привязывает к компилятору, BC и VC по-разному "заворачивают" типы и параметры методов
вообще-то пока рано делить шкуру неубитого медведя, ещё интерфейс даже не готов. вот теперь думаю, для модуля нужен список свойств, которые можно прочитать, и тех, которые можно редактировать (у VTX-то полно свойст, а у STC всего одно - название песни)
ты же на с/с++ пишешь плагины? можно и статически слинковать. правда DLL хорош тем, что можно независимо обновлять плагины и плейер
зришь в корень! кроме того можно иметь одну копию dll'ки в системе и обновлять только ее...
вообще-то пока рано делить шкуру неубитого медведя, ещё интерфейс даже не готов.
согласен, в конце концов если интерфейс будет достаточно стабильным, обертку можно один раз руками будет сделать...
вот теперь думаю, для модуля нужен список свойств, которые можно прочитать, и тех, которые можно редактировать
а вот на эту тему хорошо бы с Сергеем Бульбой пошептаться...
отъ xmms-плагин...
раззиповать, сделать "make plugin", скопировать образовавшийся libvtxplay.so в каталог, где xmms держит плагины ввода.
(у меня это /usr/lib/xmms/Input)
кстати, оказывается, есть уже один vtx-xmms-плагин под линух %)
тута: http://sashnov.nm.ru/ayengine.html
и библиотека эмуляции AY/YM там тоже есть
хм, граждане, у которых уши не из зада^H^H^H^H подмышки растут -- как считаете, которая эмуляция больше на железку похожа? :rolleyes:
а оно только vtx-ы играет?
а оно только vtx-ы играет?
ну да. вот сделает SMT анонсированный класс Song со всякими разными форматами, будет остальное ;)
ну тогда я подожду, ибо в vtx у меня ровно 1 музон ^_~
времени у меня сейчас не очень, но пока про проект не забыли, буду поддерживать к нему минимальный интерес.
вот прикрутил PT2/PT3 и подготовил интерфейс для чтения/записи свойств муз.файла (пока лишь одна заглушка)
ChipSong поддерживает только методы CreateFromFile и CreatePlayer
ChipPlayer поддерживает play - получение любого нужного количества семплов (есть свой буфер, в котором собираются "лишние" семплы от следующего фрагмента), set_volume, seek, get_pos, get_len
плейер играет vtx, pt2, pt3.
(в принципе, последние сделаны через эмулятор Z80. stc/stp не добавил только потому, что пока не отследил адрес процедурки в плейере, которая зацикливает мелодию)
и это,
в SNDRENDER был глючок! не инициализированы переменные bitA, bitB, bitC, из-за чего звук мог генерироваться "грязным" или со смешением каналов, если объект SNDCHIP создавался в необнулённой памяти (на стеке или в динамической "куче")
замените у себя библиотеку.
насчёт Z80 не знаю, как соберётся под линуксом. попробуйте свой, если не получится unreal'овский
по просьбам некоторых товарищей, работающих в MS Developer Studio, сделан солюшен со всеми проектами (либа и примеры)
вечером посмотрю.
я кстати тоже так хотел делать (z80 + sndrender) чтоб pt2/pt3/etc играть.
(наверное самый разумный подход)
насчёт Z80 не знаю, как соберётся под линуксом. попробуйте свой, если не получится unreal'овскийс ходу не собирается, ессно -- ругается на кучу всего, не только в z80. как со временем разгребусь, гляну толком. ...а в MSVC что, нет режима совместимости с ANSI/ISO C++? ;)
ту мне лог компиляции скинь, посмотрю...
ту мне лог компиляции скинь, посмотрю...вот лог :)
большая часть из-за неподдержки nameless structs/unions в описании Z80. а так мелочи
большая часть из-за неподдержки nameless structs/unions в описании Z80 ну да, по крайней мере это вроде единственное, что требует вмешательства в код, а не только в декларации.
не только. ещё проскочила разок переменная, объявленная в for и ещё кое-какие мелочи
пофиксен глюк с рассинхронизацией AY и других звуковых источников (bepeer, tape, etc), добавлен класс SNDCOUNTER для определения, сколько семплов полностью готово (при генерации от нескольких источников) и откуда из внутреннего буфера надо брать эти семплы. пример использования - в файле sndcounter.h
ура, все работает :)
кстати, предложение -- а почему бы не сделать режим EXTERNAL_BUFFER штатным? то есть передавать в start_frame указатель на буфер и его длину. ИМХО при таком раскладе больше ничего и не надо -- он полностью заменяет нынешний умолчальный режим. а то сейчас чтобы EXTERNAL_BUFFER врубить, приходится лезть в сорцы (тк дефинить его, а потом инклюдить *.h и *.cpp в файл -- неудобно, особенно если такой файл не один ,)
типа: void start_frame(SNDSAMPLE *dst, unsigned dstlen, unsigned dstpos=0);
кстати, предложение -- а почему бы не сделать режим EXTERNAL_BUFFER штатным?потому что 1) могут передавать размер - не степень двойки и 2) потеряется несколько десятков тактов внутри цикла заполнения буфера из-за переменных вместо констант (действия с константами MSVC оптимизирует на отлично)
сейчас чтобы EXTERNAL_BUFFER врубить, приходится лезть в сорцыпонятно, я специально вынес это в отдельный файл sndbuffer.h - достаточно исправить там 1-2 строки - указать, в какой переменной лежит буфер
з.ы. теперь можно немного упростить обработку звука - start_frame вызывать без параметра, результат end_frame игнорировать (см. пример), объект SNDCOUNTER сам всё считает
потому что 1) могут передавать размер - не степень двойки не степень 2ки и дефайном можно указать :rolleyes:
понятно, я специально вынес это в отдельный файл sndbuffer.h - достаточно исправить там 1-2 строки - указать, в какой переменной лежит буфер тогда еще надо #include "sndcounter.h" в sndcounter.cpp вынести на самый верх, а в sndcounter.h добавить #include "sndbuffer.h" перед ifdef'ом
хмм... если важно быстродействие, можно сделать темплейтами с параметрами-константами: медленней не станет, при использовании код править вообще не придется, и если понадобиться с несколькими буферами работать (может пригодиться в плеерах и тп) ничего не помешает.
ЗЫ извини за занудство, просто я маньяк по части интерфейсов, когда вижу отличный код, безумно хочется, чтобы и интерфейс был весь из себя :rolleyes:
не степень 2ки и дефайном можно указатьэто я уже добавил в sndrender.h:
#ifdef SND_EXTERNAL_BUFFER
#if ((SND_EXTERNAL_BUFFER_SIZE & (SND_EXTERNAL_BUFFER_SIZE-1)) != 0)
#pragma error("SND_EXTERNAL_BUFFER_SIZE must be power of 2")
#endif
#endif
тогда еще надо #include "sndcounter.h" в sndcounter.cpp вынести на самый верхсогласен
а в sndcounter.h добавить #include "sndbuffer.h" перед ifdef'омвключается через #include "sndrender.h", который надо вынести наверх
хмм... если важно быстродействие, можно сделать темплейтами с параметрами-константами: медленней не станет, при использовании код править вообще не придется, и если понадобиться с несколькими буферами работать (может пригодиться в плеерах и тп) ничего не помешаетможно, но это надо думать - надо ещё заводить класс-буфер и юзать его как параметр шаблона, что-ли, чтобы все SNDRENDER'ы c одним буфером были одним классом
не степень 2ки и дефайном можно указатьа хуже того, могут с каждым разом передавать разные буферы и размеры, когда всё должно быть одинаково, чтобы SNDCOUNTER правильно работал
а хуже того, могут с каждым разом передавать разные буферы и размеры, когда всё должно быть одинаково, чтобы SNDCOUNTER правильно работал если указатель на буфер и его размер передавать параметрами темплейта, не смогут... и, кстати, в этом случае ведь как раз и получится один класс на все SNDRENDER'ы, использующие один буфер.
Кто-нибудь знает почему плеер тормозит и как можно от этого избавится?
p.s. Паралельно в окне запускаю игру, AY Emulu хоть бы что, а сабжевый плеер начинает заикаться. :v2_frown:
Да еще и консоль эта не в тему.
он не тормозит, просто в AyEmul и в ZXSSK по разному выводится звук.
ZXSSK запихивает звук в несколько звуковых буферов (win, мне проще код написать, чем объяснить как оно работает :) ) или пихает в буфер пока можно (lin), и когда активна другая задача, звук прерывается.
AyEmul либо выставляет большой приоритет звуковому потоку, или генерит звук по требованию ОС (честно говоря не разбирался в этом вопросе), по этому нет разрывов :)
Но знаю одно точно, когда я писал ogg плеер в игрушку, у меня были такие же проблемы как и в ZXSSK, я тогда взял SDL, и написал под него (там как раз не запихивается в буфер пока можно, а вызывается процедура когда надо сгенерировать новые семплы, в принципе в сорсах SDL-а можно посмотреть на реализацию). Факт такой - звук стал ровным и не прерывался больше.
Возьми SDL, перепиши uniplayer под него и потом слушай каков звук.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot