Board.KolibriOS.org

Official KolibriOS board
It is currently Sat Aug 17, 2019 8:31 pm

All times are UTC+03:00




Post new topic  Reply to topic  [ 68 posts ]  Go to page Previous 1 2 3 4 5 Next
Author Message
 Post subject:
PostPosted: Tue Apr 11, 2006 8:35 pm 
Offline

Joined: Sat Jan 07, 2006 4:07 am
Posts: 47
uFMOD - это самая компактная библиотека для качественного воспроизведения аудио-ресурсов в формате XM. Воспроизведение аудио-потока, который может храниться в отдельном файле, в ресурсах или предварительно загружен в память, инициируется вызовом одной единственной функции. Библиотека uFMOD распространяется с открытым исходным кодом и примерами для MASM32, FASM, Visual C++ и Visual Basic 6


Top
   
 Post subject:
PostPosted: Tue Apr 11, 2006 10:03 pm 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Hater,спасибо - приму во внимание.Если смогу понять работу библиотеки,то портирую(когда до трекера дойдет очередь).


Top
   
 Post subject:
PostPosted: Wed Apr 12, 2006 12:19 pm 
Offline
Just Flooding
User avatar

Joined: Wed May 18, 2005 10:27 am
Posts: 430
Hater, спасибо за инфу, уже качаю тут
http://www.wasm.ru/src/4/ufmod.zip
будем смотреть что да как...


Top
   
 Post subject:
PostPosted: Wed Apr 12, 2006 1:19 pm 
Offline
Just Flooding
User avatar

Joined: Wed May 18, 2005 10:27 am
Posts: 430
Я кажется, опять разочарован зайдя на основной сайт, а именно 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 :(:(:(


Top
   
 Post subject:
PostPosted: Sat May 27, 2006 5:50 am 
Offline

Joined: Sat May 27, 2006 5:26 am
Posts: 100
Всем привет!

В последнее время зреет идея создания версии 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 :) Потом ещё с многозадачностью могут быть проблемы (надеюсь, можно каким-то системным вызовом тред создать) и выделением динамической памяти.


Top
   
 Post subject:
PostPosted: Sat May 27, 2006 7:51 am 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Quantum,а ты ассемблер знаеш ?

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

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

Колибри - это МНОГОЗАДАЧНАЯ ОПЕРАЦИОННАЯ СИСТЕМА.Посмотри различные программы,входящие в дистрибутив операционной системы Колибри и ты увидиш,что она обладает множеством возможностей.
А что значит,-" каким-то системным вызовом тред создать" ?
Всмысле запустить другую програмку,которая будет общаться с запустившей её программой ?(тоесть она будет являться частью первой программы)
Так это КОНЕЧНО МОЖНО.
А для динамического выделения памяти есть 64 функция.Я её использую в своём графическом редакторе.Есть реализация malloc на основе этой функции(автор Халявин Андрей(halyvin)).


Top
   
 Post subject:
PostPosted: Sat May 27, 2006 11:20 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Ура! Я закончил большую часть "полезной и нужной работы" и начал готовить АС97-драйвер. Предварительныая версия будет для Intel, SIS и nForce контроллеры похожи на Интел их можно будет сделать чуть пожже. Вместе с драйвером будет звуковая билиотека (создание звуковых буферов, микширование и конвертирование звука). Большая часть кода уже написана и обкатана в DOS.
Если всё получится как задумано разные программы смогут одновременно проигрывать несколько звуковых буферов. Думаю со временем к библиотеке можно будет подключить и SoundBlaster. Получится библиотека похожая на DirectSound но для Колибри. Надеюсь к концу июня выложить предварительные исходники.
Quantum
Quote:
Потом ещё есть DirectX DirectSound. Как ни странно, у этого интерфейса тоже нет двойного буфера, но зато есть куча навороченных (бесполезных для большинства разработок) фич.

Учитывая вышенаписанное хотелось бы знать какме именно фичи DirectSound ты считаешь бесполезными.
И что именно ты понимаешь под двойным буфером?


Top
   
 Post subject:
PostPosted: Sat May 27, 2006 9:36 pm 
Offline

Joined: Sat May 27, 2006 5:26 am
Posts: 100
2 andrew_programmer:
Quote:
Quantum,а ты ассемблер знаеш ?

Обижаешь. uFMOD как раз на ассемблере разрабатывается. Поэтому такой маленький размер и сравнительно низкая загрузка процессора (в данном случае загрузка связана преимущественно со скростью генерации PCM-потока).

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

И про ковокс знаем :) Сомневаюсь, правда, что многие сегодня захотят спаять эту заглушку для LPT, когда low-end звуковухи стоят копейки. В любом случае, разумнее включать поддержку конкретных железок (ковокс, SoundBlaster, ...) на уровне драйвера, чтоб пользовательские приложения знать не знали кто и как проигрывает их сэмплы. Такой подход мне кажется более выйгрышным, чем делать uFMOD под ковокс, ещё одну версию под SB, ещё одну для Adlib, ещё одну для встроенных интеловских чипсетов и т.д.

Quote:
А что значит,-" каким-то системным вызовом тред создать" ?

К примеру, в Win32 API тред создаётся функцией CreateThread и/или различными надстройками над этой функцией. В *никсах тоже самое делается сишной функцией pthread_create.

Quote:
Всмысле запустить другую програмку,которая будет общаться с запустившей её программой ?(тоесть она будет являться частью первой программы)

Это напоминает fork в *никсах. Нет, тред не является другой программой (процессом). Тред легковесен. Данные и код основного потока должны быть доступны из второстепенного. Время, которое система выделяет под данный процесс должно равномерно расходоваться между потоками/тредами. Конечно, если легковесных тредов в MeOS нет, можно будет адаптировать библиотеку под действующую модель многозадачности. Я ещё не разбирался с этим.

Quote:
А для динамического выделения памяти есть 64 функция

Скорее всего, это то, что нужно.

2 Serge:
Quote:
начал готовить АС97-драйвер

Это просто замечательно!

Quote:
какме именно фичи DirectSound ты считаешь бесполезными

Бесполезными для большинства разработчиков являются расширенные эффекты (эхо, хор, полоскание, эквалайзер и т.д.) Качество этих эффектов отвратительное, а процессорного времени и памяти потребляют немеряно. Если кому и нужны эти эффекты, их обычно воплощают самостоятельно. В старых версиях можно было использовать хардварные и софтверные каналы (в 9м DX уже нельзя), что приводило к настоящей какофонии на некоторых картах.

Quote:
И что именно ты понимаешь под двойным буфером?

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

В Линуксе за это отвечает драйвер, а в Win32 (и в WINMM и в DX) пришлось воплощать двойной буфер мне. Принцип такой:

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

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

Code:
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:
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, т.е. это не я его придумал.


Top
   
 Post subject:
PostPosted: Sat May 27, 2006 11:43 pm 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Quantum,я нисколько не хотел тебя обидеть.Ты человек новый,поэтому вопрос и задаю.
Я когда в первый раз появился на форуме MenuetOS(тогда это была ещё MenuetOS,а не Колибри) - меня приняли за человека,незнающего ассемблер.Но я не обиделся,а просто решил доказать делом.

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

А вот какраз звуковую систему,в которой ненужно заботиться о типе проигрывающей звуковой карты,Serge и делает.


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 12:03 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
В нашей технической литературе треды называют потоками. В Колибри они есть и хорошо работают (51 функция).
Quote:
1. Тред проигрывания периодически опрашивает звуковую подсистему, чтобы узнать сколько она уже успела проиграть из буфера канала.
2. На основании результата из п.1 можно вычислить сколько места в буфере уже освободилось под новые PCM-блоки.
3. Вызываем функцию, которая генерирует эти самые PCM-блоки, пока буфер канала не заполнится.
4. Отдыхаем немного (чтоб загрузка CPU не страдала) и возвращаемся к п.1.
А зачем такие сложности с опросом в DirectSound, там ведь есть механизм уведомлений
Code:
   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 версии.


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 2:48 am 
Offline

Joined: Sat May 27, 2006 5:26 am
Posts: 100
2 andrew_programmer:
Quote:
я нисколько не хотел тебя обидеть

Просто в русском языке есть такое выражение. Это не значит, что я действительно обиделся.

2 Serge:
Quote:
В нашей технической литературе треды называют потоками.

Чтоб не путать со стримами, предпочитаю английский термин "тред".

Quote:
В Колибри они есть и хорошо работают (51 функция).

OK, заюзаем, когда придёт время. Спасибо!

Quote:
А зачем такие сложности с опросом в DirectSound, там ведь есть механизм уведомлений

В 5ом DX этого интерфейса не было. Поэтому я его не использую. С другой стороны, WaitForSingleObject не намного эффективнее цикла со Sleep и вызовами GetCurrentPosition (этот метод отрабатывает очень быстро - проверял). Да и твой сишный код выглядит длиннее моего ассемблерного :)

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

