Tabii ki, bunu "güzel" geliyor almak sadece önemsiz değil.
Linux'ta nasıl yapılacağını bilmiyorum, ancak bir PCM tamponu oynayabilirseniz, tek yapmanız gereken onu istediğinizle doldurmaktır.
Yani tamponunuzun mono, imzalı 16 bitlik örneklerde, saniyede 44100 örnekte çalmaya ayarlandığını varsayarak, saf (sinüzoidal) bir A4 sesi (440 Hz) oluşturmak kadar basittir.
int16_t buffer[44100];
float frequency = 440.0f;
float sampling_ratio = 44100.0f;
float amplitude = 0.5f;
float t;
for (int i = 0; i < 44100; i++)
{
float theta = ((float)i / sampling_ratio) * PI;
buffer[i] = (int16_t)(sin(theta * frequency) * 32767.0f * amplitude);
}
Ancak, bu ses muhtemelen ilgi alanlarınız için çok sıkıcıdır, bu yüzden daha karmaşık şeyler yapmanız gerekir. Genel olarak, iki tür ses sentezi vardır: Toplama ve Çıkarma . Başka pek çok şey var, ama bu ikisi muhtemelen en basit olanlar. Bugün sadece katkı sentezi hakkında konuşacağım.
Katkı sentezi için, orada yaptığımla aynı şeyi yaparsınız, ancak bir genlikte bir frekans kullanmak yerine, birlikte birkaç dalga eklersiniz. Bu aynı anda bir piyanoda birkaç tuşa basmak gibidir. Kodunuzu aşağıdaki gibi görünecek şekilde değiştirirsiniz:
void add_sine_wave(int16_t* buffer, int buffer_length, float frequency, float sampling_ratio, float amplitude)
{
for (int i = 0; i < buffer_length; i++)
{
float theta = ((float)i / sampling_ratio) * M_PI;
// make sure to correct for overflows and underflows
buffer[i] += (int16_t)(sin(theta * frequency) * 32767.0f * amplitude);
}
}
ve sonra şu şekilde kullanın:
int16_t buffer[44100];
memset(buffer, 0, sizeof(buffer));
// Create an A Major chord
add_sine_wave(buffer, 44100, 440.0f, 44100.0f, 0.5f);
add_sine_wave(buffer, 44100, 554.37f, 44100.0f, 0.5f);
add_sine_wave(buffer, 44100, 659.26f, 44100.0f, 0.5f);
Bu arada, benim frekansları alıyorum burada (kullanıyorum eşit mizaç , ama orada çok ait diğer mevcut ayarlamalar).
Şimdiye kadar sadece sinüs dalgalarını kullandığımı fark ettim, ancak eski sentezleyicilerin her biri kendi ilginç ses özelliklerine sahip kare , üçgen ve testere dalgalarını da destekliyor . Bunları uygulamak oldukça basittir.
Oluşturabileceğiniz ses çeşitliliğini artırmak için yapabileceğiniz diğer şeyler şunlardır:
- Genlik modülasyonu : Tampon boyunca dalganın genliğini değiştirme
- Frekans modülasyonu : Tampon boyunca dalganın frekansını değiştirme
- Yankı : Bir örneği tampondaki şeklini ve konumunu değiştirerek tekrarlama. Kendisi çok karmaşık bir konu.
- Zarflama : Daha fazla ömür sağlamak için bir örneğin genliğini değiştirme
Buradaki nokta, tekniklerin kendilerinin çok zor olmadığıdır, bu yüzden onları sizin için soyutlamak için gerçekten bir kütüphaneye ihtiyacınız yoktur. Onları zor olan ilginç sesler yaratmak için kullanıyor.
Son bir not. Böyle bir sesle deneme yaparken verilerinizi WAV dosyalarına kaydetmek ve daha sonra Audacity gibi bazı yazılımlarda görselleştirmek gerçekten yararlı olabilir. Bu şekilde ne yaptığınızı daha net görebilirsiniz.