1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
//LENGTH IS NORMALLY EQUAL TO FREQUENCY*TIME
int Audio_Recording(char*data, int length) {
//VARIABLE DECLERATION
int Sample_Rate = FREQUENCY;
HWAVEIN hWaveIn; //Defining a recording device
WAVEHDR WaveIn_HDR; //Defines the header used to identify a waveform-audio buffer
//DEFINING THE FORMAT OF WAVEFORM_AUDIO DATA
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM; //Waveform_audio format type
pFormat.nChannels = 1; //[1 = mono and 2 = stereo] Number of channels in the waveform_audio data
pFormat.nSamplesPerSec = Sample_Rate; //Sample rate, in samples per second (Hz)
pFormat.nAvgBytesPerSec = Sample_Rate; //Required average data-transfer rate, in bytes per seconds, for the format tag -> If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec must equal nSamplesPerSec × nBlockAlign
pFormat.nBlockAlign = 1; //Block alignment, in bytes -> If wFormatTag is WAVE_FORMAT_PCM, nBlockAlign must equal (nChannels × wBitsPerSample) / 8
pFormat.wBitsPerSample = 8; //Bits per sample for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16
pFormat.cbSize = 0; //Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure -> For WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored
/*MMRESULT waveInOpen(
LPHWAVEIN phwi, //Pointer to a buffer that receives a handle identifying the open waveform-audio input device.
UINT uDeviceID, //Identifier of the waveform-audio input device to open -> WAVE_MAPPER: The function selects a waveform-audio input device capable of recording in the specified format
LPCWAVEFORMATEX pwfx, //Pointer to a WAVEFORMATEX structure that identifies the desired format for recording waveform-audio data
DWORD_PTR dwCallback, //Pointer to a fixed callback function, an event handle, a handle to a window, or the identifier of a thread to be called during waveform-audio recording to process messages related to the progress of recording -> If no callback function is required, this value can be 0
DWORD_PTR dwCallbackInstance, //User-instance data passed to the callback mechanism
DWORD fdwOpen //https://msdn.microsoft.com/en-us/library/windows/desktop/dd743847(v=vs.85).aspx
);*/
if (waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0L, 0L, WAVE_FORMAT_DIRECT)) {
return 1;
}
/*typedef struct wavehdr_tag {
LPSTR lpData; //Pointer to the waveform buffer
DWORD dwBufferLength; //Length, in bytes, of the buffer
DWORD dwBytesRecorded; //When the header is used in input, specifies how much data is in the buffer
DWORD_PTR dwUser; //User data
DWORD dwFlags; //A bitwise OR of zero of more flags
DWORD dwLoops; //Number of times to play the loop. This member is used only with output buffer
struct wavehdr_tag *lpNext;
DWORD_PTR reserved;
} WAVEHDR, *LPWAVEHDR;*/
WaveIn_HDR.lpData = (LPSTR)data;
WaveIn_HDR.dwBufferLength = length;
WaveIn_HDR.dwBytesRecorded = 0;
WaveIn_HDR.dwUser = 0L;
WaveIn_HDR.dwFlags = 0L;
WaveIn_HDR.dwLoops = 0L;
/*MMRESULT waveInPrepareHeader(
HWAVEIN hwi, //Handle to the waveform-audio input device
LPWAVEHDR pwh, //Pointer to a WAVEHDR structure that identifies the buffer to be prepared
UINT cbwh //Size of the WAVEHDR structure
);*/
waveInPrepareHeader(hWaveIn, &WaveIn_HDR, sizeof(WAVEHDR));
//The waveInAddBuffer function sends an input buffer to the given waveform-audio input device. When the buffer is filled, the application is notified.
if (waveInAddBuffer(hWaveIn, &WaveIn_HDR, sizeof(WAVEHDR))) {
return 2;
}
if (waveInStart(hWaveIn)) {
return 3;
}
//Function cleans up the preparation performed by the waveInPrepareHeader function... This function must be called after the device driver fills a buffer and returns it to the application. You must call this function before freeing the buffer
while (waveInUnprepareHeader(hWaveIn, &WaveIn_HDR, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) {
Sleep(100); //100 miliseconds: 0.1 second
}
waveInClose(hWaveIn);
return 0;
}
int Playback_Recording(char*data, int length) {
//VARIABLE DECLERATION
int Sample_Rate = FREQUENCY;
HWAVEOUT hWave_Out;
WAVEHDR WaveOut_HDR;
//DEFINING THE FORMAT OF WAVEFORM_AUDIO DATA
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM; //Waveform_audio format type
pFormat.nChannels = 1; //[1 = mono and 2 = stereo] Number of channels in the waveform_audio data
pFormat.nSamplesPerSec = Sample_Rate; //Sample rate, in samples per second (Hz)
pFormat.nAvgBytesPerSec = Sample_Rate; //Required average data-transfer rate, in bytes per seconds, for the format tag -> If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec must equal nSamplesPerSec × nBlockAlign
pFormat.nBlockAlign = 1; //Block alignment, in bytes -> If wFormatTag is WAVE_FORMAT_PCM, nBlockAlign must equal (nChannels × wBitsPerSample) / 8
pFormat.wBitsPerSample = 8; //Bits per sample for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16
pFormat.cbSize = 0; //Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure -> For WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored
/*MMRESULT waveOutOpen(
LPHWAVEOUT phwo, //Pointer to a buffer that receives a handle identifying the open waveform-audio output device
UINT_PTR uDeviceID, //Identifier of the waveform-audio output device to open... WAVE_MAPPER: The function selects a waveform-audio output device capable of playing the given format
LPWAVEFORMATEX pwfx, //Pointer to a WAVEFORMATEX structure that identifies the format of the waveform-audio data to be sent to the device
DWORD_PTR dwCallback, //Specifies the callback mechanism
DWORD_PTR dwCallbackInstance, //User-instance data passed to the callback mechanism
DWORD fdwOpen //Flags for opening the device... https://msdn.microsoft.com/en-us/library/windows/desktop/dd743866(v=vs.85).aspx
);*/
if (waveOutOpen(&hWave_Out, WAVE_MAPPER, &pFormat, 0L, 0L, WAVE_FORMAT_DIRECT)) {
return 1;
}
/*typedef struct wavehdr_tag {
LPSTR lpData; //Pointer to the waveform buffer
DWORD dwBufferLength; //Length, in bytes, of the buffer
DWORD dwBytesRecorded; //When the header is used in input, specifies how much data is in the buffer
DWORD_PTR dwUser; //User data
DWORD dwFlags; //A bitwise OR of zero of more flags
DWORD dwLoops; //Number of times to play the loop. This member is used only with output buffer
struct wavehdr_tag *lpNext;
DWORD_PTR reserved;
} WAVEHDR, *LPWAVEHDR;*/
WaveOut_HDR.lpData = (LPSTR)data;
WaveOut_HDR.dwBufferLength = length;
WaveOut_HDR.dwBytesRecorded = 0;
WaveOut_HDR.dwUser = 0L;
WaveOut_HDR.dwFlags = 0L;
WaveOut_HDR.dwLoops = 0L;
waveOutPrepareHeader(hWave_Out, &WaveOut_HDR, sizeof(WAVEHDR));
if (waveOutWrite(hWave_Out, &WaveOut_HDR, sizeof(WAVEHDR))) {
return 2;
}
while (waveOutUnprepareHeader(hWave_Out, &WaveOut_HDR, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) {
Sleep(100); //100 miliseconds = 0.1 seconds
}
waveOutClose(hWave_Out);
return 0;
}
|