recording volume - control - portaudio audacity wxwidgets

0

Spoglądając na Audacity 9e1e903aba.png
i tworzeniem w obecnym czasie programu audio zaciekawiła mnie taka opcja
Zmiana głośności nagrywania d862fa5bd9.png
i taka wizualizacja d77891cdd5.png pokazujaca sile glosnosci nagrywania

Moje pytanie brzmi.
Jak to jest zrobione? Czy taka zmiane glosnosci nagrywania mam mozliwość(w portaudio)? (moze zmiana ustawien w default input ?) Pytam w sumie z ciekawości, ale jak by ktoś mógłby mnie nakierować to może spróbowałbym takie coś zrobić.
Taka wizualizacja chyba nie jest trudna (wystarczy tam zrobić pętle odczytujaca wartosc bezwzgledna próbek?? czy coś myle) ?

Nie wiem czy nie za daleko idę w tym temacie, ale mnie zaciekawił i w sumie fajnie się to robi, ale brak wiedzy mnie zniecheca ;(
Aha i jeszcze jedno do tego potrzebne będą już wątki ?
Bo jeszcze z nimi nie miałem styczności, omijałem je dzięki Timerowi ( w sumie na siłę nie chcę ich robić)

1

Zmiana głośności jest pewnie zrobiona "normalnie", systemowo. Windowsowy mikser od zawsze ma regulację głośności nie tylko odtwarzania, ale i nagrywania.

Co do drugiego pytania, takie coś uzyskasz biorąc maksymalną wartość bezwzględną próbek z jakiegoś przedziału (np. ostatnich 100 milisekund).
Wypadałoby przeliczyć wynik na skalę logarytmiczną (decybelową).

0
Azarien napisał(a):

Zmiana głośności jest pewnie zrobiona "normalnie", systemowo. Windowsowy mikser od zawsze ma regulację głośności nie tylko odtwarzania, ale i nagrywania.

oo o tym nie pomyślałem, a to znaczy, że mogę to znaleźć tu https://msdn.microsoft.com ?

i czy to, że używam Code Blocka nie zamyka mi takiej możliwości ? ( nie mam pojęcia czy to może mieć wpływ, czy Visual Studio ma coś dołączone itp.)

0

Aha i jeszcze jedno do tego potrzebne będą już wątki ?

Nie będą. Całe GUI, nawet te bardzo złożone, spokojnie pociągniesz na timerach.

0

zaczne od najlatwiejszego
sila glosnosci nagrywania
żeby to zwizualizowac mogę poslużyć się kwxLinearRegulator z zakladki KWIC w wxsmith.
muszę pobrać to z http://wxsmithaddons.sourceforge.net/wxsmithkwic.html
i co dalej, coś czytam, ale chyba nie bardzo zrozumiałem, a może bez tego jakoś to zwizualizuje?

1

Użyj wxGauge.

0

przy naciśnięciu start dałem

 switch(smp_format)
            {
                case paUInt8: Gauge1->SetRange(16373); break;            
                case paInt16: Gauge1->SetRange(32767); break;              
                case paInt24: Gauge1->SetRange(49121); break;            
                case paInt32: Gauge1->SetRange(65134); break;             
            };

rozpatruje przyklad tylko z paInt16 więc Gauge1->SetRange(32767);

W timerze taki kod

...
    if( Pa_IsStreamActive( stream ) == 1 )
    {
...
afterSam = data.frameIndex;
if (data.frameIndex < numSamples)
{
        maxx = 0;
        for( i= beforeSam; i < afterSam; i++ )
    {
        val = data.recordedSamples[i];
        if( val < 0 ) val = -val; // ABS
        if( val > maxx )
        {
            maxx = val;  
        }
        Gauge1->SetValue((int)maxx);
    
    }
    beforeSam = afterSam;
}

Śrdenio moj Gauge wskazuje 1f16f4f329.png raczej nie zdazylo mu sie wskazac wiececj mimo iz zaczalem glosno mowic.
dziwnie ze jak nic nie robie, cisza jest to też czasem wskakuje na taki poziom co jakis czas

0

Nie tak prosto. Dla każdego smp_format format próbki jest inny, a u Ciebie jest stały, czyli taki jaki ma recordedSamples. Będziesz musiał napisać cztery wersje liczące wartości szczytowe ;) Dodatkowo próbki w formacie paUInt8 musisz liczyć nieco inaczej.

Pr0 aplikacje audio nie bawią się w takie ustawianie formatu, tylko jadą na najwyższych rozdzielczościach, dzięki czemu nie muszą mieć kilku wersji tych samych algorytmów/funkcji. Ostateczny format ustawiany jest dopiero przy zapisie do pliku.

0

chodzi Ci o te 4 wersje, że

if (smp_format == paUInt8)
{
}
else if (smp_format == paInt16 )
{
}
else if (smp_format == paInt24 )
{
}
else if (smp_format == paInt32 )

Zakres Gauge zmienia się przy starcie, a w kodzie jest coś nie tak ?

0x666 napisał(a):

Dla każdego smp_format format próbki jest inny, a u Ciebie jest stały, czyli taki jaki ma recordedSamples.

format próbki jest inny tzn? co się zmienia ?

0

Zmienia się typ wartości, które zawiera tablica recordedSamples:

paUInt8 -> uint8_t (128 to punkt środkowy, zero).
paInt16 -> int16_t.
paInt24 -> nie ma typu 24-bitowego, trzeba trochę kombinować...
paInt32 -> int32_t.

0

czyli dla int16_t - zakres to -327679 ... 0 ... 327678
int32_t - zakres to −2 147 483 648 ... 0 ... +2 147 483 647
o to chodzi ?

0

Między innymi też o to.

0

hmm, a coś jeszcze jest ;O ?

0

Co Ci dadzą same zakresy wartości jeśli będziesz źle interpretował dane w buforze?

Przykład dla próbek 16-bitowych:

int16_t *smps = (int16_t*)data.recordedSamples;

afterSam = data.frameIndex;
if (data.frameIndex < numSamples)
{
    maxx = 0;
	for( i= beforeSam; i < afterSam; i++ )
	{
		maxx = max(abs( smps[i] ), maxx);
	}
	
	Gauge1->SetValue((int)maxx);
	beforeSam = afterSam;
}

Nad resztą podumaj sam.

0

dałem jak wyżej
fe97e1fced.png

0

jeszcze w maxie rzutowałem na inta (czy lepiej tego nie robić? i zrobic z instrukcja warunkową? (bo max nie działa z takimi zmiennymi)
i byłoby spoko gdyby po 40tysięcach próbek to nie zaczęło samo skakać ;(

edit
afterSam miałem zdefiniowane jako short, poprawiam i sprawdzam

1 użytkowników online, w tym zalogowanych: 0, gości: 1