Board.KolibriOS.org

Официальный форум KolibriOS
Текущее время: Чт мар 23, 2017 1:28 pm

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 68 сообщений ]  На страницу Пред. 1 2 3 4 5 След.
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Вт апр 11, 2006 8:35 pm 
Не в сети

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вт апр 11, 2006 10:03 pm 
Не в сети
Аватара пользователя

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Ср апр 12, 2006 12:19 pm 
Не в сети
Just Flooding
Аватара пользователя

Зарегистрирован: Ср май 18, 2005 10:27 am
Сообщения: 430
Hater, спасибо за инфу, уже качаю тут
http://www.wasm.ru/src/4/ufmod.zip
будем смотреть что да как...


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Ср апр 12, 2006 1:19 pm 
Не в сети
Just Flooding
Аватара пользователя

Зарегистрирован: Ср май 18, 2005 10:27 am
Сообщения: 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 :(:(:(


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Сб май 27, 2006 5:50 am 
Не в сети

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Сб май 27, 2006 7:51 am 
Не в сети
Аватара пользователя

Зарегистрирован: Чт май 19, 2005 4:43 pm
Сообщения: 896
Quantum,а ты ассемблер знаеш ?

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

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

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Сб май 27, 2006 11:20 am 
Не в сети
Kernel Developer

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

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Сб май 27, 2006 9:36 pm 
Не в сети

Зарегистрирован: Сб май 27, 2006 5:26 am
Сообщения: 100
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.

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

Код:
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 (уже без двойного буфера):

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Сб май 27, 2006 11:43 pm 
Не в сети
Аватара пользователя

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

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

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 12:03 am 
Не в сети
Kernel Developer

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 2:48 am 
Не в сети

Зарегистрирован: Сб май 27, 2006 5:26 am
Сообщения: 100
2 andrew_programmer:
Цитата:
я нисколько не хотел тебя обидеть

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

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

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

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

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

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

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

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

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 12:03 pm 
Не в сети
Kernel Developer

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 2:01 pm 
Serge
Мне кажется, система работает несколько сложней, чем ее описал Quantum. Многие вещи бывают, скрыты от не системного программиста (в смысле того, кто не пишет непосредственно ядро) и он описал то, что происходит по его пониманию.

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


Вернуться к началу
   
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 6:00 pm 
Не в сети

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

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

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


Вернуться к началу
 Заголовок сообщения:
СообщениеДобавлено: Вс май 28, 2006 6:41 pm 
Не в сети
Kernel Developer

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


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 68 сообщений ]  На страницу Пред. 1 2 3 4 5 След.

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB