CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Rysowanie wykresu dźwięku

Rysowanie wykresu dźwięku

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Rysowanie wykresu dźwięku

Nowy postprzez kriss » niedziela, 12 grudnia 2010, 21:36

Witajcie!

Mam stworzyć wykres dźwięku (amplituda od czasu) taki jak na tym rysunku:

Obrazek

Tyle, że nie wiem jak się za niego zabrać. Udało mi się wczytać plik do programu poprzez bibliotekę BASS i narysować na komponencie TChart wykres poziomu dźwięku:
Kod: Zaznacz cały
  HSTREAM Uchwyt;
  BASS_Init(-1, 48000, 0, Handle, NULL);
  BASS_Start();
  Uchwyt = BASS_StreamCreateFile(False, "jmj-mf2.wav", 0, 0, 0); 
  BASS_ChannelPlay(Uchwyt, false);
  DWORD OK = BASS_ChannelGetLevel(Uchwyt);
  r=HIWORD(OK);
  l=LOWORD(OK);
  Chart1->Series[0]->Add(l, b, clGreen);
  Chart2->Series[0]->Add(r, b, clGreen);

Wykres rysuje się podczas odtwarzania, lecz niestety nie o taki wykres dźwięku mi chodziło. Z tego co dobrze rozumiem trzeba wykorzystać jakoś BASS_ChannelGetData, tylko pozostaje pytanie - JAK?

Chyba, że jest jakiś inny, łatwiejszy sposób wyrysowania na TChart takiego wykresu?
Avatar użytkownika
kriss
Bladawiec
Bladawiec
 
Posty: 20
Dołączył(a): niedziela, 12 grudnia 2010, 21:28
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Ultimate x64
Kompilator: C++ Builder 6 Enterprise
Gadu Gadu: 0
    Windows 7Firefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez Cyfrowy Baron » niedziela, 12 grudnia 2010, 21:58

Gdy używasz jakiejś niestandardowej biblioteki, to nie oznacza, że inni również ją znają. Powinieneś podać skąd można pobrać tą bibliotekę, oraz udzielić informacji o tym dla jakich kompilatorów jest dostępna, lub wskazać adres pod którym można takie informacje znaleźć. Ponadto nie wszyscy potrafią korzystać z tej biblioteki, więc przydałoby się więcej kodu. Ja osobiście nigdy nie słyszałem o takiej bibliotece i gdybym, miał ją przetestować, to nie wiedziałbym od czego zacząć
Ostatnio nad czymś podobnym pracuje Corvis. Przejrzyj więc jego posty.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez kriss » poniedziałek, 13 grudnia 2010, 00:03

Biblioteka zwie się BASS http://www.un4seen.com/. Bezpośredni link do ostatniej wersji: http://us2.un4seen.com/files/bass24.zip (jest tutaj plik z dokumentacją). Biblioteka jest dostępna dla C/C++, Delphi, VB. W załączniku daję przygotowaną już wersję plików .LIB dla C++ Buildera. Próbowałem rysować wykres poprzez BASS_ChannelGetLevel - ale tu jest poziom dźwięku w wartościach od 0 do 65536 na obydwa kanały.

Wrzucam tutaj kod dzięki któremu rysuję wykres na obydwu komponentach TChart:

Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{

   BASS_Init(-1, 48000, 0, Handle, NULL);
   BASS_Start();
   Uchwyt = BASS_StreamCreateFile(False, "jmj-mf2.wav", 0, 0, 0);

  // odtwarzam wczytany plik
  BASS_ChannelPlay(Uchwyt, false);
  DWORD OK = BASS_ChannelGetLevel(Uchwyt);
  r=HIWORD(OK);
  l=LOWORD(OK);
  float rozmiar = BASS_ChannelGetLength(Uchwyt);
  double time=BASS_ChannelBytes2Seconds(Uchwyt, rozmiar);
  ListBox->Items->Clear();
  ListBox->Items->Add(time); //sprawdzam ile sec trwa .wav
}

Mam też Buttony, które uaktywniają/dezaktywują timer (Interval = 1) rysujący obecnie odtwarzany plik na TChart:
Kod: Zaznacz cały
void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
  r2=20*log10(r/32768); //dB
  l2=20*log10(l/32768); //dB
  Chart1->Series[0]->Add(l2, b, clGreen);
  Chart2->Series[0]->Add(r2, b, clGreen);
}

... i teraz myślę jak zrobić bym mógł rysować wykres amplitudy od czasu. Amplituda chyba jest znormalizowana (wartości <-1;1>).
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
kriss
Bladawiec
Bladawiec
 
