ソフトウェアを改良し複数バイトのデータを送り込めるようにしました。これでROMに書き込みたいデータとクロックや制御信号を混合してパソコンからサウンド出力し、受け側の装置で分離してロジックICを意図通りに動かすことができるようになりました。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") constexpr auto SAMPLING = 192000; constexpr auto CHANNEL = 2; constexpr auto BITSPERSAMPLE = 16; constexpr auto MAXAMP = 32767; constexpr auto DIV = 4; constexpr auto BUFFERING = 10; void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { double wavelength = (double)sampling / (double)frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * i / 180.0 * pi)); } } BOOLEAN isON(unsigned char data, size_t bit, size_t bitLength, size_t value) { int oneByte = 8; for (int i = 0; i < oneByte; i++) { unsigned char mask = 0x80 >> i; if (((data & mask) == mask) && (bitLength *((bit-oneByte )+i)) <= (value % (bitLength * bit)) && (value % (bitLength * bit)) < (bitLength * ((bit - oneByte + 1) + i))) { return true; } } return false; } DWORD soundOut(LPWORD *lpWaveData, HWAVEOUT hWaveOut, unsigned char data, size_t bit, size_t cFrequency) { LPWORD lpSinWave; LPWORD lpWave; LPWORD lpWave1; LPWORD lpWave2; LPWORD lpWave3; LPWORD lpWave4; size_t i, j, end; size_t cWavelength = SAMPLING / cFrequency; size_t dataLength = (size_t)CHANNEL * (BITSPERSAMPLE / 8) * cWavelength * bit; size_t dWavelength; size_t dFrequency; WORD amplitude = MAXAMP / DIV; lpWave = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave1 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave2 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave3 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave4 = (LPWORD)calloc(sizeof(WORD), dataLength); end = dataLength/(BITSPERSAMPLE / 8); for (i = 0; i < end; i++) { lpWave[i] = 0; lpWave1[i] = 0; lpWave2[i] = 0; lpWave3[i] = 0; lpWave4[i] = 0; } /* チャンネル1 ********************************/ lpSinWave = (LPWORD)calloc(sizeof(WORD), cWavelength); createWave(lpSinWave, cFrequency, SAMPLING, MAXAMP); for (i = 0, j = 0; i < end; i += CHANNEL) { lpWave[i] = lpSinWave[j]; ++j; if (j >= cWavelength) { j = 0; } } free(lpSinWave); /* チャンネル2 ********************************/ // クロック dFrequency = 3200; dWavelength = SAMPLING / dFrequency; lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength); createWave(lpSinWave, dFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < end; i += CHANNEL) { lpWave1[i] = lpSinWave[j]; ++j; if (j >= dWavelength) { j = 0; } } for (i = 1, j = 0; i < end; i += CHANNEL, ++j) { if (j < cWavelength/2) { lpWave1[i] = 0; } if (j >= cWavelength) { j = 0; } } free(lpSinWave); // 制御データ dFrequency = 8000; dWavelength = SAMPLING / dFrequency; lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength); createWave(lpSinWave, dFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < end; i += CHANNEL) { lpWave2[i] = lpSinWave[j]; ++j; if (j >= dWavelength) { j = 0; } } for (i = 1, j = 0; i < end; i += CHANNEL, ++j) { if (j < cWavelength/1.2) { lpWave2[i] = 0; } if (j >= cWavelength) { j = 0; } } free(lpSinWave); // シリアルデータ2 dFrequency = 11300; dWavelength = SAMPLING / dFrequency; lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength); createWave(lpSinWave, dFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < end; i += CHANNEL, ++j) { lpWave3[i] = lpSinWave[j]; if (j >= dWavelength) { j = 0; } } for (i = 1; i < end; i += CHANNEL) { if (isON(data, bit, cWavelength * CHANNEL, i)) { lpWave3[i] = 0; } } free(lpSinWave); // リセット dFrequency = 17000; dWavelength = SAMPLING / dFrequency; lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength); createWave(lpSinWave, dFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < cWavelength; i += CHANNEL, ++j) { lpWave4[i] = lpSinWave[j]; if (j >= dWavelength) { j = 0; } } free(lpSinWave); // チャンネル2に合成 for (i = 1; i < end; i += CHANNEL) { lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i]; } *lpWaveData = lpWave; return (DWORD)dataLength; } int main() { LPWORD lpWave[BUFFERING]; WAVEHDR whdr[BUFFERING]; WAVEFORMATEX wfe; HWAVEOUT hWaveOut; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = CHANNEL; wfe.wBitsPerSample = BITSPERSAMPLE; wfe.nBlockAlign = CHANNEL * BITSPERSAMPLE / 8; wfe.nSamplesPerSec = SAMPLING; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); for (int i = 0; i < BUFFERING; i++) { whdr[i].dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr[i].dwLoops = 1; lpWave[i] = NULL; } std::string str; do { std::cout << "2桁毎の16進コードを入力しEnterを押して下さい。(00 ~ FF)" << std::endl; std::cout << "続けて入力する場合は間を空けないでください。" << std::endl; std::cout << "Ctrl+Zを入力しEnterで終了します。" << std::endl; std::cin >> str; // Ctrl+Zで終了 if (std::cin.eof()) { break; } char strData[3]; strData[2] = 0x00; size_t bit = 9; size_t frequency = 43; int freeBuffer = 0; for (int i = 0, j = 0, k = 0; i < str.size(); i += 2, j++, k++) { if (j >= BUFFERING) { j = 0; } freeBuffer = j + 1; if (freeBuffer >= BUFFERING) { freeBuffer = 0; } if (lpWave[freeBuffer] != NULL) { std::cout << "free=" << std::dec << freeBuffer << std::endl; free(lpWave[freeBuffer]); lpWave[freeBuffer] = NULL; } strData[0] = str[i]; strData[1] = str[(size_t)i + 1]; // 入力された文字列をデータに変換 unsigned char data = (unsigned char)strtol(strData, NULL, 16); // サウンド出力 whdr[j].dwBufferLength = soundOut(&lpWave[j], hWaveOut, data, bit, frequency); whdr[j].lpData = (LPSTR)lpWave[j]; waveOutPrepareHeader(hWaveOut, &whdr[j], sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr[j], sizeof(WAVEHDR)); std::cout << "no=" << std::dec << j << ", data=" << std::hex << (int)data << "H" << std::endl; if (k > BUFFERING-3) { Sleep((1000 * (DWORD)bit) / (DWORD)frequency); } } int num = (int)str.size() / 2; if (num == 0) { num = 1; } else if (num > BUFFERING) { num = BUFFERING; } Sleep((1000 * (DWORD)bit * (num +1)) / (DWORD)frequency); for (int i = 0; i < num; i++) { if (lpWave[i] != NULL) { std::cout << "free=" << std::dec << i << std::endl; free(lpWave[i]); lpWave[i] = NULL; } } } while (true); waveOutClose(hWaveOut); }