Jak změnit hlasitost wav souboru v C? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak změnit hlasitost wav souboru v C? – C / C++ – Fórum – Programujte.comJak změnit hlasitost wav souboru v C? – C / C++ – Fórum – Programujte.com

 

Thomasso0
Newbie
9. 4. 2011   #1
-
0
-

Ahoj,

snažím se udělat editor WAV souborů v C a zasekl jsem se u změny hlasitosti. Nejsem si jistý příkazem:

buffer *= hlasitost;


Celá funkce vypadá takto:

int upraveniHlasitosti(FILE *fr, FILE *fw, float hlasitost, struct sFileInfo file, unsigned int data_size)

{
int buffer;

do {
if (fread(&buffer, 4, 1, fr) != 1) {
return CHYBA_READ;
}
else {
buffer *= hlasitost;
if (fwrite(&buffer, 2, 1, fw) != 1) {
CHYBA_WRITE;
}
}
} while (buffer != EOF);
return ZADNA_CHYBA;
}


Jdu na to správně nebo to je nesmysl?

Díky za odpovědi...

Nahlásit jako SPAM
IP: 80.188.117.–
Thomasso0
Newbie
9. 4. 2011   #2
-
0
-

Samozřejmě u zapisování má být

&buffer, 4, 1
...

Nahlásit jako SPAM
IP: 80.188.117.–
nervak0
Věrný člen
9. 4. 2011   #3
-
0
-

Násobení samo o sobě je v pohodě (ale chtělo by to zaokrouhlení a hlídání limitů).
Ale ten cyklus je špatně a pochybuju, že jsou ty vzorky 4-bytové.

Nahlásit jako SPAM
IP: 213.211.51.–
Thomasso0
Newbie
9. 4. 2011   #4
-
0
-

Jak to myslíš, zaokrouhlení a limity? A proč je cyklus špatně? Vzorky jsou 2bytové, to jsem podělal, buffer má být short, ale furt s tím nějak čachruju, tak jsou tam nesrovnalosti.

Když třeba zadám koeficient 2 (zvýšení hlasitosti na 200%), tak jsem zkoušel vypsat každý vzorek před a po násobení a neshodovalo se to... Jako originál jsem použil zvuk z QIPu a výsledný soubor jen tak trochu zachrastil...

Nahlásit jako SPAM
IP: 80.188.117.–
nervak0
Věrný člen
9. 4. 2011   #5
-
0
-

Používáš celočíselný typ. Když koeficient a výsledek nebude celočíselný, tak se zlomková část ořízne.
Když máš rozsah -32768 .. 32767, tak se do něj třeba při 20000 * 2 nevejdeš, měl bys to pohlídat.
Podmínku cyklu máš (buffer != EOF), nemyslím si, že wav používá nějakou speciální hodnotu vzorku jako indikátor konce.

Nahlásit jako SPAM
IP: 213.211.51.–
Thomasso0
Newbie
9. 4. 2011   #6
-
0
-

A jakou podmínku bys doporučoval? Buffer by měl teda být float?

Nahlásit jako SPAM
IP: 80.188.117.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2011   #7
-
0
-

To Thomasso : float samozrejme ne.. (treba si to preved z int16 na int64 - to uz se bude hlidat preteceni hodnot pomerne snadno) .. bude neskutecne rusivy az ti to zacne lupat (tj. ze ti to najednou preskoci z maximalni hodnoty nekam do uplne opacny faze)

pak samozrejme budes muset nejprve zjistit, jaka je bitova hloubka toho zvuku.. treba pro 24b ti to uz moc fungovat nebude.. a ani pro 8...
a ted nejvetsi zaludnost.. ujisti se, v jakem byte orderu jsou ty cisla :) little/big endian.. a podle toho se taky musis prispusobit

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Thomasso0
Newbie
9. 4. 2011   #8
-
0
-

Dík za odpověď, ale jdeš na mě moc odborně, já jsem dá se říct začátečník :-). Nevím, co myslíš převodem na int64, to slyším poprvé v životě. Mám funkci na zjištění byterate, samplerate, bitspersample, počet kanálu atd., takže s tím nebude problém.

