119 lines
3.6 KiB
C
119 lines
3.6 KiB
C
// ============================================================================
|
|
// audio_demo.c - XAudio2 音频系统演示
|
|
// 生成 440Hz 正弦波并播放 2 秒,无需外部 WAV 文件
|
|
// ============================================================================
|
|
|
|
#include "../Engine/Audio/audio.h"
|
|
#include "../Engine/Core/logger.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <windows.h>
|
|
|
|
#pragma comment(lib, "winmm.lib")
|
|
|
|
// 生成标准 PCM WAV 数据 (44.1kHz, 16bit, 单声道)
|
|
static uint8_t* generate_sine_wave_wav(float frequency, float duration_sec, uint32_t* out_size) {
|
|
const uint32_t sample_rate = 44100;
|
|
const uint16_t channels = 1;
|
|
const uint16_t bits_per_sample = 16;
|
|
const uint16_t block_align = channels * bits_per_sample / 8;
|
|
const uint32_t byte_rate = sample_rate * block_align;
|
|
const uint32_t num_samples = (uint32_t)(sample_rate * duration_sec);
|
|
const uint32_t data_size = num_samples * block_align;
|
|
const uint32_t file_size = 44 + data_size;
|
|
|
|
uint8_t* wav = (uint8_t*)malloc(file_size);
|
|
if (!wav) return NULL;
|
|
|
|
// RIFF 头
|
|
memcpy(wav + 0, "RIFF", 4);
|
|
memcpy(wav + 4, &file_size, 4);
|
|
memcpy(wav + 8, "WAVE", 4);
|
|
|
|
// fmt chunk
|
|
memcpy(wav + 12, "fmt ", 4);
|
|
uint32_t fmt_size = 16;
|
|
memcpy(wav + 16, &fmt_size, 4);
|
|
uint16_t audio_format = 1; // PCM
|
|
memcpy(wav + 20, &audio_format, 2);
|
|
memcpy(wav + 22, &channels, 2);
|
|
memcpy(wav + 24, &sample_rate, 4);
|
|
memcpy(wav + 28, &byte_rate, 4);
|
|
memcpy(wav + 32, &block_align, 2);
|
|
memcpy(wav + 34, &bits_per_sample, 2);
|
|
|
|
// data chunk
|
|
memcpy(wav + 36, "data", 4);
|
|
memcpy(wav + 40, &data_size, 4);
|
|
|
|
// 生成正弦波样本
|
|
int16_t* samples = (int16_t*)(wav + 44);
|
|
float amplitude = 0.3f; // 避免削波
|
|
for (uint32_t i = 0; i < num_samples; i++) {
|
|
float t = (float)i / (float)sample_rate;
|
|
// 简单淡出,避免咔嗒声
|
|
float envelope = 1.0f;
|
|
if (i < 1000) envelope = (float)i / 1000.0f;
|
|
if (i > num_samples - 1000) envelope = (float)(num_samples - i) / 1000.0f;
|
|
float sample = sinf(2.0f * 3.14159265f * frequency * t) * amplitude * envelope;
|
|
samples[i] = (int16_t)(sample * 32767.0f);
|
|
}
|
|
|
|
*out_size = file_size;
|
|
return wav;
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
(void)argc; (void)argv;
|
|
|
|
printf("Lity3D - Audio Demo\n");
|
|
printf("========================\n");
|
|
|
|
AudioSystem* audio = audio_create();
|
|
if (!audio) {
|
|
printf("ERROR: Failed to create XAudio2 audio system\n");
|
|
return 1;
|
|
}
|
|
printf("XAudio2 audio system created.\n");
|
|
|
|
AudioSource* source = audio_source_create(audio);
|
|
if (!source) {
|
|
printf("ERROR: Failed to create audio source\n");
|
|
audio_destroy(audio);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t wav_size = 0;
|
|
uint8_t* wav_data = generate_sine_wave_wav(440.0f, 2.0f, &wav_size);
|
|
if (!wav_data) {
|
|
printf("ERROR: Failed to generate sine wave\n");
|
|
audio_source_destroy(source);
|
|
audio_destroy(audio);
|
|
return 1;
|
|
}
|
|
|
|
if (!audio_load_wav_memory(source, wav_data, wav_size)) {
|
|
printf("ERROR: Failed to load generated WAV into audio source\n");
|
|
free(wav_data);
|
|
audio_source_destroy(source);
|
|
audio_destroy(audio);
|
|
return 1;
|
|
}
|
|
free(wav_data);
|
|
printf("Generated 440Hz sine wave loaded.\n");
|
|
|
|
printf("Playing 2 seconds...\n");
|
|
audio_source_play(source);
|
|
|
|
// 等待播放结束 (约 2 秒 + 缓冲)
|
|
Sleep(2500);
|
|
|
|
audio_source_destroy(source);
|
|
audio_destroy(audio);
|
|
|
|
printf("Audio demo finished successfully.\n");
|
|
return 0;
|
|
}
|