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
| typedef struct { uint32_t sample_rate; uint16_t channels; uint16_t bits_per_sample; uint32_t data_size; int16_t *data; } PCMAudio;
PCMAudio* create_pcm_audio(uint32_t sample_rate, uint16_t channels, uint16_t bits_per_sample, uint32_t duration_ms) { PCMAudio *audio = (PCMAudio*)malloc(sizeof(PCMAudio)); if (!audio) return NULL; audio->sample_rate = sample_rate; audio->channels = channels; audio->bits_per_sample = bits_per_sample; uint32_t samples_per_channel = (sample_rate * duration_ms) / 1000; audio->data_size = samples_per_channel * channels * (bits_per_sample / 8); audio->data = (int16_t*)malloc(audio->data_size); if (!audio->data) { free(audio); return NULL; } return audio; }
void generate_sine_wave(PCMAudio *audio, double frequency, double amplitude) { if (!audio || !audio->data) return; uint32_t total_samples = audio->data_size / sizeof(int16_t); double angular_freq = 2.0 * M_PI * frequency / audio->sample_rate; for (uint32_t i = 0; i < total_samples; i += audio->channels) { double sample_time = (double)(i / audio->channels) / audio->sample_rate; int16_t sample_value = (int16_t)(amplitude * 32767 * sin(angular_freq * sample_time)); for (int ch = 0; ch < audio->channels; ch++) { if (i + ch < total_samples) { audio->data[i + ch] = sample_value; } } } }
void write_wav_header(FILE *file, PCMAudio *audio) { fwrite("RIFF", 1, 4, file); uint32_t file_size = 36 + audio->data_size; fwrite(&file_size, 4, 1, file); fwrite("WAVE", 1, 4, file); fwrite("fmt ", 1, 4, file); uint32_t fmt_size = 16; fwrite(&fmt_size, 4, 1, file); uint16_t audio_format = 1; fwrite(&audio_format, 2, 1, file); fwrite(&audio->channels, 2, 1, file); fwrite(&audio->sample_rate, 4, 1, file); uint32_t byte_rate = audio->sample_rate * audio->channels * (audio->bits_per_sample / 8); fwrite(&byte_rate, 4, 1, file); uint16_t block_align = audio->channels * (audio->bits_per_sample / 8); fwrite(&block_align, 2, 1, file); fwrite(&audio->bits_per_sample, 2, 1, file); fwrite("data", 1, 4, file); fwrite(&audio->data_size, 4, 1, file); }
|