74HC164Nでシリアルパラレル変換ができるとはByteデータを送り込めるということになります。ソフトウェアを改良しByte単位にデータを送れるか実験してみました。


ピークが15回出ています。これが74HC164Nにリセット信号を送っているところで、その手前が1バイトのビットデータとなります。74HC164NはNOT出力ですので信号が立っているところが0、立っていないところが1と解釈してください。1、3、5、7と増えていくのが波形からわかります。



#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>
#pragma comment (lib, "winmm.lib")
void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
size_t wavelength = sampling / frequency;
double d = 360.0 / wavelength;
double pi = 3.14159265359;
for (int i = 0; i < wavelength; i++) {
lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
}
}
BOOLEAN isON(unsigned char data, size_t bit, size_t i) {
size_t bit9 = bit * 9;
size_t bit8 = bit * 8;
size_t bit7 = bit * 7;
size_t bit6 = bit * 6;
size_t bit5 = bit * 5;
size_t bit4 = bit * 4;
size_t bit3 = bit * 3;
size_t bit2 = bit * 2;
if (((data & 0x80) == 0x80) && 0 <= (i % (bit9)) && (i % (bit9)) < (bit)) {
return true;
}
if (((data & 0x40) == 0x40) && (bit) <= (i % (bit9)) && (i % (bit9)) < (bit2)) {
return true;
}
if (((data & 0x20) == 0x20) && (bit2) <= (i % (bit9)) && (i % (bit9)) < (bit3)) {
return true;
}
if (((data & 0x10) == 0x10) && (bit3) <= (i % (bit9)) && (i % (bit9)) < (bit4)) {
return true;
}
if (((data & 0x08) == 0x08) && (bit4) <= (i % (bit9)) && (i % (bit9)) < (bit5)) {
return true;
}
if (((data & 0x04) == 0x04) && (bit5) <= (i % (bit9)) && (i % (bit9)) < (bit6)) {
return true;
}
if (((data & 0x02) == 0x02) && (bit6) <= (i % (bit9)) && (i % (bit9)) < (bit7)) {
return true;
}
if (((data & 0x01) == 0x01) && (bit7) <= (i % (bit9)) && (i % (bit9)) < (bit8)) {
return true;
}
return false;
}
int main() {
WAVEFORMATEX wfe;
static HWAVEOUT hWaveOut;
static WAVEHDR whdr;
static LPWORD lpWave;
static LPWORD lpWave1;
static LPWORD lpWave2;
static LPWORD lpWave3;
static LPWORD lpWave4;
static LPWORD lpData;
// 最初と最後の1sは出力しないので3以上とする
DWORD terms = 17;
size_t i, j, k, start, end;
size_t frequency = 9;
size_t sampling = 192000;
size_t wavelength = sampling / frequency;
wavelength = sampling / frequency;
wfe.wFormatTag = WAVE_FORMAT_PCM;
wfe.nChannels = 2;
wfe.wBitsPerSample = 16;
wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
wfe.nSamplesPerSec = (DWORD)sampling;
wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);
lpWave1 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);
lpWave2 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);
lpWave3 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);
lpWave4 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);
end = sampling * wfe.nChannels;
WORD amplitude = 32767/4;
for (i = 0; i < end; i++) {
lpWave[i] = 0;
lpWave1[i] = 0;
lpWave2[i] = 0;
lpWave3[i] = 0;
lpWave4[i] = 0;
}
// 最初の1sは出力しない
start = sampling * wfe.nChannels;
end = wfe.nChannels * sampling * terms;
// 最後の1sは出力しない
end -= sampling * wfe.nChannels;
size_t valWavelength;
size_t valFrequency;
size_t bit = wfe.nChannels * sampling / frequency;
/* チャンネル1 ********************************/
lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
createWave(lpData, frequency, sampling, amplitude);
for (i = start, j = 0; i < end; i += 2) {
lpWave[i] = lpData[j];
++j;
if (j >= wavelength) { j = 0; }
}
free(lpData);
/* チャンネル2 ********************************/
// クロック
valFrequency = 3200;
valWavelength = sampling / valFrequency;
lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
createWave(lpData, valFrequency, sampling, amplitude);
for (i = start + 1, j = 0, k = 0; i < end; i += 2, ++j, ++k) {
if (k < sampling / frequency / 2) { lpWave1[i] = lpData[j]; }
if (j >= valWavelength) { j = 0; }
if (k >= sampling / frequency) { k = 0; }
}
free(lpData);
const unsigned char dataList[] = {
0x01,
0x03,
0x07,
0x0F,
0x1F,
0x3F,
0x7F,
0xFF,
0x7F,
0x3F,
0x1F,
0x0F,
0x07,
0x03,
0x01
};
size_t dataLen = sizeof(dataList) / sizeof(*dataList);
unsigned char data = 0x00;
// シリアルデータ1
valFrequency = 8000;
valWavelength = sampling / valFrequency;
lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
createWave(lpData, valFrequency, sampling, amplitude);
for (i = 1, j = 0; i < end; i += 2, ++j) {
lpWave2[start + i] = lpData[j];
if (j >= valWavelength) { j = 0; }
}
free(lpData);
// シリアルデータ2
valFrequency = 11300;
valWavelength = sampling / valFrequency;
lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
createWave(lpData, valFrequency, sampling, amplitude);
for (i = 1, j = 0; i < end; i += 2, ++j) {
lpWave3[start + i] = lpData[j];
if (j >= valWavelength) { j = 0; }
}
for (i = 1, j = 0, k = 0; i < end; i += 2, j += 2) {
data = dataList[k];
if (j >= bit * 9) { j = 0; ++k; }
if (k >= dataLen) { k = 0; }
if (isON(data, bit, i)) {
lpWave3[start + i] = 0;
}
}
free(lpData);
// リセット
valFrequency = 17000;
valWavelength = sampling / valFrequency;
lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
createWave(lpData, valFrequency, sampling, amplitude);
for (i = 1; i < end; i += 2, ++j) {
lpWave4[start + i] = 0;
}
for (i = 1, j = 0; i < end; i += 2, ++j) {
if ((i % (bit * 9)) < bit) {
lpWave4[start + i - bit] = lpData[j];
}
if (j >= valWavelength) { j = 0; }
}
free(lpData);
// チャンネル2に合成
for (i = 1; i < end; i += 2) {
lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i];
}
// サウンド出力
whdr.lpData = (LPSTR)lpWave;
whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
whdr.dwLoops = 1;
waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
char str[128];
std::cout << "hello, world\n";
std::cin >> str;
}