Пианино на системном динамике

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
MaratSoft
Сообщения: 3
Зарегистрирован: 01 ноя 2009, 21:56
Откуда: Kazan Tatarstan Russia

Написал пианино:

Код: Выделить всё

#include<iostream.h>
#include<conio.h>
#include<dos.h>
#include<ctype.h>


void play(char c)
 {
  c=tolower(c);

switch (c) 

      {
          case 'q': {sound(130);delay(150);nosound(); break;};
          case '2': {sound(138.6);delay(150);nosound(); break;};
          case 'w': {sound(146);delay(150);nosound();; break;};
          case '3': {sound(155.6);delay(150);nosound();; break;};
          case 'e': {sound(164.8);delay(150);nosound();; break;};
          case 'r': {sound(174.6);delay(150);nosound();; break;};
          case '5': {sound(185);delay(150);nosound();; break;};
          case 't': {sound(196);delay(150);nosound();; break;};
          case '6': {sound(207.7);delay(150);nosound();; break;};
          case 'y': {sound(220);delay(150);nosound();; break;};
          case '7': {sound(233.1);delay(150);nosound();; break;};
          case 'u': {sound(246.9);delay(150);nosound();; break;};

          case 'z': {sound(261.7);delay(150);nosound(); break;};
          case 's': {sound(277.2);delay(150);nosound(); break;};
          case 'x': {sound(293.7);delay(150);nosound();; break;};
          case 'd': {sound(311.1);delay(150);nosound();; break;};
          case 'c': {sound(329.6);delay(150);nosound();; break;};
          case 'v': {sound(349.2);delay(150);nosound();; break;};
          case 'g': {sound(370);delay(150);nosound();; break;};
          case 'b': {sound(392);delay(150);nosound();; break;};
          case 'h': {sound(415.3);delay(150);nosound();; break;};
          case 'n': {sound(440);delay(150);nosound();; break;};
          case 'j': {sound(466.2);delay(150);nosound();; break;};
          case 'm': {sound(493.9);delay(150);nosound();; break;};
          default: break;
     };
 };


int main()
{
char c;

do
{
 c=getch();
 play(c);
}while(c!=27);

clrscr();
return 0;
}
Хочу сделать так чтобы звучание продолжалось, пока не будет отпущена
клавиша. Помогите с этим вопросом пожалуйста.
Наверное должна существоваь какая то функция, для события отпущения клавиши.
И есть ли аналоги таймера как например в среде Delphi?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Для того, чтобы обеспечить online опрос клавиатуры стандартных средств в досовском Borland C++ нет.

Проблем у тебя несколько:

1. Не учитываются несколько нажатых клавиш.
2. Пока играет звук программа находится в delay, следовательно она не может отвечать за другие нажатые клавиши (как следствие переполнение keyboard буфера и писк от операционной системы).
3. Нельзя сделать так, чтобы звук звучал до тех пор, пока нажата клавиша - он всегда будет звучать порциями по 150 миллисекунд.

Если первую проблему можно побороть не меняя подхода к обработке клавиш, то остальные проблемы не разрешимы в выбранной идеологии процессинга нажатий. Здесь сможет спасти только перехват клавиатурного прерывания. К сожалению подробности сейчас из головы дать не могу, так как давно баловался этими вещами. Нужно гуглить.

Вообще всё это неправильно. Если уж делать, то делать хорошо. Следует переходить на Win и по полной программе использовать возможности более прогрессивной операционной системы.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
MaratSoft
Сообщения: 3
Зарегистрирован: 01 ноя 2009, 21:56
Откуда: Kazan Tatarstan Russia

Надо делать без прерываний. Нашел такую функцию kbhit(); называется.
Переписал код(пока только для буквы Q):

Код: Выделить всё

#include<iostream.h>
#include<conio.h>
#include<dos.h>
#include<ctype.h>