No a ten little/big endian, to je taky novinka...

Byl bych moc vděčný, kdybys to popsal trošku víc amatérsky :-)... Je to maturitní projekt, můj první větší program.

Tom.

Nahlásit jako SPAM
IP: 80.188.117.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2011   #9
-
0
-

vic amatersky.. abych to vubec jeste umel:

pocitac pouziva na ukladani dat takzvane datove typy. kazdy typ ma svoje vlastnosti - kolik zabere bitu (8, 16, 32, 64 .... ),
jestli je to celociselny typ, ukazatel na jine misto v pameti, jestli ma znamenko, ...

napriklad pokud mas celociselny typ char se znamenkem tak mas rozsah -128 az 127 ( kde nejvyssi bit znamena znamenko.. )
pokud by ses podival na ty cisla pod drobnohledem tak mas vlastne 0-127 a 128=-128 az 255 = -1 (teda pokud se nepletu)

no a problem je v tom, jak vlastne brat cisla, ktere maji vice Bajtu.. mas napriklad 16b cislo a to se da ulozit jako little endian, kdy prvni byte (s nizsi adresou) je ten mene platnej (ma nizsi rad) a druhej byte je ten "dulezitejsi" ...
nebo naopak ( big endian)
proste jak zjistit, kde je napriklad prave znamenko? jakou spravnou hodnotu vlastne zrovna signal ma?

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Thomasso0
Newbie
9. 4. 2011   #10
-
0
-

No, stejně moc nevím, co teda mám konkrétně udělat.. :/ Ale dík za odpověď...

A když už jsme u těch wavů, tak teď jsem napsal tuhle funkci:



/* ========================== */
/* SPOJENI 2 SOUBORU */
/* ========================== */
int spojeniSouboru(FILE *fr1, FILE *fr2, FILE *fw, struct sFileInfo file, struct sChunkInfo chunk)
{
short buffer;

fseek(fr1, 0, SEEK_SET);
do {
if (fread(&buffer, 2, 1, fr1) != 1) {
return CHYBA_READ;
}
if (fwrite(&buffer, 2, 1, fw) != 1) {
return CHYBA_WRITE;
}
} while (!feof(fr1));
fseek(fr2, chunk.poziceData+8, SEEK_SET);
fseek(fw, 0, SEEK_END);
do {
if (fread(&buffer, 2, 1, fr2) != 1) {
return CHYBA_READ;
}

if (fwrite(&buffer, 2, 1, fw) != 1) {
return CHYBA_WRITE;
}
} while (!feof(fr2));
return ZADNA_CHYBA;
}


Ale ve výsledku se do fw zapíše jen fr1, prostě fr1=fw... fr2 tam vůbec není. Neví někdo proč?

Dík.

Nahlásit jako SPAM
IP: 80.188.117.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2011   #11
-
0
-

kdo vi kam skaces tim: fseek(fr2, chunk.poziceData+8, SEEK_SET);

+ nema smysl skakat v souboru kam zapisujes na konec kdyz si nemenil pozici

+ chtelo by to trochu zlepsit styl odsazovani.. takhle clovek nepozna na prvni pohled co k cemu patri

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Thomasso0
Newbie
9. 4. 2011   #12
-
0
-

No skáču tím na první hudební vzorek ve fr2. Zkusil jsem tam teď dát prostě 47 (první vzorek podle Pspadu) a pořád nic. S tím koncem fw máš pravdu, a to odsazování mám vždy o 2 mezery, tady jsem to zkopíroval a nějak se to podělalo...

Nahlásit jako SPAM
IP: 80.188.117.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2011   #13
-
0
-

mozna tabulatory..

Jeste jedna vec.. neni moc rychle nacitat po 2 bajtech .. klidne si udelej buffer na 1024B a kopiruj po blocich

asi nejjednodussi bude vypisovat co zrovna ctes

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 41 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý