Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Allegro 4] Odtworzenie dźwięku o danej częstotliwości

Ostatnio zmodyfikowano 2017-04-06 13:24
Autor Wiadomość
rav_jarosz2
Temat założony przez niniejszego użytkownika
[Allegro 4] Odtworzenie dźwięku o danej częstotliwości
» 2017-04-01 15:34:26
Dzień dobry! Próbuję zrobić prosty kreator muzyki. Nigdy wcześniej nie próbowałem bawić się dźwiękiem. Mam problem z tym, żeby wytworzyć dźwięk "w locie". Nie mam pojęcia dlaczego poniższy kod nie działa. Mógłbym wczytać każdą nutę jako .wav ale nie chcę wczytywać sampli każdego dźwięku, bo to zbyt niewygodne. Pomożecie? :)
C/C++
#include <allegro.h>

int main()
{
    allegro_init();
    install_keyboard();
   
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 );
   
    install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, "" );
    set_volume( 255, 255 );
   
    BITMAP * buffer = create_bitmap( 800, 600 );
    clear_to_color( buffer, 0x333333 );
   
    play_audio_stream( 1024, 8, FALSE, 440, 255, 128 );
   
    while( !key[ KEY_ESC ] )
    {
        blit( buffer, screen, 0, 0, 0, 0, 800, 600 );
    }
   
    destroy_bitmap( buffer );
    return 0;
}
END_OF_MAIN();
P-159675
j23
» 2017-04-01 19:49:45
Nie znam Allegro, ale z pobieżnego przeglądu dokumentacji wychodzi, że powinieneś  użyć funkcji get_audio_stream_buffer, żeby uzyskać dostęp do bufora audio, który powinieneś wypełnić próbkami, po czym użyć free_audio_stream_buffer, co by strumień wiedział, że bufor jest gotowy.
P-159682
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2017-04-01 21:20:53
Ehh, nic nie rozumiem z tej dokumentacji. Póki co ominąłem to tak, że utworzyłem sobie w Audacity sampla o częstotliwości 1Khz i trwającym pół sekundy. Potem go wczytałem

C/C++
SAMPLE * dzwiek = load_sample( "1khz.wav" );

A później odtwarzam go 2 razy na sekundę

C/C++
stop_sample( dzwiek );
play_sample( dzwiek, 255, 128, 440, 1 );

Modyfikuję czwarty parametr funkcji żeby zagrać inną częstotliwość (bo bazowa jest 1Khz i mój sampel ma 1Khz, więc jak dam 440 w to miejsce to mój sampel będzie odtworzony z takim zwolnieniem).
Niestety sampel trwa też wtedy odpowiednio dłużej
(dla 440Hz ponad 2 razy dłużej) dlatego przed odtworzeniem jest zatrzymanie poprzedniego.

Ale i tak czekam na lepsze i optymalniejsze ogarnięcie tematu, jeśli ktoś potrafi i chce :)
P-159684
j23
» 2017-04-02 11:33:20
Jeśli chcesz generować dźwięk w locie, to prawdopodobnie musisz użyć funkcji, o których pisałem wcześniej. Co do generowania dźwięku, możesz użyć funkcji sin i generować wartości kolejnych próbek według wzoru: smp[ i ] = sin(2*PI*f*i/sr), gdzie f to częstotliwość w Hz, i to indeks próbki, sr to częstotliwość próbkowania w Hz.

Spróbuj tak:
C/C++
unsigned buff_size = 1024;
unsigned sample_rate = 44100;
unsigned bits = 16;
unsigned channels = 1;
double freq = 1000; // częstotliwość dźwięku

AUDIOSTREAM * stream = play_audio_stream( buff_size, bits, channels, sample_rate, 255, 128 );
if( stream )
{
    int i = 0;
   
    while( i < 2 * sample_rate ) // przykładowe 2 sekundy
    {
        int16_t * buf =( int16_t * ) get_audio_stream_buffer( stream );
        if( buf != NULL )
        {
            for( int j = 0; j < buff_size; ++j, ++i )
                 buf[ j ] = int16_t( 32767.* sin( 2.* M_PI * freq * double( i ) / sample_rate ) );
           
            free_audio_stream_buffer( stream );
        }
       
        std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
    }
}

...
Nie znam Allegro, pisane z palca, więc może nie działać...
P-159689
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2017-04-02 14:14:25
M_PI nie miałem zdefiniowane więc dałem:
C/C++
#define M_PI 3.14159

I zmieniłem tą funkcję
C/C++
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
na
C/C++
rest( 1 );

Ale wyrzuciło błąd w tej kluczowej linii:

conversion from `double' to non-scalar type `fix' requested

Nie mam pojęcia jak to naprawić...

PS: Mój programik ten który wytwarza dźwięk modyfikując sampla 1Khz
już działa sam w sobie i gra
http://chomiczek.uploadfile.pl​/pobierz/1058819---gy5b.html

Tylko muszę dodać częstotliwość dla każdej nuty i każdego półtonu (bo teraz odtwarzam 100Hz*wysokość nuty) i będzie git :D
(SPACJA- odtwarzanie/stop, LPM-wstawienie nutki,
 PPM-usunięcie nutki, F1-zapisanie projektu)

Ale zmieniłbym chętnie metodę odtwarzania, bo ta jest taka jakaś...
P-159695
j23
» 2017-04-02 19:43:11
M_PI nie miałem zdefiniowane
Makro jest zdefiniowane w math.h, choć może być zablokowane.

Ale wyrzuciło błąd w tej kluczowej linii:
Być może kompilator nie wie, co to jest int16_t. Dodaj nagłówek <stdint.h>.
P-159707
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2017-04-06 13:24:45
Nooo i cudownie. Działa.

Dzięki wielkie za pomoc :)
P-159879
« 1 »
  Strona 1 z 1