Если ты воплотишь полный аналог DirectSound, многие скажут спасибо, но это займёт слишком много времени.


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 12:03 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Quote:
Нет, этот интерфейс уведомлений не является воплощением двойного буфера. Заметь, что в Линуксе я не жду никаких событий, и не слежу за курсором в буфере. Я просто пишу в буфер, а sleep там только для охлаждения.
Тогда я не очень понимаю, как эта штука в Линуксе работает. Если поток активен все время, то он просто зря грузит процессор, а Sleep() это лишние переключения. Уведомления в это случае эффективней. Поток активируется только тогда, когда драйвер установит событие. И как в Линуксе определяется когда писать ещё рано или уже можно?


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 2:01 pm 
Serge
Мне кажется, система работает несколько сложней, чем ее описал Quantum. Многие вещи бывают, скрыты от не системного программиста (в смысле того, кто не пишет непосредственно ядро) и он описал то, что происходит по его пониманию.

Quantum
Без обид надеюсь? Я только выразил своем ИМХО. Никакого сомнения в твоих способностях. Нам нужны толковые люди в проекте.


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 6:00 pm 
Offline

Joined: Sat May 27, 2006 5:26 am
Posts: 100
2 Mario79:
Конечно, всё гораздо сложнее. Я же привёл ссылку на описание OSS где-то выше. Даже с пользовательской перспективы всё сложнее, чем я описал.

2 Serge:
Quote:
Тогда я не очень понимаю, как эта штука в Линуксе работает

Когда тред вызывает write чтобы записать очередной блок PCM, драйвер не возвращает управления пока не освободится место. Всё просто (с пользовательской точки зрения, естественно).


Top
   
 Post subject:
PostPosted: Sun May 28, 2006 6:41 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Когда тред вызывает write чтобы записать очередной блок PCM, драйвер не возвращает управления пока не освободится место. Всё просто (с пользовательской точки зрения, естественно). Тогда большой разницы с DirectSound нет


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 68 posts ]  Go to page Previous 1 2 3 4 5 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Limited