Skocz do zawartości

Ciekawostka do pracy inżynierskiej - dwukrotnie mniejsza amplituda sygnału z magistrali I2S, PMODI2S2


Pomocna odpowiedź

Napisano

Dzień dobry, piszę obecnie pracę dyplomową na temat cyfrowego przetwarzania sygnału audio, i dopiero teraz analizując efekty pracy dostrzegłem pewną ciekawostkę. Sygnał audio wchodzący do układu ma pewną wartość, ale wychodzący z niego ma ją już dwukrotnie mniejszą. Myślę nad tym i myślę i średnio idzie myślenie - obecnie sądzę, że w jakiś sposób program przetwarza te dane w taki sposób, że bit znaku jest tracony przy przesunięciach bitowych i wysyła ramkę 32 bitów z 23 bitami dotyczącymi sygnału audio zamiast 24 bitów. Dobrze myślę, czy głęboko w lesie? Tutaj sygnał audio wchodzący na wejście układu:

image.thumb.png.1f900a9047abce7985561ff42a9cd37a.png

A tutaj wychodzący z układu:

image.thumb.png.c71fcd9babebcd278e593f1263312bdb.png

Kodek to PMOD I2S2, kod do obsługi I2S:

void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s) {
	rxBuffer[0] = changeVolumeLeft(rxBuffer[0]);
	rxBuffer[1] = changeVolumeRight(rxBuffer[1]);

	rxBuffer[0] = Calc_IIR_LT_Left(rxBuffer[0]);
	rxBuffer[1] = Calc_IIR_LT_Right(rxBuffer[1]);

	rxBuffer[0] = Calc_IIR_LMT_Left(rxBuffer[0]);
	rxBuffer[1] = Calc_IIR_LMT_Right(rxBuffer[1]);

	rxBuffer[0] = Calc_IIR_MT_Left(rxBuffer[0]);
	rxBuffer[1] = Calc_IIR_MT_Right(rxBuffer[1]);

	rxBuffer[0] = Calc_IIR_HT_Left(rxBuffer[0]);
	rxBuffer[1] = Calc_IIR_HT_Right(rxBuffer[1]);

	rxBuffer[0] = Calc_IIR_UHT_Left(rxBuffer[0]);
	rxBuffer[1] = Calc_IIR_UHT_Right(rxBuffer[1]);

	txBuffer[0] = rxBuffer[0];
	txBuffer[1] = rxBuffer[1];
}

Odbywają się tutaj same mnożenia, natomiast samo przesunięcie bitowe ustawione jest w pliku .ioc

image.thumb.png.351af64518899e6b7cfd2fde1b58d630.png

A tutaj przykładowy kod funkcji Calc - wszystkie wyglądają tak samo, ale mają różne współczynniki w środku:

int Calc_IIR_UHT_Left(int inSample) {
	float inSampleF = (float) inSample;
	float outSampleF = a0UHT * inSampleF + a1UHT * lin_UHT_z1
			+ a2UHT * lin_UHT_z2 - b1UHT * lout_UHT_z1 - b2UHT * lout_UHT_z2;
	lin_UHT_z2 = lin_UHT_z1;
	lin_UHT_z1 = inSampleF;
	lout_UHT_z2 = lout_UHT_z1;
	lout_UHT_z1 = outSampleF;

	return (int) outSampleF;
}

 

Nie liczyłem z ręki z prostego powodu - zakładając, że współczynniki wzmocnienia każdego z filtrów są równe zero, otrzymuję zawsze a0 = 1, a każdy inny współczynnik = 0. Zatem sygnał jest w każdej funkcji mnożony przez 1, i do niego dodawane są wartości 0. Sygnał nigdy się nie zmienia. W funkcji change volume mogę mieć jedynie inną wartość, ale potencjometr mam ustawiony na środku, co po przeliczeniach daje wartość z zakresu od 0 do 2, przy czym w debugerze widzę, że ma wartość 1, zatem sygnał w sposób niezmieniony zostaje przepisany pod koniec do zmiennej txBuffer

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...