void play(char c)
 {
  c=tolower(c);

switch (c)

      {
	  case 'q': {sound(130);do{sound(130);delay(20);}while(kbhit()!=0);nosound(); break;};
	  case '2': {sound(138.6);delay(150);nosound(); break;};
	  case 'w': {sound(146);delay(150);nosound();; break;};
	  case '3': {sound(155.6);delay(150);nosound();; break;};
	  case 'e': {sound(164.8);delay(150);nosound();; break;};
	  case 'r': {sound(174.6);delay(150);nosound();; break;};
	  case '5': {sound(185);delay(150);nosound();; break;};
	  case 't': {sound(196);delay(150);nosound();; break;};
	  case '6': {sound(207.7);delay(150);nosound();; break;};
	  case 'y': {sound(220);delay(150);nosound();; break;};
	  case '7': {sound(233.1);delay(150);nosound();; break;};
	  case 'u': {sound(246.9);delay(150);nosound();; break;};

	  case 'z': {sound(261.7);delay(150);nosound(); break;};
	  case 's': {sound(277.2);delay(150);nosound(); break;};
	  case 'x': {sound(293.7);delay(150);nosound();; break;};
	  case 'd': {sound(311.1);delay(150);nosound();; break;};
	  case 'c': {sound(329.6);delay(150);nosound();; break;};
	  case 'v': {sound(349.2);delay(150);nosound();; break;};
	  case 'g': {sound(370);delay(150);nosound();; break;};
	  case 'b': {sound(392);delay(150);nosound();; break;};
	  case 'h': {sound(415.3);delay(150);nosound();; break;};
	  case 'n': {sound(440);delay(150);nosound();; break;};
	  case 'j': {sound(466.2);delay(150);nosound();; break;};
	  case 'm': {sound(493.9);delay(150);nosound();; break;};
	  default: break;
     };
 };


int main()
{
char c;

do
{
 c=getch();
 play(c);
}while(c!=27);

clrscr();
return 0;
}

Там если ставишь большой дилэй(), то клавиатурный буфер переполняется и издается характерный звук, ну и соответственно прога зависает. А с дилэй(20); буфер успевает очищаться, но при этом звук самого системного динамика чересчур прерывистый.
Значит надо решать проблему очищения клавиатурного буфера.
Быть может есть какие функции для этого?
З.Ы. Это все пишется в Turbo C++ 3.0, нужно все решать только его средствами.
Аватара пользователя
rrrFer
Сообщения: 237
Зарегистрирован: 07 сен 2008, 14:15
Контактная информация:

Код: Выделить всё

case 'q': //вроде бы { ненужна
    //sound() вроде бы тоже ненужен
    do{
         sound(130);
         delay(20);
    }while(kbhit()!=0);
    nosound(); 
break;
kbhit() это конечно хорошо, но обработать одновременное нажатий нескольких кнопок им неполучится. По делай наверно надо подобрать подходящую задержку(я б поэкспериментировал - но я отключил динамик), вообще с буфером проблемы непонятны - клавишу отпустил - из цикла вышел, а чтобы после выхода очищался буфер можно попробовать как то так: (не проверял) :

Код: Выделить всё

case 'q':
    while(kbhit()){
         sound(130);
         getch();
    }
break;
то есть пока нажата клавиша вызываем соунд, удаляем символ из буфера клавиатуры. Не уверен что работать будет только ))
MaratSoft
Сообщения: 3
Зарегистрирован: 01 ноя 2009, 21:56
Откуда: Kazan Tatarstan Russia

2 rrrFer

Если мы пишем:

Код: Выделить всё

case 'q':
    while(kbhit()){
         sound(130);
         getch();
    }
break;
,то имеем лишнюю задержку, потомй что гетч(); ждет пока ему дадут нажатие.
С буфером как раз таки есть проблема, потому что когда происходит дилэй(), а клавиша зажата, соответственно и буфер принимает на себя и переполняется. А если дилэй() небольшой, то он успевает отработать до того момента как буфер переполнится. Но отсюда и вытекает прерывистый звук динамика из-за кратковременной отработки саунд().
Я уже пробовал настраивать, достаточно тонко, но все равно результат удручающий. Нужна функция для принудительной очистки буфера.
Но тут еще одна загвоздка - кбхит() завязан на буфере, и его значение будет нулевым если мы очистим буфер.
Лажа.
Ответить