Вход в Зоопарк ручных компьютеров
gps мониторинг, транспортная логистика, gps слежение
Если вы видите баннеры при просмотре с КПК, то вам - СЮДА
Как определить что нет звука
Форумы Поиск Вход Для ПК
Программирование для КПК
Вс Июн 16, 2002 20:02
Nloge (Маститый писатель)
Нужно программно определить что soundBalster (или что там в машинках вместо него...) сейчас свободен и не проигрывает никаких звуков. Точнее мне нужно узнать что другая программка закончила использовать soundBlaster. Как это сделать?
____________
e800; J568; J548
Пн Июн 17, 2002 3:24
vroma (Гость)
2Nloge:

"программно определить что soundBalster ... сейчас свободен и не проигрывает никаких звуков"
Насколько я знаю Windows CE API (мы говорим о WinCE ?) не имеет функции, позволяющей узнать, что waveOut устройство свободно или используется приложением. Коды возврата функции waveOutOpen() также не содержат такой ошибки, как "устройство уже используется".

"узнать что другая программка закончила использовать soundBlaster".
А зачем это знать ? Чтобы самому выводить туда звук ? Или запретить вывод звука другими приложениями пока звук выводишь ты ?
Как по мне, простого решения указанной проблемы не существует.

В Windows CE звуком заведуют процесс GWES.EXE, работающий в режиме ядра, а также загружаемый этим процессом драйвер audio устройства.
Насколько я знаю WinCE позволяет открыть одно и тоже audio устройство одновременно из нескольких процессов пользовательского режима и одновременно выводить из них данные (но не одновременно их воспроизводить на устройстве). Процесс GWES.EXE будет эти данные хранить в своих буферах и поочередно передавать драйверу, а драйвер будет писать их в порт устройства. Когда и с учетом каких факторов GWES.EXE принимает решение, что необходимо начать передачу драйверу данных, поступивших от другого приложения, я не знаю. В принципе, опытным путем можно выяснить этот момент.
Поскольку драйвер устройства и GWES.EXE "разговаривают" друг с другом с помощью events, которые сигнализируют о проделываемой ими работе, можно попытаться "подключиться" к соответствующим events и в своем приложении также получать от драйвера сигналы о состоянии устройства, а от процесса GWES.EXE - о наличии данных для пересылки драйверу.
Может эта информация тебе поможет побороть проблему Smile.

P.S. Когда я работал со звуком в Windows CE, то у меня возникла извечная проблема дуплексной работы waveIn и waveOut. Они одновременно не работали, поскольку в аудиосхеме для in/out передачи данных используется один канал ДМА, который блокируется драйвером при вызове одной из wave функций. При этом Windows CE не знает (не сообщает приложению) о такой блокировке и работает так, как будто бы железо дуплексное - данные с микрофона снимает, на воспоизведение их посылает, но при этом ничего не играет (хотя входящий поток записан нормально). Если у тебя такое же железо, то проблема определения использования устройства решается сама собой - открываешь устройство и драйвер наглухо заблокирует доступ из других приложений Smile.
Пн Июн 17, 2002 3:54
Nloge (Маститый писатель)
Спасибо за хороший и развернутый ответ.
Да конечно речь идет о WinCE.
Задача у меня немного другая, проще наверное, а может и нет, кто его знает... Есть приложение, интерфейск которого прост до безобразия - это диалоговое окно с CEdit и CButton (написано не мной, но видно что на MFC). Хорошего в этой программке то что она может читать (на английском, испанском и еще нескольких языках) то что введешь в этот самый Edit при нажатии на эту самую кнопку. На самом деле это демонстрашка, но ее возможностей мне вполне хватает. Сложностей в том чтобы из другой программы заставить это приложение прочитать что угодно нет никакой - посылаю пару сообщений и все замечательно. То есть режим словаря говоряшего для Halli 2.0 в черновую я сделал.
Теперь хочеться сделать автоматическое чтение книги (качество результата вопрос второй - но на мой слух - средненькое, а значит в принципе пойдет). Проблема - как узнать что програмка закончила читать очередное предложение и можно ей подавать следующую порцию. В буфере то конечно все сохраняется что ни положишь, но он не резиновый, да и не красиво это...
Сама программка действительно нмкаких событий не получает по окончанию фразы (я это вроде проверил), как отловить сообщение между драйвером и GWES.EXE - ставить системный Hook?
____________
e800; J568; J548
Пн Июн 17, 2002 5:20
vroma (Гость)
2Nloge:

