{"schemaVersion":"1.0","type":"Article","types":["Article"],"slug":"transferring-data-between-computers-using-audio-on-windows-11-ws8xv","url":"https://zyvop.com/transferring-data-between-computers-using-audio-on-windows-11-ws8xv","title":"Transferring Data Between Computers Using Audio on Windows 11","subtitle":null,"tldr":"LINK： ‣ send: #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #pragma comment(lib, \"winmm.lib\") #define AUDIO_BITS_PER_SAMPLE 16 #de...","keywords":[],"entities":["I0veD","cyber security researcher","ZyVOP"],"keyTakeaways":["LINK： ‣ send: #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #pragma comment(lib, \"winmm.lib\") #define AUDIO_BITS_PER_SAMPLE 16 #define AUDIO_SAMPLE_RATE 8000 #define TONE_LENGTH_MS 50 #define TRANSMISSION_START_FREQUENCY 2000 #define BIT_TONE_FREQUENCY_ON 600 #define BIT_TONE_FREQUENCY_OFF 800 #define TRANSMISSION_END_FREQUENCY 1500 #define BIT_TONE_FREQUENCY_NEXT 1200 struct WaveHeaderStruct { DWORD dwChunkID; DWORD dwChunkSize; DWORD dwFormat; DWORD dwSubChunk1ID; DWORD dwSubChunk1Size; WORD wAudioFormat; WORD wNumChannels; DWORD dwSampleRate; DWORD dwByteRate; WORD wBlockAlign; WORD wBitsPerSample; DWORD dwSubChunk2ID; DWORD dwSubChunk2Size; }; FILE* pGlobal_WaveFile = NULL; DWORD dwGlobal_TotalWaveDataLength = 0; WaveHeaderStruct Global_WaveHeader; DWORD InitialiseWaveFile(char* pFilePath) { // create output file errno_t err = fopen_s(&amp;pGlobal_WaveFile, pFilePath, \"wb\"); if (err != 0 || pGlobal_WaveFile == NULL) { return 1; } // reset data length dwGlobal_TotalWaveDataLength = 0; // generate initial wave header memset((void*)&amp;amp;Global_WaveHeader, 0, sizeof(Global_WaveHeader)); Global_WaveHeader.dwChunkID = 0x46464952; Global_WaveHeader.dwChunkSize = 36; Global_WaveHeader.dwFormat = 0x45564157; Global_WaveHeader.dwSubChunk1ID = 0x20746D66; Global_WaveHeader.dwSubChunk1Size = 16; Global_WaveHeader.wAudioFormat = 1; Global_WaveHeader.wNumChannels = 1; Global_WaveHeader.dwSampleRate = AUDIO_SAMPLE_RATE; Global_WaveHeader.dwByteRate = AUDIO_SAMPLE_RATE * (AUDIO_BITS_PER_SAMPLE / 8); Global_WaveHeader.wBlockAlign = AUDIO_BITS_PER_SAMPLE / 8; Global_WaveHeader.wBitsPerSample = AUDIO_BITS_PER_SAMPLE; Global_WaveHeader.dwSubChunk2ID = 0x61746164; Global_WaveHeader.dwSubChunk2Size = 0; // write header to file fwrite((void*)&amp;amp;Global_WaveHeader, sizeof(Global_WaveHeader), 1, pGlobal_WaveFile); return 0; } DWORD CloseWaveFile() { // move back to the start of the file rewind(pGlobal_WaveFile); // store total data length in wave header Global_WaveHeader.dwChunkSize += dwGlobal_TotalWaveDataLength; Global_WaveHeader.dwSubChunk2Size += dwGlobal_TotalWaveDataLength; // write the updated header fwrite((void*)&amp;amp;Global_WaveHeader, sizeof(Global_WaveHeader), 1, pGlobal_WaveFile); // close file handle fclose(pGlobal_WaveFile); return 0; } DWORD GenerateTone(DWORD dwFrequency, DWORD dwDuration) { DWORD dwSampleCount = 0; DWORD dwTotalSize = 0; double dPeriod = 0; WORD* pwSampleList = NULL; // set initial values dwSampleCount = (AUDIO_SAMPLE_RATE * dwDuration) / 1000; dwTotalSize = dwSampleCount * sizeof(WORD); dPeriod = AUDIO_SAMPLE_RATE / (double)dwFrequency; // allocate memory for audio samples pwSampleList = (WORD*)malloc(dwTotalSize); if (pwSampleList == NULL) { return 1; } listen： #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #pragma comment(lib, \"winmm.lib\") #define AUDIO_BITS_PER_SAMPLE 16 #define AUDIO_SAMPLE_RATE 8000 #define TRANSMISSION_START_FREQUENCY 2000 #define BIT_TONE_FREQUENCY_ON 600 #define BIT_TONE_FREQUENCY_OFF 800 #define TRANSMISSION_END_FREQUENCY 1500 #define BIT_TONE_FREQUENCY_NEXT 1200 #define TONE_THRESHOLD 500 DWORD dwGlobal_TransmissionStarted = 0; DWORD dwGlobal_BitsReceived = 0; BYTE bGlobal_RecvBits[8]; DWORD dwGlobal_LastToneType = 0; // 1 second audio buffer BYTE bGlobal_AudioBuffer[AUDIO_SAMPLE_RATE * sizeof(WORD)]; double CalculateToneMagnitude(short *pSamples, DWORD dwSampleCount, DWORD dwTargetFrequency) { DWORD dwK = 0; double dScalingFactor = 0; double dW = 0; double dSine = 0; double dCosine = 0; double dCoeff = 0; double dQ0 = 0; double dQ1 = 0; double dQ2 = 0; double dMagnitude = 0; // set initial values for goertzel algorithm dScalingFactor = (double)dwSampleCount / 2.0; dwK = (DWORD)(0.5 + (((double)dwSampleCount * (double)dwTargetFrequency) / AUDIO_SAMPLE_RATE)); dW = (2.0 * 3.14159 * (double)dwK) / (double)dwSampleCount; dSine = sin(dW); dCosine = cos(dW); dCoeff = 2.0 * dCosine; // process all samples for(DWORD i = 0; i &amp;lt; dwSampleCount; i++) { // process current sample dQ0 = (dCoeff * dQ1) - dQ2 + pSamples[i]; dQ2 = dQ1; dQ1 = dQ0; } // calculate magnitude dMagnitude = (double)sqrtf((float)((dQ1 * dQ1) + (dQ2 * dQ2) - (dQ1 * dQ2 * dCoeff))); dMagnitude /= 100; return dMagnitude; } DWORD ProcessSamples() { BYTE bRecvByte = 0; DWORD dwSamplesRemaining = 0; DWORD dwCurrSampleIndex = 0; DWORD dwCurrChunkSize = 0; short *pCurrSamplePtr = NULL; double dFrequencySignal_TransmissionStart = 0; double dFrequencySignal_TransmissionStart2 = 0; double dFrequencySignal_TransmissionEnd = 0; double dFrequencySignal_NextBit = 0; double dFrequencySignal_BitOn = 0; double dFrequencySignal_BitOff = 0; double dStrongestTone = 0; DWORD dwStrongestToneType = 0; // process current samples dwSamplesRemaining = sizeof(bGlobal_AudioBuffer) / sizeof(WORD); dwCurrSampleIndex = 0; for(;;) { // check of all samples have been processed if(dwSamplesRemaining == 0) { // finished break; } // calculate current chunk size (25ms) dwCurrChunkSize = (AUDIO_SAMPLE_RATE / 40); if(dwSamplesRemaining &amp;lt; dwCurrChunkSize) { dwCurrChunkSize = dwSamplesRemaining; } // get current sample position pCurrSamplePtr = (short*)&amp;amp;bGlobal_AudioBuffer[dwCurrSampleIndex * sizeof(WORD)]; // check if a transmission is already in progress if(dwGlobal_TransmissionStarted == 0) { // no transmission - check if a new one is starting dFrequencySignal_TransmissionStart = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_START_FREQUENCY); if(dFrequencySignal_TransmissionStart &amp;gt;= TONE_THRESHOLD) { // new data transmission detected dwGlobal_BitsReceived = 0; dwGlobal_LastToneType = TRANSMISSION_START_FREQUENCY; dwGlobal_TransmissionStarted = 1; } } else { // a transmission is already in progress - get next tone dFrequencySignal_TransmissionStart = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_START_FREQUENCY); dFrequencySignal_BitOn = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_ON); dFrequencySignal_BitOff = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_OFF); dFrequencySignal_NextBit = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_NEXT); dFrequencySignal_TransmissionEnd = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_END_FREQUENCY); // check for the strongest tone dStrongestTone = 0; dwStrongestToneType = 0; if(dFrequencySignal_TransmissionStart &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_TransmissionStart; dwStrongestToneType = TRANSMISSION_START_FREQUENCY; } if(dFrequencySignal_BitOn &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_BitOn; dwStrongestToneType = BIT_TONE_FREQUENCY_ON; } if(dFrequencySignal_BitOff &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_BitOff; dwStrongestToneType = BIT_TONE_FREQUENCY_OFF; } if(dFrequencySignal_NextBit &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_NextBit; dwStrongestToneType = BIT_TONE_FREQUENCY_NEXT; } if(dFrequencySignal_TransmissionEnd &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_TransmissionEnd; dwStrongestToneType = TRANSMISSION_END_FREQUENCY; } // ensure at least one frequency is above the minimum threshold if(dStrongestTone &amp;lt; TONE_THRESHOLD) { if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** DATA CORRUPT - CANCELLED TRANSMISSION **\\n&amp;quot;); } dwGlobal_TransmissionStarted = 0; } else { // check if the tone has changed if(dwStrongestToneType != dwGlobal_LastToneType) { // new tone detected if(dwStrongestToneType == TRANSMISSION_START_FREQUENCY) { // found &amp;quot;transmission start&amp;quot; tone but already receiving data if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** DATA CORRUPT - CANCELLED TRANSMISSION **\\n&amp;quot;); } dwGlobal_TransmissionStarted = 0; } else if(dwStrongestToneType != BIT_TONE_FREQUENCY_NEXT) { // check if this is a data bit if(dwStrongestToneType == BIT_TONE_FREQUENCY_ON || dwStrongestToneType == BIT_TONE_FREQUENCY_OFF) { if(dwGlobal_BitsReceived == 0) { // receiving first data bit printf(&amp;quot;** RECEIVING DATA **\\n&amp;quot;); } // check if the &amp;quot;on&amp;quot; or &amp;quot;off&amp;quot; bit tone is strongest if(dwStrongestToneType == BIT_TONE_FREQUENCY_ON) { // received &amp;quot;1&amp;quot; bit bGlobal_RecvBits[7 - (dwGlobal_BitsReceived % 8)] = 1; } else { // received &amp;quot;0&amp;quot; bit bGlobal_RecvBits[7 - (dwGlobal_BitsReceived % 8)] = 0; } // wait for confirmation before reading next bit dwGlobal_BitsReceived++; // check if a full byte (8 bits) has been received if(dwGlobal_BitsReceived % 8 == 0) { // convert bits to byte bRecvByte = 0; for(DWORD i = 0; i &amp;lt; 8; i++) { // convert current bit bRecvByte |= (bGlobal_RecvBits[i] &amp;lt;&amp;lt; i); } // print current byte printf(&amp;quot;%c&amp;quot;, bRecvByte); } } else if(dwStrongestToneType == TRANSMISSION_END_FREQUENCY) { // end of transmission if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** END OF TRANSMISSION (received %u bytes) **\\n&amp;quot;, dwGlobal_BitsReceived / 8); } dwGlobal_TransmissionStarted = 0; } } // store last tone type dwGlobal_LastToneType = dwStrongestToneType; } } } // update values for next chunk dwSamplesRemaining -= dwCurrChunkSize; dwCurrSampleIndex += dwCurrChunkSize; } return 0; } int main() { HWAVEIN hWave = NULL; WAVEHDR WaveHeaderData; WAVEFORMATEX WaveFormatData; DWORD dwRetnVal = 0; HANDLE hWaveEvent = NULL; // create event hWaveEvent = CreateEvent(NULL, 1, 0, NULL); if(hWaveEvent == NULL) { return 1; } // set wave format data memset((void*)&amp;amp;WaveFormatData, 0, sizeof(WaveFormatData)); WaveFormatData.wFormatTag = WAVE_FORMAT_PCM; WaveFormatData.wBitsPerSample = AUDIO_BITS_PER_SAMPLE; WaveFormatData.nChannels = 1; WaveFormatData.nSamplesPerSec = AUDIO_SAMPLE_RATE; WaveFormatData.nAvgBytesPerSec = AUDIO_BITS_PER_SAMPLE * (AUDIO_BITS_PER_SAMPLE / 8); WaveFormatData.nBlockAlign = AUDIO_BITS_PER_SAMPLE / 8; WaveFormatData.cbSize = 0; // open wave handle if(waveInOpen(&amp;amp;hWave, WAVE_MAPPER, &amp;amp;WaveFormatData, (DWORD)hWaveEvent, 0, CALLBACK_EVENT | WAVE_FORMAT_DIRECT) != MMSYSERR_NOERROR) { CloseHandle(hWaveEvent); return 1; } for(;;) { // set wave header data memset((void*)&amp;amp;WaveHeaderData, 0, sizeof(WaveHeaderData)); WaveHeaderData.lpData = (LPSTR)bGlobal_AudioBuffer; WaveHeaderData.dwBufferLength = sizeof(bGlobal_AudioBuffer); WaveHeaderData.dwBytesRecorded = 0; WaveHeaderData.dwUser = 0; WaveHeaderData.dwFlags = 0; WaveHeaderData.dwLoops = 0; // prepare wave header if(waveInPrepareHeader(hWave, &amp;amp;WaveHeaderData, sizeof(WaveHeaderData)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // add wave input buffer if(waveInAddBuffer(hWave, &amp;amp;WaveHeaderData, sizeof(WaveHeaderData)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // reset event ResetEvent(hWaveEvent); // start recording if(waveInStart(hWave) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // wait until recording has finished for(;;) { // wait for event to fire WaitForSingleObject(hWaveEvent, INFINITE); // check if sample has finished recording if(WaveHeaderData.dwFlags &amp;amp; WHDR_DONE) { // finished break; } } // unprepare wave header if(waveInUnprepareHeader(hWave, &amp;amp;WaveHeaderData, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // process audio samples if(ProcessSamples() != 0) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } } // close wave handle waveInClose(hWave); // close event CloseHandle(hWaveEvent); return 0; }."],"headings":[],"outboundLinks":[],"contentText":"LINK： ‣ send: #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #pragma comment(lib, \"winmm.lib\") #define AUDIO_BITS_PER_SAMPLE 16 #define AUDIO_SAMPLE_RATE 8000 #define TONE_LENGTH_MS 50 #define TRANSMISSION_START_FREQUENCY 2000 #define BIT_TONE_FREQUENCY_ON 600 #define BIT_TONE_FREQUENCY_OFF 800 #define TRANSMISSION_END_FREQUENCY 1500 #define BIT_TONE_FREQUENCY_NEXT 1200 struct WaveHeaderStruct { DWORD dwChunkID; DWORD dwChunkSize; DWORD dwFormat; DWORD dwSubChunk1ID; DWORD dwSubChunk1Size; WORD wAudioFormat; WORD wNumChannels; DWORD dwSampleRate; DWORD dwByteRate; WORD wBlockAlign; WORD wBitsPerSample; DWORD dwSubChunk2ID; DWORD dwSubChunk2Size; }; FILE* pGlobal_WaveFile = NULL; DWORD dwGlobal_TotalWaveDataLength = 0; WaveHeaderStruct Global_WaveHeader; DWORD InitialiseWaveFile(char* pFilePath) { // create output file errno_t err = fopen_s(&amp;pGlobal_WaveFile, pFilePath, \"wb\"); if (err != 0 || pGlobal_WaveFile == NULL) { return 1; } // reset data length dwGlobal_TotalWaveDataLength = 0; // generate initial wave header memset((void*)&amp;amp;Global_WaveHeader, 0, sizeof(Global_WaveHeader)); Global_WaveHeader.dwChunkID = 0x46464952; Global_WaveHeader.dwChunkSize = 36; Global_WaveHeader.dwFormat = 0x45564157; Global_WaveHeader.dwSubChunk1ID = 0x20746D66; Global_WaveHeader.dwSubChunk1Size = 16; Global_WaveHeader.wAudioFormat = 1; Global_WaveHeader.wNumChannels = 1; Global_WaveHeader.dwSampleRate = AUDIO_SAMPLE_RATE; Global_WaveHeader.dwByteRate = AUDIO_SAMPLE_RATE * (AUDIO_BITS_PER_SAMPLE / 8); Global_WaveHeader.wBlockAlign = AUDIO_BITS_PER_SAMPLE / 8; Global_WaveHeader.wBitsPerSample = AUDIO_BITS_PER_SAMPLE; Global_WaveHeader.dwSubChunk2ID = 0x61746164; Global_WaveHeader.dwSubChunk2Size = 0; // write header to file fwrite((void*)&amp;amp;Global_WaveHeader, sizeof(Global_WaveHeader), 1, pGlobal_WaveFile); return 0; } DWORD CloseWaveFile() { // move back to the start of the file rewind(pGlobal_WaveFile); // store total data length in wave header Global_WaveHeader.dwChunkSize += dwGlobal_TotalWaveDataLength; Global_WaveHeader.dwSubChunk2Size += dwGlobal_TotalWaveDataLength; // write the updated header fwrite((void*)&amp;amp;Global_WaveHeader, sizeof(Global_WaveHeader), 1, pGlobal_WaveFile); // close file handle fclose(pGlobal_WaveFile); return 0; } DWORD GenerateTone(DWORD dwFrequency, DWORD dwDuration) { DWORD dwSampleCount = 0; DWORD dwTotalSize = 0; double dPeriod = 0; WORD* pwSampleList = NULL; // set initial values dwSampleCount = (AUDIO_SAMPLE_RATE * dwDuration) / 1000; dwTotalSize = dwSampleCount * sizeof(WORD); dPeriod = AUDIO_SAMPLE_RATE / (double)dwFrequency; // allocate memory for audio samples pwSampleList = (WORD*)malloc(dwTotalSize); if (pwSampleList == NULL) { return 1; } listen： #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #pragma comment(lib, \"winmm.lib\") #define AUDIO_BITS_PER_SAMPLE 16 #define AUDIO_SAMPLE_RATE 8000 #define TRANSMISSION_START_FREQUENCY 2000 #define BIT_TONE_FREQUENCY_ON 600 #define BIT_TONE_FREQUENCY_OFF 800 #define TRANSMISSION_END_FREQUENCY 1500 #define BIT_TONE_FREQUENCY_NEXT 1200 #define TONE_THRESHOLD 500 DWORD dwGlobal_TransmissionStarted = 0; DWORD dwGlobal_BitsReceived = 0; BYTE bGlobal_RecvBits[8]; DWORD dwGlobal_LastToneType = 0; // 1 second audio buffer BYTE bGlobal_AudioBuffer[AUDIO_SAMPLE_RATE * sizeof(WORD)]; double CalculateToneMagnitude(short *pSamples, DWORD dwSampleCount, DWORD dwTargetFrequency) { DWORD dwK = 0; double dScalingFactor = 0; double dW = 0; double dSine = 0; double dCosine = 0; double dCoeff = 0; double dQ0 = 0; double dQ1 = 0; double dQ2 = 0; double dMagnitude = 0; // set initial values for goertzel algorithm dScalingFactor = (double)dwSampleCount / 2.0; dwK = (DWORD)(0.5 + (((double)dwSampleCount * (double)dwTargetFrequency) / AUDIO_SAMPLE_RATE)); dW = (2.0 * 3.14159 * (double)dwK) / (double)dwSampleCount; dSine = sin(dW); dCosine = cos(dW); dCoeff = 2.0 * dCosine; // process all samples for(DWORD i = 0; i &amp;lt; dwSampleCount; i++) { // process current sample dQ0 = (dCoeff * dQ1) - dQ2 + pSamples[i]; dQ2 = dQ1; dQ1 = dQ0; } // calculate magnitude dMagnitude = (double)sqrtf((float)((dQ1 * dQ1) + (dQ2 * dQ2) - (dQ1 * dQ2 * dCoeff))); dMagnitude /= 100; return dMagnitude; } DWORD ProcessSamples() { BYTE bRecvByte = 0; DWORD dwSamplesRemaining = 0; DWORD dwCurrSampleIndex = 0; DWORD dwCurrChunkSize = 0; short *pCurrSamplePtr = NULL; double dFrequencySignal_TransmissionStart = 0; double dFrequencySignal_TransmissionStart2 = 0; double dFrequencySignal_TransmissionEnd = 0; double dFrequencySignal_NextBit = 0; double dFrequencySignal_BitOn = 0; double dFrequencySignal_BitOff = 0; double dStrongestTone = 0; DWORD dwStrongestToneType = 0; // process current samples dwSamplesRemaining = sizeof(bGlobal_AudioBuffer) / sizeof(WORD); dwCurrSampleIndex = 0; for(;;) { // check of all samples have been processed if(dwSamplesRemaining == 0) { // finished break; } // calculate current chunk size (25ms) dwCurrChunkSize = (AUDIO_SAMPLE_RATE / 40); if(dwSamplesRemaining &amp;lt; dwCurrChunkSize) { dwCurrChunkSize = dwSamplesRemaining; } // get current sample position pCurrSamplePtr = (short*)&amp;amp;bGlobal_AudioBuffer[dwCurrSampleIndex * sizeof(WORD)]; // check if a transmission is already in progress if(dwGlobal_TransmissionStarted == 0) { // no transmission - check if a new one is starting dFrequencySignal_TransmissionStart = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_START_FREQUENCY); if(dFrequencySignal_TransmissionStart &amp;gt;= TONE_THRESHOLD) { // new data transmission detected dwGlobal_BitsReceived = 0; dwGlobal_LastToneType = TRANSMISSION_START_FREQUENCY; dwGlobal_TransmissionStarted = 1; } } else { // a transmission is already in progress - get next tone dFrequencySignal_TransmissionStart = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_START_FREQUENCY); dFrequencySignal_BitOn = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_ON); dFrequencySignal_BitOff = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_OFF); dFrequencySignal_NextBit = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, BIT_TONE_FREQUENCY_NEXT); dFrequencySignal_TransmissionEnd = CalculateToneMagnitude(pCurrSamplePtr, dwCurrChunkSize, TRANSMISSION_END_FREQUENCY); // check for the strongest tone dStrongestTone = 0; dwStrongestToneType = 0; if(dFrequencySignal_TransmissionStart &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_TransmissionStart; dwStrongestToneType = TRANSMISSION_START_FREQUENCY; } if(dFrequencySignal_BitOn &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_BitOn; dwStrongestToneType = BIT_TONE_FREQUENCY_ON; } if(dFrequencySignal_BitOff &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_BitOff; dwStrongestToneType = BIT_TONE_FREQUENCY_OFF; } if(dFrequencySignal_NextBit &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_NextBit; dwStrongestToneType = BIT_TONE_FREQUENCY_NEXT; } if(dFrequencySignal_TransmissionEnd &amp;gt; dStrongestTone) { dStrongestTone = dFrequencySignal_TransmissionEnd; dwStrongestToneType = TRANSMISSION_END_FREQUENCY; } // ensure at least one frequency is above the minimum threshold if(dStrongestTone &amp;lt; TONE_THRESHOLD) { if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** DATA CORRUPT - CANCELLED TRANSMISSION **\\n&amp;quot;); } dwGlobal_TransmissionStarted = 0; } else { // check if the tone has changed if(dwStrongestToneType != dwGlobal_LastToneType) { // new tone detected if(dwStrongestToneType == TRANSMISSION_START_FREQUENCY) { // found &amp;quot;transmission start&amp;quot; tone but already receiving data if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** DATA CORRUPT - CANCELLED TRANSMISSION **\\n&amp;quot;); } dwGlobal_TransmissionStarted = 0; } else if(dwStrongestToneType != BIT_TONE_FREQUENCY_NEXT) { // check if this is a data bit if(dwStrongestToneType == BIT_TONE_FREQUENCY_ON || dwStrongestToneType == BIT_TONE_FREQUENCY_OFF) { if(dwGlobal_BitsReceived == 0) { // receiving first data bit printf(&amp;quot;** RECEIVING DATA **\\n&amp;quot;); } // check if the &amp;quot;on&amp;quot; or &amp;quot;off&amp;quot; bit tone is strongest if(dwStrongestToneType == BIT_TONE_FREQUENCY_ON) { // received &amp;quot;1&amp;quot; bit bGlobal_RecvBits[7 - (dwGlobal_BitsReceived % 8)] = 1; } else { // received &amp;quot;0&amp;quot; bit bGlobal_RecvBits[7 - (dwGlobal_BitsReceived % 8)] = 0; } // wait for confirmation before reading next bit dwGlobal_BitsReceived++; // check if a full byte (8 bits) has been received if(dwGlobal_BitsReceived % 8 == 0) { // convert bits to byte bRecvByte = 0; for(DWORD i = 0; i &amp;lt; 8; i++) { // convert current bit bRecvByte |= (bGlobal_RecvBits[i] &amp;lt;&amp;lt; i); } // print current byte printf(&amp;quot;%c&amp;quot;, bRecvByte); } } else if(dwStrongestToneType == TRANSMISSION_END_FREQUENCY) { // end of transmission if(dwGlobal_BitsReceived != 0) { printf(&amp;quot;\\n** END OF TRANSMISSION (received %u bytes) **\\n&amp;quot;, dwGlobal_BitsReceived / 8); } dwGlobal_TransmissionStarted = 0; } } // store last tone type dwGlobal_LastToneType = dwStrongestToneType; } } } // update values for next chunk dwSamplesRemaining -= dwCurrChunkSize; dwCurrSampleIndex += dwCurrChunkSize; } return 0; } int main() { HWAVEIN hWave = NULL; WAVEHDR WaveHeaderData; WAVEFORMATEX WaveFormatData; DWORD dwRetnVal = 0; HANDLE hWaveEvent = NULL; // create event hWaveEvent = CreateEvent(NULL, 1, 0, NULL); if(hWaveEvent == NULL) { return 1; } // set wave format data memset((void*)&amp;amp;WaveFormatData, 0, sizeof(WaveFormatData)); WaveFormatData.wFormatTag = WAVE_FORMAT_PCM; WaveFormatData.wBitsPerSample = AUDIO_BITS_PER_SAMPLE; WaveFormatData.nChannels = 1; WaveFormatData.nSamplesPerSec = AUDIO_SAMPLE_RATE; WaveFormatData.nAvgBytesPerSec = AUDIO_BITS_PER_SAMPLE * (AUDIO_BITS_PER_SAMPLE / 8); WaveFormatData.nBlockAlign = AUDIO_BITS_PER_SAMPLE / 8; WaveFormatData.cbSize = 0; // open wave handle if(waveInOpen(&amp;amp;hWave, WAVE_MAPPER, &amp;amp;WaveFormatData, (DWORD)hWaveEvent, 0, CALLBACK_EVENT | WAVE_FORMAT_DIRECT) != MMSYSERR_NOERROR) { CloseHandle(hWaveEvent); return 1; } for(;;) { // set wave header data memset((void*)&amp;amp;WaveHeaderData, 0, sizeof(WaveHeaderData)); WaveHeaderData.lpData = (LPSTR)bGlobal_AudioBuffer; WaveHeaderData.dwBufferLength = sizeof(bGlobal_AudioBuffer); WaveHeaderData.dwBytesRecorded = 0; WaveHeaderData.dwUser = 0; WaveHeaderData.dwFlags = 0; WaveHeaderData.dwLoops = 0; // prepare wave header if(waveInPrepareHeader(hWave, &amp;amp;WaveHeaderData, sizeof(WaveHeaderData)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // add wave input buffer if(waveInAddBuffer(hWave, &amp;amp;WaveHeaderData, sizeof(WaveHeaderData)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // reset event ResetEvent(hWaveEvent); // start recording if(waveInStart(hWave) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // wait until recording has finished for(;;) { // wait for event to fire WaitForSingleObject(hWaveEvent, INFINITE); // check if sample has finished recording if(WaveHeaderData.dwFlags &amp;amp; WHDR_DONE) { // finished break; } } // unprepare wave header if(waveInUnprepareHeader(hWave, &amp;amp;WaveHeaderData, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } // process audio samples if(ProcessSamples() != 0) { // error CloseHandle(hWaveEvent); waveInClose(hWave); return 1; } } // close wave handle waveInClose(hWave); // close event CloseHandle(hWaveEvent); return 0; }","contentHash":"sha256:d21f3bfd3d0350db99df8c33a04f115f7286dbc2ea62d81bef749609274d07a2","authorName":"I0veD","authorUrl":"https://zyvop.com/author/i0ved","authorSameAs":["https://www.cdxiaodong.life/","https://github.com/cdxiaodong","https://www.linkedin.com/in/%E6%A0%8B-%E7%A8%8B-167b89391/"],"category":null,"tags":[],"audience":"Software engineers and developers building applications with software development","tone":"Professional, cyber security researcher perspective","readingTimeMinutes":4,"wordCount":1025,"faqs":null,"primaryTopic":null,"publishedAt":"2026-08-12T05:35:21.299Z","updatedAt":"2026-08-28T13:00:00.098Z","canonicalUrl":"https://www.cdxiaodong.life/article/AudioTransmit"}