coin.asm
comment *
ml /c /coff /Fl /Sa coin.asm
link /subsystem:console coin
*
 
includelib kernel32
includelib winmm
 
.386
.model flat, c
option casemap: none
 
include kernel32.inc
include winmm.inc
 
SAMPLE_RATE	equ	48000
DATA_LEN	equ	SAMPLE_RATE * 11 / 10
 
.data
wave	db	'RIFF'
	dd	36 + DATA_LEN
	db	'WAVE'
	db	'fmt '
	dd	16
	dw	1
	dw	1
	dd	SAMPLE_RATE
	dd	SAMPLE_RATE
	dw	1
	dw	8
	db	'data'
	dd	DATA_LEN
data	db	DATA_LEN dup (80h)
 
.data?
pData	dd	?
 
.code
 
note proc c uses edi, freq:dword, len:dword
	local t:dword, lv:dword
 
	cld
	mov	edi, pData
	mov	t, 0
	mov	lv, SAMPLE_RATE * 16
	mov	ecx, len
L1:
	push	ecx
 
	; al = lv / SAMPLE_RATE
	mov	eax, lv
	xor	edx, edx
	mov	ecx, SAMPLE_RATE
	div	ecx
	sub	lv, 16
 
	; al = 80h + (t < SAMPLE_RATE / 2) ? al : -al
	cmp	t, SAMPLE_RATE / 2
	jb	@f
	neg	al
@@:
	add	al, 80h
	stosb
 
	; t = (t + freq) % SAMPLE_RATE
	mov	eax, t
	add	eax, freq
	xor	edx, edx
	mov	ecx, SAMPLE_RATE
	div	ecx
	mov	t, edx
 
	pop	ecx
	loop	L1
 
	mov	pData, edi
	ret
note endp
 
start:
	mov	pData, offset data
	invoke	note, 988, SAMPLE_RATE / 10
	invoke	note, 1319, SAMPLE_RATE
	invoke	sndPlaySound, addr wave, 4
	invoke	ExitProcess, 0
 
end start
 

C++プロトタイプ

coin.cpp
#include <Windows.h>
#pragma comment(lib, "winmm")
 
#define SAMPLE_RATE 48000
#define DATA_LEN (SAMPLE_RATE*11/10)
 
struct WAVE {
	DWORD RIFF_ckid;
	DWORD RIFF_cksize;
	DWORD fccType;
	DWORD fmt_ckid;
	DWORD fmt_cksize;
	WORD  wFormatTag;
	WORD  nChannels;
	DWORD nSamplesPerSec;
	DWORD nAvgBytesPerSec;
	WORD  nBlockAlign;
	WORD  wBitsPerSample;
	DWORD data_ckid;
	DWORD data_cksize;
	BYTE  data[DATA_LEN];
};
 
BYTE* pData;
 
void tone(DWORD freq, DWORD len) {
	DWORD t = 0;
	DWORD lv = SAMPLE_RATE * 16;
	for (DWORD i = 0; i < len; i++) {
		BYTE h = BYTE(lv / SAMPLE_RATE);
		lv -= 16;
		*(pData++) = 0x80 + ((t < SAMPLE_RATE/2) ? h : -h);
		t = (t + freq) % SAMPLE_RATE;
	}
}
 
int main()
{
	static WAVE wave = {
		0x46464952, 36 + DATA_LEN, 0x45564157,
		0x20746D66, 16, 1, 1, SAMPLE_RATE, SAMPLE_RATE, 1, 8,
		0x61746164, DATA_LEN
	};
	pData = wave.data;
	tone(988, SAMPLE_RATE/10);
	tone(1319, SAMPLE_RATE);
	sndPlaySoundA((LPCSTR)&wave, SND_MEMORY | SND_SYNC);
}
 
最終更新:2021年11月09日 10:15