-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathmain.cpp
More file actions
151 lines (132 loc) · 4.88 KB
/
main.cpp
File metadata and controls
151 lines (132 loc) · 4.88 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#define WAV_EXPORT
// Synth public API (player mode — COMPILE_VSTI not defined)
#include "Synth.h"
// Song data exported from the 64klang3 plugin (File → Export → Song / Patch)
// Place 64k2Patch.h and 64k2Song.h in this directory (or set PLAYER_SONG_DIR in CMake).
#define INCLUDE_NODES
#include "64k2Patch.h"
#include "64k2Song.h"
#define SAMPLE_RATE 44100
#define SAMPLE_TYPE float
// Output buffer: song length + 60 s safety tail
static SAMPLE_TYPE lpSoundBuffer[MAX_SAMPLES * 2 + SAMPLE_RATE * 60 * 2];
static HWAVEOUT hWaveOut;
static WAVEFORMATEX WaveFMT =
{
WAVE_FORMAT_IEEE_FLOAT,
2, // channels
SAMPLE_RATE, // samples per second
SAMPLE_RATE * sizeof(SAMPLE_TYPE) * 2, // bytes per second
sizeof(SAMPLE_TYPE) * 2, // block align
sizeof(SAMPLE_TYPE) * 8, // bits per sample
0 // no extension
};
static WAVEHDR WaveHDR =
{
(LPSTR)lpSoundBuffer,
MAX_SAMPLES * sizeof(SAMPLE_TYPE) * 2,
0, 0, 0, 0, 0, 0
};
static MMTIME MMTime = { TIME_SAMPLES, 0 };
#ifdef WAV_EXPORT
char ExportWaveHeader[44] =
{
'R', 'I', 'F', 'F',
0, 0, 0, 0, // filled below
'W', 'A', 'V', 'E',
'f', 'm', 't', ' ',
16, 0, 0, 0,
3, 0,
2, 0,
0x44, 0xac, 0, 0,
0x20, 0x62, 0x05, 0,
8, 0,
32, 0,
'd', 'a', 't', 'a',
0, 0, 0, 0 // filled below
};
#endif
char infotext[] =
"64klang3 Synthesizer and Player by Gopher/Alcatraz (2026)\n"
"Precalc is 5s. Wait for termination to get a exemusic.wav file written.\n\n"
"Title : ...\n"
"Author : ...\n"
"Length : 13:37\n\n"
" |-------------------------------------------------------------------|\n"
"PlayPos: ";
// Required when linking without the CRT (/NODEFAULTLIB) to suppress the
// "floating-point support not loaded" linker warning.
extern "C" { int _fltused = 1; }
// Debug or 64-bit Release: link CRT normally, use standard main().
// 32-bit Release: no-CRT build (/NODEFAULTLIB /ENTRY:mainCRTStartup), use raw entry point.
#if defined(_DEBUG) || defined(_M_X64)
int main()
#else
void mainCRTStartup()
#endif
{
// write info text to console
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), infotext, sizeof(infotext), NULL, NULL);
// Initialise the synth with the exported patch and song data
_64klang_Init(SynthStream, SynthNodes,
SynthMonoConstantOffset, SynthStereoConstantOffset, SynthMaxOffset);
int SongLength = *(((int*)SynthStream) + 1);
// Start rendering on a background thread; give it a 5 s head-start
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)_64klang_Render, lpSoundBuffer, 0, 0);
Sleep(5000);
// Open waveOut device and begin playback
waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFMT, NULL, 0, CALLBACK_NULL);
waveOutPrepareHeader(hWaveOut, &WaveHDR, sizeof(WaveHDR));
waveOutWrite(hWaveOut, &WaveHDR, sizeof(WaveHDR));
DWORD lastUpdate = 0;
// Wait until playback completes or user presses Escape
do
{
waveOutGetPosition(hWaveOut, &MMTime, sizeof(MMTIME));
// update song progress bar
if ((MMTime.u.sample - lastUpdate) >= SongLength / 70)
{
lastUpdate = MMTime.u.sample;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "#", 1, NULL, NULL);
}
Sleep(128);
} while (MMTime.u.sample < SongLength && !GetAsyncKeyState(VK_ESCAPE));
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, NULL, NULL);
// write a wav file in the end
#ifdef WAV_EXPORT
#ifdef WAIT_FOR_IT
do
{
Sleep(128);
} while (!_64klang_RenderDone());
#endif
HANDLE hFile = CreateFileA("exemusic.wav", // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
// init wave header
*((DWORD*)(&ExportWaveHeader[4])) = SongLength*2*sizeof(SAMPLE_TYPE)+36; // size of the rest of the file in bytes
*((DWORD*)(&ExportWaveHeader[40])) = SongLength*2*sizeof(SAMPLE_TYPE); // size of raw sample data to come
// write wave header
WriteFile( hFile, // open file handle
ExportWaveHeader, // start of data to write
44, // number of bytes to write
&lastUpdate, // number of bytes that were written
NULL); // no overlapped structure
WriteFile( hFile, // open file handle
lpSoundBuffer, // start of data to write
SongLength*2*sizeof(SAMPLE_TYPE), // number of bytes to write
&lastUpdate, // number of bytes that were written
NULL); // no overlapped structure
CloseHandle(hFile);
#endif
ExitProcess(0);
}