Serwis został przeniesiony pod nową domenę: http://cpp0x.pl/
PowrótPowrótHistoria odwiedzonych stron
AutorWiadomość
Data: 2009-09-20 16:25:36

Skorek
Problem z kbhit()

Ostatnio napisałem program który ma na celu odtwarzać dźwięki za pomocą PcSpeakera
ale w pewnym momęcie napodkałem problem. Mianowicie gdy wciśniemy jakis klawisz to gra żądany dźwięk, ale po puszczeniu klawisza dźwięk nie chce przestać grać.

Próbowałem odczytywać czy klawisz jest wciśnięty czy nie za pomocą funkcji kbhit(), ale to działa tylko gdy wciśniemy klawisz, po puszczeniu klawisza program nie robi tego co ma.

Miejsce gdzie jest problem :


if(!kbhit()){
  global_char = 7;
}


Jeżeli zakomentujemy tę część program będzie jakoś działał.


#include <iostream>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <ddtconsole.h>

#define czas 60000
#define disp_text "Dzwienki od Q do P\nZmiana oktawy + i -\n"

using namespace ddt::console;
using namespace std;

unsigned short last_key;
unsigned char global_char;
HANDLE opened_th[2] = {0,0};
short oktawa = 4;
const int notes[7][10] = {
  {0,33,37,41,44,49,55,62,65,73},
  {62,65,73,82,87,98,110,123,131,147},
  {123,131,147,165,175,196,220,247,262,294},
  {247,262,294,330,349,392,440,494,523,587},
  {494,523,587,659,698,784,880,988,1047,1175},
  {998,1047,1175,1319,1397,1568,1760,1976,2093,2349},
  {1976,2093,2349,2637,2794,3136,3520,3951,4186,0},
};
const string note_symb[7][10] = {
  {"Brak","C1","D1","E1","F1","G1","A1","H1","C2","D2"},
  {"H2","C2","D2","E2","F2","G2","A2","H2","C3","D3"},
  {"H2","C3","D3","E3","F3","G3","A3","H3","C4","D4"},
  {"H3","C4","D4","E4","F4","G4","A4","H4","C5","D5"},
  {"H4","C5","D5","E5","F5","G5","A5","H5","C6","D6"},
  {"H5","C6","D6","E6","F6","G6","A6","H6","C7","D7"},
  {"H6","C7","D7","E7","F7","G7","A7","H7","C8","Brak"},
};
const int keys[10] = {113,119,101,114,116,121,117,105,111,112}; //Kody klawiszy. Małe litery.

DWORD WINAPI play_sound(PVOID freq){
  Beep(DWORD(freq),czas);
}

DWORD WINAPI key_radar(PVOID terminate){
  do {
    while(kbhit()){
      global_char = getch();
    }
    if(!kbhit()){ //tu jest problem.
      global_char = 7;
    }
  } while(1==1);
}

string check_key(unsigned char key){
  //static unsigned char last_key;

  if(key == last_key){
    for(int i=0;i<=10;i++){
      if(int(key) == keys[i]){
        return note_symb[oktawa][i];
      }
    }
  }

  if(key == 43){
    oktawa++;
    if(oktawa > 6) {oktawa = 6;}
    return "Oktawa +";
  } else if (key == 45){
    oktawa--;
    if(oktawa < 0) {oktawa = 0;}
    return "Oktawa -";
  }

  if(key != last_key){
    DWORD th_id = 0;
    int freq = 0;
    if(opened_th[1] != NULL){
      TerminateThread(opened_th[1],0);
    }
    last_key = key;
    for(int i=0;i<=10;i++){
      if(int(key) == keys[ i]){
        freq = notes[oktawa][ i];
        opened_th[1] = CreateThread(NULL, 0, play_sound, (PVOID)freq, 0, &th_id);
        return note_symb[oktawa][ i];
      }
    }
    opened_th[1] = CreateThread(NULL, 0, play_sound, (PVOID)freq, 0, &th_id);
    return "Pauza";
  }
  return "";
}

