Страницы

Поиск по вопросам

четверг, 9 апреля 2020 г.

pc speaker c++ beep();

#cpp #linux

                    
Для winapi существует стандартная библиотека windows.h с функцией Beep().

Есть ли аналог в gnu/linux, или необходимо использовать сторонние библиотеки?
    


Ответы

Ответ 1



Если есть conio.h, можно воспользоваться putch('\a'); Про putchar рядом была тема, что не работает, но думаю, putch должен.

Ответ 2



Можно использовать возможности консоли линукс. Для этого нужно залогиниться в текстовый терминал. Далее использовать управляющие последовательности (в формате для printf): \033[10;%d] - установить частоту. \033[11;%d] - установить длительность в миллисекундах. \a - собственно выдать сигнал установленной частоты и длительности. Перед выдачей нового сигнала нужно подождать пока закончится текущий, иначе он будет прерван и сразу зазвучит новый. Может потребоваться загрузить модуль ядра для поддержки pc-speaker pcspkr или snd_pcsp и с помощью alsamixer включить всё, что касается speaker и beep. Код: #include #include void Beep(int Hz, int msec) { fprintf(stderr,"\033[10;%d]\033[11;%d]\a", Hz, msec); usleep(msec*1000); } int main(int argc, char* argv[]) { Beep(494, 250); Beep(523, 250); Beep(587, 500); Beep(523, 250); Beep(494, 250); Beep(440, 500); return 0; } Запускать необходимо из текстовой консоли или перенаправить вывод stderr на неё. Думаю в настоящее время более удобным является другой способ -- использовать одну из портируемых библиотек. Поэтому предлагаю реализацию Beep с помощью SDL в котором использовал идею алгоритма Брезенхема. Справедливости ради скажу, что для высоких частот звук консоли лучше. #include #include #include typedef struct { SDL_AudioSpec spec; int freq; int t; int err; int newfreq; int newt; Uint8 v; } udata_t; static udata_t uData; static void fill_audio(void *udata, Uint8 *stream, int len) { udata_t * const d= udata; while(len--) { if(!d->t) { if(d->newt) d->t = d->newt; d->freq = d->newfreq; d->newt = 0; } if(d->t) { d->t--; d->err += d->freq; if(d->err >= d->spec.freq) { d->err -= d->spec.freq*2; d->v= ~d->v; } } else if(!len) { SDL_PauseAudio(1); } *stream++ = d->v; } } void Beep(int Hz, int msec) { while(uData.newt) { usleep((uData.t*1000+uData.spec.freq-1)/uData.spec.freq*1000); } uData.newfreq= Hz*4; uData.newt= uData.spec.freq*msec/1000; if(!uData.t) SDL_PauseAudio(0); } void wait_audio() { while(uData.newt || uData.t) { usleep((uData.t*1000+uData.spec.freq-1)/uData.spec.freq*1000); } } void init_audio() { SDL_AudioSpec wanted; /* Set the audio format */ wanted.freq = 65535; wanted.format = AUDIO_U8; wanted.channels = 1; /* 1 = mono, 2 = stereo */ wanted.samples = 1024; /* Good low-latency value for callback */ wanted.callback = fill_audio; wanted.userdata = &uData; /* Open the audio device, forcing the desired format */ if ( SDL_OpenAudio(&wanted, &uData.spec) < 0 ) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); exit(1); } uData.err= uData.spec.freq; } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_AUDIO); init_audio(); Beep(494, 250); Beep(523, 250); Beep(587, 500); Beep(523, 250); Beep(494, 250); Beep(440, 500); wait_audio(); return 0; } Компиляция: gcc beepsdl.c `sdl2-config --cflags --libs` либо sdl-config вместо sdl2-config в зависимости от версии. Возможно потребуется поставить libsdl2-dev.

Комментариев нет:

Отправить комментарий