C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
DirectSound, прерывание звука при потере фокуса.
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



Вот как это выглядит снаружи

Присоединить изображение

Присоединить изображение


Вернуться в Вопросы программирования в C++Builder