int main(){
  SetConsoleTitleA("Music Player by Skorek. Rev 3.");
  string info[2];
  cout << disp_text;

  opened_th[0] = CreateThread(NULL, 0, key_radar, (PVOID)false, 0, NULL);

  while (int(global_char) != 27){   
    info[0] = check_key(global_char);
    if(info[0] == "") {info[0] = info[1];}
    gotoxy(1,1);
    cout << disp_text << "Oktawa: " << oktawa+1 << "\nDzwienk: " << info[0] << "              ";
    gotoxy(1, 10);
    info[1] = info[0];
    SetConsoleTitleA("Music Player by Skorek. Rev 3.");
  }   
  TerminateThread(opened_th[0], 0);
  return 0;
}



Prosze o pomoc.
Może jest jakas inna funkcja do określania tego czy klawisz jest wciśnięty ??

Data: 2009-09-20 17:10:47

malan


Pamiętaj, że kbhit() to nie getch() i nie czeka, aż klawisz zostanie naciśnięty.

Tak na szybko to mi do głowy przyszło coś takiego (tylko nie wiem, czy to zdziała):

while(kbhit()==false)
{
  if(kbhit())
  global_char=getch();
  else
  global_char=7;
}
Data: 2009-09-20 18:35:34

Skorek


Tak też już próbowałem. I nie działa.

Funkcja "key_radar" to osobny wątek i ma za zadanie przez cały czas działania programu aktualizować zmienną global_char gdzie zapisany jest aktualnie wciśnięty przycisk.

global_char = 7 znacza, że jest wciśnięty klawisz o numerze 7 a tego nie ma w tablicy globalnej "keys" czyli nie powinien być odtworzony żaden dźwięk. Zamiast wartości 7 możemy podstawić cokolwiek innego co nie jest kodem klawiszy: (q,w,e,r,t,y,u,i,o,p).

Data: 2009-09-20 20:04:16

Skorek


Teraz próbowałem przerobić program tak żeby kożystał z biblioteki SDL. Czytałem kurs obsługi klawiatury na tej stronie i napotkałem inne problemy.

Teraz funkcja "key_radar" wygląda tak:

DWORD WINAPI key_radar(PVOID terminate){
  SDL_Event key_event;
  while (SDL_PollEvent(&key_event)) {
    if(key_event.type == SDL_KEYDOWN){
      while(kbhit()){
        global_char = getch();
      }       
    } else {
      global_char = 1;  
    }
  }
}



Ale występują nastęujące błędy:


  [Linker error] undefined reference to `SDL_PollEvent'
  [Linker error] undefined reference to `WinMain@16'
  ld returned 1 exit status



I już nie wiem co mam robić żeby program działał.

Data: 2009-09-20 20:13:49

steckel


Dodaj to do opcji linkera:

SDL.lib SDLmain.lib
Data: 2009-09-20 21:18:19

Skorek


Dodałem do linkera to co napisałeś i mam kolejne błędy.

Circular main <- main.o dependency dropped.
1



Statystyki tematuOstatnio przeczytali
Czytało użytkowników:24Graku, OSA_PL, ison, maciejo, SeaMonster131, malan, Piotr Szawdyński
Przeczytało użytkowników:7
Czytało osób ogólnie:95
Przeczytało osób ogólnie:25



PowrótPowrótHistoria odwiedzonych stron
Panel Logowania
Login:
Hasło:

Użytkowników
Obecnie aktywnych:15
Zalogowanych:0
Zarejestrowanych:4367
Ostatnie 24h:716
Non-cookie 24h:2190
Wszystkich:214766
Ostatnia Aktualizacja
2010-09-01 19:27:34 (6 dni temu)
Ostatnio aktywni
fish133 godz
wiewiorka9 godz
Koni9 godz
BuZuz9 godz
Prezmen12 godz
trupank12 godz
szczgl14 godz
filipesq14 godz
KRIIS55115 godz
kuba181716 godz
extra217 godz
pixelmaster18 godz

Wynajem Sopot - wakacje
Pokój 2 osobowy 130zł/doba;
Lokalizacja: Sopot


O portaluArchiwumHistoriaIndeksRegulaminWyszukiwarkaLinki
Kurs HTML - strona WWW za darmoRestauracja "ATOL" - SopotValid HTML 4.01 TransitionalValid CSS!HTML CSS JavaScript FLASH PHP MySQL