Visual Studioの場合、volatileとして宣言された変数にはメモリーフェンス操作が含まれます(このオプションがオフになっていない場合は、デフォルトでオン)ので、スレッド間で使用できます。このコードでは、音楽トラックを再生するための揮発性変数を使用することができます。私は以下のCコード例を含めました。
私は、音楽を再生している間は、Beep()はCPUに束縛されないことを前提としています(Windows XPのようではありません)。
より正確なタイミングを得るために、ticker frequencyを64hz(15.625ms)から1000hz(1ms)に増やすためにtimeBeginPeriod()を使用できます。 Windows XPとおそらくWindows 2000の場合、Sleep()と私の推測Beep()は128ティックごとに3つの余分な実際のティックを追加して1000hzティッカーをエミュレートするのに対して、timeBeginPeriod(1)は1024hzで実際にティッカーを実行させます125ミリ秒の境界線上で立ち上がります。これは、Sleep(1)が(42,84、および125コールで)時々約2msまでかかる可能性があることを意味します。
注 - 最終的に通信するハードウェアが不足しているため、Windows VistaおよびWindows XP 64ビット版ではビープ音はサポートされませんでした。 Windows 7では、ビープ音がセッションのデフォルトのサウンドデバイスに送信されるように書き換えられました。これは通常、ターミナルサービスで実行されている場合を除いてサウンドカードです。この場合、ビープ音はクライアントで表示されます。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms679277(v=vs.85).aspx
例マルチスレッド "ビープ" コード。このコードは、PCスピーカーを使用してWindows XPで正常に動作します。 Windows 7では、サウンドカードを使用しており、音符の間には何らかの無音があります。
/*----------------------------------------------------------------------*/
/* mtbeep.c multi-thread beep demo */
/*----------------------------------------------------------------------*/
#include <windows.h>
/* include winmm.lib for timeBeginPeriod */
#pragma comment(lib, "winmm.lib")
#define TRACK0 0
#define TRACK1 1
#define TRACK2 2
#define TRACKX 3 /* exit thread 1 if trackx */
typedef struct {
DWORD dwFreq;
DWORD dwDuration;
}NOTE;
/*----------------------------------------------------------------------*/
/* data */
/*----------------------------------------------------------------------*/
static HANDLE htT1; /* thread 1 handle */
static DWORD dwThreadT1; /* thread id's (not used) */
static volatile DWORD dwTrack; /* beep track to play */
/* songs */
static NOTE anTrack0[4] = {300, 500, 450, 500, 600, 500, 0, 0};
static NOTE anTrack1[4] = { 0, 250};
static NOTE anTrack2[4] = {400, 500, 300, 500, 200, 500, 0, 0};
static NOTE anTrackx[4] = {0, 0};
/*----------------------------------------------------------------------*/
/* code */
/*----------------------------------------------------------------------*/
static DWORD WINAPI Thread0(LPVOID);
static DWORD WINAPI Thread1(LPVOID);
/*----------------------------------------------------------------------*/
/* main */
/*----------------------------------------------------------------------*/
DWORD main(DWORD argc, BYTE **argv)
{
timeBeginPeriod(1); /* set period to 1ms */
Sleep(128); /* wait for it to stabilize */
/* create thread */
htT1 = CreateThread(NULL, 0, Thread1, 0, 0, &dwThreadT1);
if(!htT1){
/* createthread failed */
goto exit0;}
Thread0((LPVOID)NULL); /* start Thread 0 */
exit0:
if(htT1){ /* close thread */
dwTrack = TRACKX;
WaitForSingleObject(htT1, INFINITE);
CloseHandle(htT1);}
timeEndPeriod(1); /* restore period */
return(0);
}
/*----------------------------------------------------------------------*/
/* Thread0 */
/*----------------------------------------------------------------------*/
static DWORD WINAPI Thread0(LPVOID lpvoid)
{
int i;
for(i = 0; i < 4; i++){
dwTrack = i%3;
Sleep(5000);
}
return 0;
}
/*----------------------------------------------------------------------*/
/* Thread1 beep thread */
/*----------------------------------------------------------------------*/
static DWORD WINAPI Thread1(LPVOID lpvoid)
{
NOTE *apTrack[4] = {anTrack0, anTrack1, anTrack2, anTrackx};
NOTE *pTrack = anTrack0; /* ptr to array of notes */
DWORD cTrack = TRACKX; /* current track */
int iNote = 0; /* note index */
while(dwTrack != TRACKX){ /* play a note loop */
if(cTrack != dwTrack){ /* if song changed */
iNote = 0; /* start at first note */
cTrack = dwTrack; /* of next song */
pTrack = apTrack[cTrack];
}
if(!pTrack[iNote].dwDuration) /* if end of song */
iNote = 0; /* reset note index */
if(pTrack[iNote].dwFreq) /* if note play it */
Beep(pTrack[iNote].dwFreq, pTrack[iNote].dwDuration);
else /* else silence */
Sleep(pTrack[iNote].dwDuration);
iNote++;
}
return(0);
}
はWIN32の[マルチスレッド]を記述するMSDN上のリソース(https://msdn.microsoft.com/en-us/library/y6h8hye8(V = vs.80).aspxの)機能をがあります。 ''ライブラリのような新しいC++機能にアクセスすることができなければ、あなたはWIN32システムコールを使って手動で多くのことをする必要があります。 –
lcs
トラック番号のみを転送する場合は、アトムint 'trackNum' varを使用し、サウンドスレッドがトラックの最後に到達したときにそれを読み取らせ、ネスト1を選択する必要がある(または同じものを繰り返す) )。それを止める必要がある場合は、「-1」は「今すぐ停止してイベントを待つ」という意味にすることができます。 – ThingyWotsit
はい、どうしたら新しいスレッドを作成してこれを許可しますか?簡単な例を教えてください。 – FAMICOMASTER