Comment puis-je, disons, jouez un son avec une amplitude donnée et un maquillage de fréquence donné (disons, composé de fréquences 2 kHz et 3 kHz) de manière natale sous Windows (32 bits et 64 bits, jusqu'à Windows 7) ? p>
(par natif, je veux dire sans utiliser de bibliothèque externe.) p>
Je crois que cela a besoin de méthode WaveOutwrite mais je n'ai aucune idée Comment ça marche. P>
4 Réponses :
bip via le haut-parleur PC ou en utilisant DirectX Sound. Je peux offrir des extraits si vous avez besoin. P>
Eh bien, la fonction Beep ne fonctionne pas car elle ne peut pas générer une combinaison de fréquences. DirectX Sound semble être surkill, car je veux juste générer une tonalité simple ... y a-t-il un moyen de le faire avec quelque chose comme WaveOutwrite code>? Je pense que c'est la bonne façon, mais je n'ai aucune idée de quelles données pour le donner.
@Mehrdad: WavOutwrite s'attend à ce que le format WAV au format WAV, IIRC.
@Adam: ah maintenant que i> est une bonne réponse. =) N'hésitez pas à poster cela pour que je puisse l'accepter! (BTW, est-ce que c'est la complète i> des données vagues ou une seule partie de celui-ci? Dois-je aussi envoyer tous les en-têtes de riff?)
the Bien que cela soit ciblé sur les applications WPF, le lien suivant devrait s'avérer utile pour toute application de bureau: P>
Waveout code> Fonctions traite des données de forme d'onde SON (au format WAV, si je vous rappelle correctement). P>
J'ai quelque chose de travail ...
#define _USE_MATH_DEFINES 1 #include <math.h> #include <stdio.h> #include <tchar.h> #include <windows.h> #include <mmreg.h> #include <complex> #pragma comment(lib, "Winmm.lib") MMRESULT play(float nSeconds, float signal(float timeInSeconds, unsigned short channel, void *context), void *context = NULL, unsigned long samplesPerSecond = 48000) { UINT timePeriod = 1; MMRESULT mmresult = MMSYSERR_NOERROR; WAVEFORMATEX waveFormat = {0}; waveFormat.cbSize = 0; waveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; waveFormat.nChannels = 2; waveFormat.nSamplesPerSec = samplesPerSecond; const size_t nBuffer = (size_t)(nSeconds * waveFormat.nChannels * waveFormat.nSamplesPerSec); float *buffer; waveFormat.wBitsPerSample = CHAR_BIT * sizeof(buffer[0]); waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / CHAR_BIT; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; buffer = (float *)calloc(nBuffer, sizeof(*buffer)); __try { for (size_t i = 0; i < nBuffer; i += waveFormat.nChannels) for (unsigned short j = 0; j < waveFormat.nChannels; j++) buffer[i+j] = signal((i+j) * nSeconds / nBuffer, j, context); HWAVEOUT hWavOut = NULL; mmresult = waveOutOpen(&hWavOut, WAVE_MAPPER, &waveFormat, NULL, NULL, CALLBACK_NULL); if (mmresult == MMSYSERR_NOERROR) { __try { timeBeginPeriod(timePeriod); __try { WAVEHDR hdr = {0}; hdr.dwBufferLength = (ULONG)(nBuffer * sizeof(buffer[0])); hdr.lpData = (LPSTR)&buffer[0]; mmresult = waveOutPrepareHeader(hWavOut, &hdr, sizeof(hdr)); if (mmresult == MMSYSERR_NOERROR) { __try { ULONG start = GetTickCount(); mmresult = waveOutWrite(hWavOut, &hdr, sizeof(hdr)); Sleep((ULONG)(1000 * nSeconds - (GetTickCount() - start))); } __finally { waveOutUnprepareHeader(hWavOut, &hdr, sizeof(hdr)); } } } __finally { timeEndPeriod(timePeriod); } } __finally { waveOutClose(hWavOut); } } } __finally { free(buffer); } return mmresult; } // Triangle wave generator float triangle(float timeInSeconds, unsigned short channel, void *context) { const float frequency = *(const float *)context; const float angle = (float)(frequency * 2 * M_PI * timeInSeconds); switch (channel) { case 0: return (float)asin(sin(angle + 0 * M_PI / 2)); default: return (float)asin(sin(angle + 1 * M_PI / 2)); } } // Pure tone generator float pure(float timeInSeconds, unsigned short channel, void *context) { const float frequency = *(const float *)context; const float angle = (float)(frequency * 2 * M_PI * timeInSeconds); switch (channel) { case 0: return (float)sin(angle + 0 * M_PI / 2); default: return (float)sin(angle + 1 * M_PI / 2); } } int _tmain(int argc, _TCHAR* argv[]) { float frequency = 2 * 261.626F; play(1, pure, &frequency); return 0; }
+1. Mais je pense que le générateur de vagues triangle est faux. Selon Wikipedia : retour (flotteur) Asin (NAS (angle + 0 * M_PI / 2)) * 2 / M_PI; code>.