Posty: 20
Dołączył(a): niedziela, 12 grudnia 2010, 21:28
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Ultimate x64
Kompilator: C++ Builder 6 Enterprise
Gadu Gadu: 0
    Windows 7Firefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez polymorphism » poniedziałek, 13 grudnia 2010, 12:53

Coś w ten deseń:
KOD cpp:     UKRYJ  
float buffer[2048];

read = BASS_ChannelGetData(Uchwyt, buffer, sizeof(buffer) | BASS_DATA_FLOAT);
if(read != -1)
{
        read /= sizeof(float); /* 'read' to liczba pobranych float'ów  */

        /* tu rysujesz wykres */
}
 
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
kriss
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez kriss » poniedziałek, 13 grudnia 2010, 17:09

Ok, wielkie dzięki, wykres rysuje się jak należy ;)
Avatar użytkownika
kriss
Bladawiec
Bladawiec
 
Posty: 20
Dołączył(a): niedziela, 12 grudnia 2010, 21:28
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Ultimate x64
Kompilator: C++ Builder 6 Enterprise
Gadu Gadu: 0
    Windows 7Firefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez Giewont » środa, 18 maja 2011, 14:21

Witam. Mam podobny problem z wyrysowaniem przebiegu czasowego dźwięku za pomocą biblioteki BASS.
Czy mógłbym prosić o dokładniejsze wyjaśnienie jak użyć w tym celu funkcji BASS_ChannelGetData ?
Rozumiem, że funkcja w przedstawionym wyżej fragmencie kodu zwraca próbkę do zmiennej read, ale jak teraz
wyciągnąć z niej znormalizowaną amplitudę dla lewego i prawego kanału ?

Początkowo próbowałem zrealizować wykres za pomocą wspominanej już w tym temacie funkcji ChannelGetLevel, niestety wykres
wyglądał nieprawidłowo :( Funkcja ta zwraca wartości z zakresu od 0 do 32768, próbowałem przekonwertować je na zakres <-1, +1> za pomocą
poniższego kodu:
Kod: Zaznacz cały
          DWORD r, l;
          float r2, l2;
          OK = BASS_ChannelGetLevel(Uchwyt);
          r=HIWORD(OK);
          l=LOWORD(OK);
          if (r <= 16384)
          {
                r2 = (float)r/16384;
                r2 = (1-r2)*-1;
          }
          else
          {
                r2 = (float)(r-16384);
                r2 = r2/16384;
          }
          if (l <= 16384)
          {
                l2 = (float)l/16384;
                l2 = (1-l2)*-1;
          }
          else
          {
                l2 = (float)(l-16384);
                l2 = l2/16384;
          }

Wykres wyrysowywany był następnie z wartości l2 i r2. Mimo, że mieściły się one w pożądanym zakresie - wygląd wykresu moim zdaniem był nieprawidłowy:
Obrazek
Avatar użytkownika
Giewont
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 23 stycznia 2011, 11:37
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: Borland C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez polymorphism » środa, 18 maja 2011, 14:50

Rozumiem, że funkcja w przedstawionym wyżej fragmencie kodu zwraca próbkę do zmiennej read (...)

Przecież tam masz napisane jak wół, czym jest wartość w zmiennej read!
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez Giewont » środa, 18 maja 2011, 19:34

polymorphism napisał(a):Przecież tam masz napisane jak wół, czym jest wartość w zmiennej read!


sorry, chodziło mi oczywiście o buffer
Avatar użytkownika
Giewont
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 23 stycznia 2011, 11:37
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: Borland C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez polymorphism » środa, 18 maja 2011, 19:45

No to w takim razie odpowiedź brzmi: tak, buffer zawiera serię znormalizowanych próbek.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Rysowanie wykresu dźwięku

Nowy postprzez Giewont » czwartek, 19 maja 2011, 14:38

dzięki, wykres rysuje się poprawnie :)

ostateczne rozwiązanie wygląda tak:
KOD cpp:     UKRYJ  
DWORD read;
float r2, l2;
float buffer[2048];
read = BASS_ChannelGetData(Uchwyt, buffer, sizeof(buffer) | BASS_DATA_FLOAT);
          if(read != -1)
          {
                read /= sizeof(float);
                for (int i=0 ; i<read ; i+=2)
                {
                        l2=buffer[i];                    // lewy
                        r2=buffer[i+1];                // prawy
                }
          }


pozdrawiam !
Avatar użytkownika
Giewont
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 23 stycznia 2011, 11:37
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: Borland C++ Builder 6
Gadu Gadu: 0
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości