klen |
Отправлено: 01.08.2005, 15:00 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Вобщем потребовался мне НЧ-генератор сигнала, и решил я его на звуковухе сделать и с выхода получать сигнал который я захочу. Использую интерфейсы DirectSound. В документации написано что если после захвата интерфейса устройство вывода сделать вызов lpIDirectSound->-SetCooperativeLevel( WinHandle , DSSCL_PRIORITY ) то звук будет проигрыватся непрерывно, однако при потере фокуса окном (WinHandle) проигрывание сигнала встает колом. А при передаче фокуса продолжает проигрывать. Че нада сделать чтоб независимо от фокуса буффер уссройства вывода проигрыал звук?
Зарание спасибо.
Вопрос решен установкой потерряного флага. Спасибо если кто напрягся:)
Отредактировано klen — 01/08/2005, 18:05 |
|
Георгий |
Отправлено: 01.08.2005, 20:24 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
покажи код то — вдруг кому-нибудь пригодится |
|
klen |
Отправлено: 02.08.2005, 07:48 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Хорошо. У меня щас код заточен исключительно под генерацияю 8 импульсного ШИМ. Это нужно для формирования сигнала управления радиоуправляемой авиамодели. Код нада вылизать — щас кака, просто работает. Сделаю комментарии и оформлю как компонент — настраиваешь свойства, передаешь массив с записью отсчетов сигнала и компанент через DS циклически его проигрывает.
А пока вот содержательный кусок как это делать можно
CODE |
__fastcall TDACThread::TDACThread(bool CreateSuspended , unsigned int BufferSizeBySample , unsigned int SamplesPerSec , HANDLE WinHandle )
: TThread(CreateSuspended)
{
FQPulse_0 = 114;
FQPulse_1 = 114;
FQPulse_2 = 114;
FQPulse_3 = 114;
FQPulse_4 = 114;
FQPulse_5 = 114;
FQPulse_6 = 114;
FQPulse_7 = 114;
FPulseMaxTime = 180;
FPulseMinTime = 48;
FPauseTime = 25;
FSynchroPauseTime = 292;
FAmp = -2000;
FNegativeSynhcroPulse = true;
FMode = 1;
// создание буффера управляющего пакета
FControlPWMPackage = new short [BufferSizeBySample];
// создание событий нотификации
FNotifyEvents[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
FNotifyEvents[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
// создание объекта критической секции
InitializeCriticalSection( &FCriticalSection );
FBufferSizeBySample = BufferSizeBySample;
// захват интерфейса обьекта DirectSound
DirectSoundCreate( NULL , &FDAC , NULL );
// установка приоритета буффера
FDAC->SetCooperativeLevel( WinHandle , DSSCL_PRIORITY );
FWFormat.wFormatTag=WAVE_FORMAT_PCM;
FWFormat.nChannels=1;
FWFormat.wBitsPerSample = 16;
FWFormat.nSamplesPerSec = SamplesPerSec;
FWFormat.nBlockAlign = (FWFormat.nChannels * FWFormat.wBitsPerSample)/8;
FWFormat.nAvgBytesPerSec = (FWFormat.nSamplesPerSec * FWFormat.nBlockAlign);
FBufferDescr.lpwfxFormat = &FWFormat;
FBufferDescr.dwSize = sizeof(DSCBUFFERDESC);
FBufferDescr.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
FBufferDescr.dwBufferBytes = FBufferSizeBySample * FWFormat.wBitsPerSample / 8; // размер буффера драйвера
FBufferDescr.dwReserved = 0;
FDAC->CreateSoundBuffer(&FBufferDescr, &FBuffer, NULL);
// захват интерфейса нотификации событий буфера
IDirectSoundNotify* BufferNotify = NULL;
FBuffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&BufferNotify);
if ( !BufferNotify ) throw "Fuck";
DSBPOSITIONNOTIFY BufferNotifyPosition[2] = { 0 ,
FNotifyEvents[0] ,
FBufferDescr.dwBufferBytes/4 — 1 ,
FNotifyEvents[1] };
if ( 0 > BufferNotify->SetNotificationPositions( 1 , BufferNotifyPosition )) throw "Fuck";
BufferNotify->Release();
UdateControlPWMPackage ();
}
//---------------------------------------------------------------------------
__fastcall TDACThread::~TDACThread()
{
Terminate();
WaitFor();
// удаление объекта критической секции
DeleteCriticalSection(&FCriticalSection);
delete FControlPWMPackage;
}
//---------------------------------------------------------------------------
void __fastcall TDACThread::CancelCapture()
{
FBuffer->Stop();
// установка в сигнальное состояние событий нотификации
SetEvent(FNotifyEvents[0]);
SetEvent(FNotifyEvents[1]);
}
//---------------------------------------------------------------------------
void TDACThread::SetName()
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = "BufferNotifier";
info.dwThreadID = -1;
info.dwFlags = 0;
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD),(DWORD*)&info );
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
}
}
//---------------------------------------------------------------------------
void __fastcall TDACThread::Execute()
{
SetName();
// запуск проигрывания
FBuffer->Play( NULL , 0 , DSBPLAY_LOOPING );
while ( !Terminated )
{
// ожидание заполнения подбуфера буфера драйвера
FEventIndex = WaitForMultipleObjects ( 2 , FNotifyEvents , false , INFINITE ) — WAIT_OBJECT_0;
if ( Terminated )
{
// останов чтения и освобождение интерфейсов DS
FBuffer->Stop();
FBuffer->Release();
FDAC->Release();
// освобождаем события
CloseHandle (FNotifyEvents[0]);
CloseHandle (FNotifyEvents[1]);
return;
}
else
{
// сброс событий
ResetEvent (FNotifyEvents[0]);
ResetEvent (FNotifyEvents[1]);
DWORD Cursor = 0;
void* Buff0 = NULL;
void* Buff1 = NULL;
DWORD Bytes0 = 0 ;
DWORD Bytes1 = 0 ;
if ( FEventIndex ) Cursor = FBufferSizeBySample;
else Cursor = 0;
if ( FUpdated )
{
// блокировние буффера драйвера
FBuffer->Lock( Cursor, FBufferSizeBySample , &Buff0 , &Bytes0 , &Buff1 , &Bytes1 , 0 );
try
{
// вход в критическую секции
EnterCriticalSection(&FCriticalSection);
// копирование формы сигнала в буфер драйвера
memcpy ( Buff0 , FControlPWMPackage , FBufferSizeBySample * sizeof(short) );
FUpdated = false;
// выход из критической секции
LeaveCriticalSection(&FCriticalSection);
}
catch (...)
{
// на всякий случай
}
// разблокирование буффера драйвера
FBuffer->Unlock( Buff0 , Bytes0 , Buff1 , Bytes1 );
}
}
}
FBuffer->Stop();
FBuffer->Release();
FDAC->Release();
}
|
Отредактировано klen — 02/08/2005, 07:58 |
|
klen |
Отправлено: 02.08.2005, 07:57 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
Вот как это выглядит снаружи
Присоединить изображение
|
|
|