dawid pisze:Chodzi mi o to że amplituda w plikach wave może mieć wartość do 1 volta
 )
 )
 ), zwany float, czy też single. Pozwala on na zapis wartości z dynamiką ok 760dB, co znacznie wykracza poza możliwości jakiegokolwiek sprzętu pomiarowego, czy grającego (typowy cholernie trudny do przeskoczenia próg to 140dB)
 ), zwany float, czy też single. Pozwala on na zapis wartości z dynamiką ok 760dB, co znacznie wykracza poza możliwości jakiegokolwiek sprzętu pomiarowego, czy grającego (typowy cholernie trudny do przeskoczenia próg to 140dB)
dawid pisze:A co do normalizacji tych plikow to mi to troche nie wychodzi, bo jak podziele przez najwieksza mozliwa wartosc w pliku to zostaje bardzo mala wartosc. Jak ktos wie cos wiecec o normalizacji plikow wave to będę bardzo wdzieczny jak sie podzieli zemną tą wiedzą
 ), to wystarczy pomnożyć wszystkie próbki przez 32767, a potem podzielić przez maksymalną wartość. Koniecznie w tej kolejności, operację wykonujemy na jakimś 32-bitowym typie danych (zazwyczaj int, ale trzeba sprawdzić)
 ), to wystarczy pomnożyć wszystkie próbki przez 32767, a potem podzielić przez maksymalną wartość. Koniecznie w tej kolejności, operację wykonujemy na jakimś 32-bitowym typie danych (zazwyczaj int, ale trzeba sprawdzić)
Kod: Zaznacz cały
int probki[N]; /* tablica N próbek, jest int, ale to nie ważne ;) */
int max; /* maksymalna wartość znaleziona w próbkach */
float t; /* a przez to będziemy mnożyć */
int i; /* a to tylko taki indeks */
max = 0;
/* szukamy maksymalnej wartości */
for(i = 0; i<N; i++) {
  if (abs(probki[i]) > max) /* ma być wartość bezwzględna, bo ważne są oba limity, górny i dolny */
    max = abs(probki[i]);
}
/* teraz w max mamy największą wartość, albo 0, jeżeli wszystkie próbki były zerami */
if (max > 0) { /* jak max będzie zero, to nie ma co liczyć bo się wykrzaczy */
  t = 32767.0 / ((float) max); /* przez to będziemy mnożyć. zamiast 32767.0 możesz wstawić inną wartość, wtedy do niej będziesz normalizował */
/* i wszystkie próbki po kolei, operacje wykonujemy jako zmiennoprzecinkową (float), a wynik całkowity (int) */
  for(i = 0; i<N; i++)
    probki[i] = (int) (t * (float) probki[i]); /* a mnożenie jest dla tego, że jest szybsze od dzielenia */
}
 
Kod: Zaznacz cały
#include <math.h>
#define CZAS 1.0 /* czas w sekundach, czyli długość sampla */
#define FS 44100 /* częstotliwość próbkowania w Hz */
#define N ((int) (CZAS * FS)) /* ilość próbek */
#define FG 1000.0 /* częstotliwość Twojego "generatora" w Hz */
#define PI 3.141593 /* stosunek obwodu okręgu do jego średnicy :P */
#define PI2 (PI+PI) /* mówi samo za siebie */
#define SKALA 32767.0 /* maksymalna wartość (bezwzględna) jaka się znajdzie w tablicy */
/* Dane w tablicy będą miały zakres od -SKALA do +SKALA */
/* minimalna wartość (-32768) nigdy nie wystąpi, po takie przeskalowanie albo spowoduje asymetrię, albo doda składową stałą */
/* dla n bitów SKALA = 2 ^ (n - 1) - 1 */
#define ZERO 32768 /* poziom przesynięcia zera w pliku .wav */
/* dla n bitów ZERO = 2 ^ (n - 1) */
unsigned short sample[N]; /* tablica próbek, wartało by dynamiczną alokację zastosować */
/* chyba ten typ, na amidze na pewno to jest UWORD ma być 16 bit bez znaku*/
int main(void) {
int index; /* indeks w tablicy próbek */
float domega; /* przyrost fazy */
float omega = 0.0; /* aktualna wartość kąta */
/* no i to by było na tyle deklaracji */
/* teraz trzeba by przeliczyć, o ile będzie się zwiększał kąt (faza) dla każdej próbki w radianach ofkozz */
  domega = PI2 * FG / ((float) FS);
  for(index = 0; index<N; index++) {
/* liczymy sinusa, wynik mnożymy przez skalę i z zakresu -1.0 do +1.0 robi się -SKALA do +SKALA */
/* Potem dodajemy ZERO, czyli przesuwany sygnał tak, że wszystkie wartości są dodatnie) */
    sample[index] = (unsigned short) (sin(omega)*SKALA) + ZERO;
/* po każdej próbce zwiększamy wartość kąta */
    omega += domega;
/* poniższa operacja to korekcja kąta bardzo ważna dla dłuższych próbek, bo funkcje trygonometryczne tracą dokładność wraz ze wzrostem wartości argumentu, więc trzymamy go zawsze w zakresie 0.0-2*PI */
/* taka metoda i tak wprowadza błąd narastający z czasem. Właściwe było by zastosowanie np. akumulatora fazy ale jest to już trochę bardziej skomplikowane jeżeli chce się uzyskać dużą dokładność i dowolność wyboru częstotliwości */
/* to co jest tutaj w zupełności do Twoich zastosowań wystarczy */
    while(omega > PI2) {
      omega -= PI2;
    }
  }
 /* No i koniec :) w tablicy sample[] mamy wartości gotowe do zapisu do pliku */
  return 0;
}
 
Wróć do „Komputery, oprogramowanie i internet”
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika. i 12 gości