"как узнать что програмка закончила читать очередное предложение"

Все зависит от того из какого процесса ты хочешь это знать.

1. Если ты сам посылаешь аудиоданные, то это можно сделаться следующим образом.
Когда ты открываешь аудио устройство функцией waveOutOpen() в качестве одного из ее параметров указываешь функцию обратного вызова (как вариант). Эта функция будет принимать сообщения от драйвера. Она может выглядеть, например, так:

Код:

void CALLBACK SOCallback(
   HANDLE      hWaveIn,
   WORD      msg,
   DWORD      instance,
   DWORD      param1,
   DWORD      param2)
{
   if(msg==WOM_DONE)
   {
   ...
   }
}


Открыв устройство, например, так:

Код:

   if(result = waveOutOpen(&mWaveHandle, WAVE_MAPPER,
               &waveFormat, (DWORD)SOCallback,
               (DWORD)this, CALLBACK_FUNCTION))
   {
   ...
   }


Дальше можно подготовить аудиоданные (waveOutPrepareHeader()) и передать их в буфер драйвера (waveOutWrite()). После успешной передачи освободить буфер приложения (waveOutUnprepareHeader()), например, так:

Код:

      err = waveOutPrepareHeader(mWaveHandle, &mToneHeader, sizeof(WAVEHDR));
      CheckWaveError("waveOutPrepareHeader", err);
      if(!(err = waveOutWrite(mWaveHandle, &mToneHeader, sizeof(WAVEHDR))))
      {
         while(!(mToneHeader.dwFlags & WHDR_DONE))
            Sleep(0);
         err = waveOutUnprepareHeader(mWaveHandle, &mToneHeader, sizeof(WAVEHDR));
         CheckWaveError("waveOutUnprepareHeader", err);
      }
      else
      {
         CheckWaveError("waveOutWrite", err);
      }


Когда драйвер устройства передаст данные в порт устройства и освободит свой буфер, он (драйвер) вызовет функцию обратного вызова твоего приложения SOCallback() со значением (msg==WOM_DONE). Получив это сообщение ты можешь передать драйверу следующую порцию данных и так делать до тех пор, пока есть данные. Переполнения буфера не будет и ты будешь знать когда программа закончила читать очередное предложение.


2. Если же ты предполагаешь передавать из своего приложения в "программку, которая может читать" исключительно текстовые данные, то можешь использовать для этой цели, например, функцию SendMessage(), синхронную по своей природе. Она вернет управление твоей программе только тогда, когда CEdit и CButton "программки, которая может читать" обработают твое сообщение. Это может помочь контролировать факт получения "программкой, которая может читать" сообщения и (косвенным образом) факт его последующей отправки аудиодрайверу. Правда, при этом многое зависит от того, как реализована "программка, которая может читать".



С пожеланиями успехов,
vroma
Пн Июн 17, 2002 13:13
Nloge (Маститый писатель)
Вариант у меня именно второй. То есть я передаю только текстовые данные (с помощью как раз SendMessage)а аудиопоток формируется совершенно другим приложением. Причем SendMessage заканчивает работу сразу, даже до того как фраза начинает звучать из динамика. Поэтому я и думал что может можно как-то опросить soundBlaster.... Ладно - будем искать Smile
____________
e800; J568; J548

Если вы видите баннеры при просмотре с КПК, то вам - СЮДА



Форумы Handy.ru 


Powered by phpBB © 2001 phpBB Group