А есть ли планы создания трекера

Projects yet to be implemented in working code
  • Hater,спасибо - приму во внимание.Если смогу понять работу библиотеки,то портирую(когда до трекера дойдет очередь).
  • Hater, спасибо за инфу, уже качаю тут
    http://www.wasm.ru/src/4/ufmod.zip
    будем смотреть что да как...
  • Я кажется, опять разочарован зайдя на основной сайт, а именно http://ufmod.sourceforge.net/
    видим:
    Version 1.12
    uFMOD is a lightweight XM chiptune player library. It's perfect for size-critical applications (such as intros), click free, bug free, easy to use, open source.

    OS: Win32, Linux, BSD
    Sound subsystems: WINMM, DirectX, OSS

    Т.е. все так нужное нам спрятано в Sound subsystems :(:(:(
  • Всем привет!

    В последнее время зреет идея создания версии uFMOD для MenuetOS. Оказывается, такая идея зреет не только в моей голове.

    В принципе, VaStaNi всё правильно написал. Нужен драйвер (интерфейс или sound subsystem, как я их окрестил :-) чтобы принимал клочки данных в формате PCM и выводил их на динамики. В формате PCM есть несколько субформатов. Переделать uFMOD под любой из них никакого труда не составит.

    В качестве подсистемы мне очень нравится реализация OSS (http://www.opensound.com/). Там на сайте спецификация, если интересно. Хоть это и старый стандарт для аудио в *никсах, с ним предельно просто обращаться. Суть такая:

    1. Открываем файл /dev/dsp
    2. Посылаем в файл (пишем) несколько команд, чтобы задать параметры воспроизведения (моно/стерео, частоту и т.д.)
    3. Начинаем периодически посылать в этот файл PCM фрагменты.

    Заметьте, что нет необходимости работать в режиме двойного буфера, т.е. ждать пока драйвер проиграет определённое количество фрагментов, чтобы дописать новые (звук должен проигрываться непрерывно, но генерироваться только по мере необходимости, минимально загружая CPU).

    В винде WINMM работает почти как OSS в Линуксе, только хуже :)

    WINMM перекладывает всю ответственность по содержанию двойного буфера на пользователя.

    Потом ещё есть DirectX DirectSound. Как ни странно, у этого интерфейса тоже нет двойного буфера, но зато есть куча навороченных (бесполезных для большинства разработок) фич.

    Существует ли уже в MenuetOS какое-то подобие OSS или WINMM? Для проигрывания wav-файлов что-то есть? Если да, то за библиотекой дело не станет ;)

    Конечно, мне ещё нужно разобраться как в MenuetOS делать hello world :) Потом ещё с многозадачностью могут быть проблемы (надеюсь, можно каким-то системным вызовом тред создать) и выделением динамической памяти.
  • Quantum,а ты ассемблер знаеш ?

    Вот sound subsystem у нас еще нет,т.к. был драйвер только для звуковой карты SoundBlaster(и то не для всех).
    Но Serge заниматься написанием звукового драйвера AC'97 и звуковой подсистемой.В результате написания такой подсистемы понадобились некоторые дополнительные возможности которых в Колибри небыло.И он временно переключился на работу по улучшению ядра(ОЧЕНЬ ПОЛЕЗНУЮ И НУЖНУЮ).

    А также над этим работал ещё один человек -Hater.Он занимался созданием звуковой подсистемы,но для COVOX-а.COVOX - это простейший цифро-аналоговый преобразователь,состоящий из 16 резисторов и 1 конденсатора(его может спаять ЛЮБОЙ),который подключается на LPT(параллельный) порт компьютера.Эта простенькая звуковая карта даёт приемлимое качества звука.Лучше уж иметь ковокс,чем вообще быть без звука.Но такая звуковая карта нагружает CPU т.к. необходимо 44100 раз в секунду посылать на LPT порт звуковые данные.Степень загрузки процессора покачто нам неизвестна,потомучто драйвера ещё нет.Но в принципе простенький драйвер COVOX-а можно написать за 8 часов.

    Колибри - это МНОГОЗАДАЧНАЯ ОПЕРАЦИОННАЯ СИСТЕМА.Посмотри различные программы,входящие в дистрибутив операционной системы Колибри и ты увидиш,что она обладает множеством возможностей.
    А что значит,-" каким-то системным вызовом тред создать" ?
    Всмысле запустить другую програмку,которая будет общаться с запустившей её программой ?(тоесть она будет являться частью первой программы)
    Так это КОНЕЧНО МОЖНО.
    А для динамического выделения памяти есть 64 функция.Я её использую в своём графическом редакторе.Есть реализация malloc на основе этой функции(автор Халявин Андрей(halyvin)).
  • Ура! Я закончил большую часть "полезной и нужной работы" и начал готовить АС97-драйвер. Предварительныая версия будет для Intel, SIS и nForce контроллеры похожи на Интел их можно будет сделать чуть пожже. Вместе с драйвером будет звуковая билиотека (создание звуковых буферов, микширование и конвертирование звука). Большая часть кода уже написана и обкатана в DOS.
    Если всё получится как задумано разные программы смогут одновременно проигрывать несколько звуковых буферов. Думаю со временем к библиотеке можно будет подключить и SoundBlaster. Получится библиотека похожая на DirectSound но для Колибри. Надеюсь к концу июня выложить предварительные исходники.
    Quantum
    Потом ещё есть DirectX DirectSound. Как ни странно, у этого интерфейса тоже нет двойного буфера, но зато есть куча навороченных (бесполезных для большинства разработок) фич.
    Учитывая вышенаписанное хотелось бы знать какме именно фичи DirectSound ты считаешь бесполезными.
    И что именно ты понимаешь под двойным буфером?
  • 2 andrew_programmer:
    Quantum,а ты ассемблер знаеш ?
    Обижаешь. uFMOD как раз на ассемблере разрабатывается. Поэтому такой маленький размер и сравнительно низкая загрузка процессора (в данном случае загрузка связана преимущественно со скростью генерации PCM-потока).

    Зато с MenuetOS я совершенно не знаком, хотя уже пытаюсь найти походящую документацию и туториальчики.

    И про ковокс знаем :) Сомневаюсь, правда, что многие сегодня захотят спаять эту заглушку для LPT, когда low-end звуковухи стоят копейки. В любом случае, разумнее включать поддержку конкретных железок (ковокс, SoundBlaster, ...) на уровне драйвера, чтоб пользовательские приложения знать не знали кто и как проигрывает их сэмплы. Такой подход мне кажется более выйгрышным, чем делать uFMOD под ковокс, ещё одну версию под SB, ещё одну для Adlib, ещё одну для встроенных интеловских чипсетов и т.д.
    А что значит,-" каким-то системным вызовом тред создать" ?
    К примеру, в Win32 API тред создаётся функцией CreateThread и/или различными надстройками над этой функцией. В *никсах тоже самое делается сишной функцией pthread_create.
    Всмысле запустить другую програмку,которая будет общаться с запустившей её программой ?(тоесть она будет являться частью первой программы)
    Это напоминает fork в *никсах. Нет, тред не является другой программой (процессом). Тред легковесен. Данные и код основного потока должны быть доступны из второстепенного. Время, которое система выделяет под данный процесс должно равномерно расходоваться между потоками/тредами. Конечно, если легковесных тредов в MeOS нет, можно будет адаптировать библиотеку под действующую модель многозадачности. Я ещё не разбирался с этим.
    А для динамического выделения памяти есть 64 функция
    Скорее всего, это то, что нужно.

    2 Serge:
    начал готовить АС97-драйвер
    Это просто замечательно!
    какме именно фичи DirectSound ты считаешь бесполезными
    Бесполезными для большинства разработчиков являются расширенные эффекты (эхо, хор, полоскание, эквалайзер и т.д.) Качество этих эффектов отвратительное, а процессорного времени и памяти потребляют немеряно. Если кому и нужны эти эффекты, их обычно воплощают самостоятельно. В старых версиях можно было использовать хардварные и софтверные каналы (в 9м DX уже нельзя), что приводило к настоящей какофонии на некоторых картах.
    И что именно ты понимаешь под двойным буфером?
    См. выше:
    ждать пока драйвер проиграет определённое количество фрагментов, чтобы дописать новые (звук должен проигрываться непрерывно, но генерироваться только по мере необходимости, минимально загружая CPU).
    В Линуксе за это отвечает драйвер, а в Win32 (и в WINMM и в DX) пришлось воплощать двойной буфер мне. Принцип такой:

    1. Тред проигрывания периодически опрашивает звуковую подсистему, чтобы узнать сколько она уже успела проиграть из буфера канала.
    2. На основании результата из п.1 можно вычислить сколько места в буфере уже освободилось под новые PCM-блоки.
    3. Вызываем функцию, которая генерирует эти самые PCM-блоки, пока буфер канала не заполнится.
    4. Отдыхаем немного (чтоб загрузка CPU не страдала) и возвращаемся к п.1.

    Упрощённо это реализовано следующим образом:

    Code: Select all

    uFMOD_Thread:
    	push ebp
    	mov ebp,mmt
    	push esi
    	inc [SW_ThreadRun] ; сигналим, что тред запущен
    thread_loop_1:
    	; ***
    	; Обращаемся к драйверу чтобы узнать текущее положение курсора
    	; в буфере канала (т.е. какой участок он сейчас проигрывает)
    	; Результат в eax.
    	; ***
    	cdq
    	mov ecx,[FSOUND_BufferSize]
    	div ecx
    	mov ecx,[FSOUND_BlockSize]
    	xchg eax,edx
    	cdq
    	div ecx ; eax <= ((playing_offset / 4) % FSOUND_BufferSize) / FSOUND_BlockSize
    	xchg eax,esi
    thread_loop_2:
    	; ***
    	; Отдыхаем немного, чтоб охладилась CPU :)
    	; ***
    	cmp [uFMOD_FillBlk],esi
    	je loop_2_end
    	call uFMOD_SW_Fill ; <- эта функция генерирует слудующий сэмпл (PCM-блок)
    	jmp thread_loop_2
    loop_2_end:
    	cmp [SW_Exit],0 ; это чтоб тред можно было остановить извне
    	jz thread_loop_1
    	pop esi
    	dec [SW_ThreadRun] ; сигналим, что тред уже кончился
    	pop ebp
    	retn 4
    Это и есть наш двойной буфер. Для сравнения см. тоже самое но для Линукса/BSD (уже без двойного буфера):

    Code: Select all

    uFMOD_Thread:
    	inc [SW_ThreadRun] ; сигналим, что тред запущен
    thread_loop_1:
    	; ***
    	; Отдыхаем немного, чтоб охладилась CPU :)
    	; ***
    	call uFMOD_SW_Fill ; <- эта функция генерирует слудующий сэмпл (PCM-блок)
    	; ***
    	; Посылаем PCM блок драйверу
    	; ***
    	cmp [SW_Exit],0 ; это чтоб тред можно было остановить извне
    	jz thread_loop_1
    	dec [SW_ThreadRun] ; сигналим, что тред уже кончился
    	retn
    Кстати, термин "двойной буфер" для звука взят из спецификации OSS, т.е. это не я его придумал.
  • Quantum,я нисколько не хотел тебя обидеть.Ты человек новый,поэтому вопрос и задаю.
    Я когда в первый раз появился на форуме MenuetOS(тогда это была ещё MenuetOS,а не Колибри) - меня приняли за человека,незнающего ассемблер.Но я не обиделся,а просто решил доказать делом.

    >разумнее включать поддержку конкретных железок (ковокс, SoundBlaster, ...) на уровне драйвера, чтоб пользовательские приложения знать не знали кто и как проигрывает их сэмплы.

    А вот какраз звуковую систему,в которой ненужно заботиться о типе проигрывающей звуковой карты,Serge и делает.
  • В нашей технической литературе треды называют потоками. В Колибри они есть и хорошо работают (51 функция).
    1. Тред проигрывания периодически опрашивает звуковую подсистему, чтобы узнать сколько она уже успела проиграть из буфера канала.
    2. На основании результата из п.1 можно вычислить сколько места в буфере уже освободилось под новые PCM-блоки.
    3. Вызываем функцию, которая генерирует эти самые PCM-блоки, пока буфер канала не заполнится.
    4. Отдыхаем немного (чтоб загрузка CPU не страдала) и возвращаемся к п.1.
    А зачем такие сложности с опросом в DirectSound, там ведь есть механизм уведомлений

    Code: Select all

    	hRet=pDS->CreateSoundBuffer( &dsbd, &pDSBuffer, NULL );
    	if (hRet!=DS_OK)
    	{	wsprintf(szErrorMessage,"%s","Create buffer error");
    		return (FALSE);
    	}
    
    	for (int i = 0; i < 2; i++)
    	{	hEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
    		
    		if (!hEvents[i]) 
    		{	wsprintf(szErrorMessage,"%s","Event object creation");
    			return FALSE;    
    		}
    	}
    	
    	hRet=pDSBuffer->QueryInterface(IID_IDirectSoundNotify,(VOID**)&pDSNotify);
    	if (hRet!=DS_OK)
    	{	wsprintf(szErrorMessage,"%s","Create notify interface");
    		return (FALSE);
    	}
    	
    	pDSPosNotifies[0].dwOffset = 0;         //уведомление в начале
    	pDSPosNotifies[0].hEventNotify = hEvents[0];
    	pDSPosNotifies[1].dwOffset = 0x8000; //и в середине
    	pDSPosNotifies[1].hEventNotify = hEvents[1];
    
    	hRet = pDSNotify->SetNotificationPositions(2,pDSPosNotifies);
    	if (hRet!=DS_OK)
    	{	wsprintf(szErrorMessage,"%s","Set notify positions");
    		return (FALSE);
    	}
    
    	if(!CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NotifyHandle, NULL, 0, &dwThreadId))
    	{	wsprintf(szErrorMessage,"%s","Create notify handle thread");
    		return (FALSE);
    	}
    
    
    DWORD NotifyHandle(LPVOID lpvoid) 
    {
    	DWORD dwOffset;
    	VOID *pPtr1=NULL, *pPtr2=NULL;   
    	DWORD dwSize1=0, dwSize2=0;
    	DWORD dwBytesRead;    
    	
    	while (TRUE)
    	{      DWORD dwEvent = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE); //ожидаем события
    		EnterCriticalSection(&csWavSound);
    		if(!pDSBuffer)
    		{	LeaveCriticalSection(&csWavSound);
    			ExitThread(0);
    		}
    		dwEvent -= WAIT_OBJECT_0;
    		dwOffset = pDSPosNotifies[dwEvent==0 ? 1:0].dwOffset;  
    		pDSBuffer->Lock(dwOffset,dwBufferSize/2, &pPtr1, &dwSize1, &pPtr2, &dwSize2, 0); //получаем доступ к буферу
    
    //заполняем буфер данными
    
    		pDSBuffer->Unlock(pPtr1, dwSize1, pPtr2, dwSize2);
    		LeaveCriticalSection(&csWavSound);
    	}
    }
    
    Одна часть буфера проигрывается, другая записывается. Буфер можно разбивать на несколько частей разного размера по желанию. Если это называется "двойным буфером" то в DirectSound это есть уже давно где-то с 7 версии.
  • 2 andrew_programmer:
    я нисколько не хотел тебя обидеть
    Просто в русском языке есть такое выражение. Это не значит, что я действительно обиделся.

    2 Serge:
    В нашей технической литературе треды называют потоками.
    Чтоб не путать со стримами, предпочитаю английский термин "тред".
    В Колибри они есть и хорошо работают (51 функция).
    OK, заюзаем, когда придёт время. Спасибо!
    А зачем такие сложности с опросом в DirectSound, там ведь есть механизм уведомлений
    В 5ом DX этого интерфейса не было. Поэтому я его не использую. С другой стороны, WaitForSingleObject не намного эффективнее цикла со Sleep и вызовами GetCurrentPosition (этот метод отрабатывает очень быстро - проверял). Да и твой сишный код выглядит длиннее моего ассемблерного :)

    Нет, этот интерфейс уведомлений не является воплощением двойного буфера. Заметь, что в Линуксе я не жду никаких событий, и не слежу за курсором в буфере. Я просто пишу в буфер, а sleep там только для охлаждения.

    Если ты воплотишь полный аналог DirectSound, многие скажут спасибо, но это займёт слишком много времени.
  • Нет, этот интерфейс уведомлений не является воплощением двойного буфера. Заметь, что в Линуксе я не жду никаких событий, и не слежу за курсором в буфере. Я просто пишу в буфер, а sleep там только для охлаждения.
    Тогда я не очень понимаю, как эта штука в Линуксе работает. Если поток активен все время, то он просто зря грузит процессор, а Sleep() это лишние переключения. Уведомления в это случае эффективней. Поток активируется только тогда, когда драйвер установит событие. И как в Линуксе определяется когда писать ещё рано или уже можно?
  • Serge
    Мне кажется, система работает несколько сложней, чем ее описал Quantum. Многие вещи бывают, скрыты от не системного программиста (в смысле того, кто не пишет непосредственно ядро) и он описал то, что происходит по его пониманию.

    Quantum
    Без обид надеюсь? Я только выразил своем ИМХО. Никакого сомнения в твоих способностях. Нам нужны толковые люди в проекте.
  • 2 Mario79:
    Конечно, всё гораздо сложнее. Я же привёл ссылку на описание OSS где-то выше. Даже с пользовательской перспективы всё сложнее, чем я описал.

    2 Serge:
    Тогда я не очень понимаю, как эта штука в Линуксе работает
    Когда тред вызывает write чтобы записать очередной блок PCM, драйвер не возвращает управления пока не освободится место. Всё просто (с пользовательской точки зрения, естественно).
  • Когда тред вызывает write чтобы записать очередной блок PCM, драйвер не возвращает управления пока не освободится место. Всё просто (с пользовательской точки зрения, естественно). Тогда большой разницы с DirectSound нет
  • Who is online

    Users browsing this forum: No registered users and 3 guests