Thronplunder
nackt.
- Registriert
- 14 Juli 2013
- Beiträge
- 18.475
Hallo miteinander
Ich schreibe momentan als Abschlussarbeit eine Headerdatei, mit der man relativ einfach Klangsynthese betreiben kann.
Beim "Optimieren" mit Zeigern sprang mir allerdings dieser Fehler entgegen und auch mit Googlen konnte ich ihn so spontan jetzt nicht beheben.
Zuvor hat allerdings Alles einigermaßen Funktioniert. Zur Not könnte ich also noch einfach zurückrudern.
Wer den Code in voller Länge betrachten will, kann dies im nachfolgenden Spoiler tun.
Die Fehlermeldung aus der Konsole dazu lautet:
Dabei vermute ich stark, dass der Fehler in der Funktion create_tone_sine
in Verbindung mit der Funktion merge liegt
Zumindest bekomme ich keinen Fehler wenn ich diese aus dem Code eines Testprogrammes auskommentiere.
Das Testprogramm sieht folgendermaßen aus:
Ich hoffe jemand hat den Mut und die Lust sich da durchzukämpfen. Vielleicht ist es ja aber auch ganz einfach und ich seh den Wald vor lauter Bäumen nicht.
Vielen Dank schonmal im Vorraus
Ich schreibe momentan als Abschlussarbeit eine Headerdatei, mit der man relativ einfach Klangsynthese betreiben kann.
Beim "Optimieren" mit Zeigern sprang mir allerdings dieser Fehler entgegen und auch mit Googlen konnte ich ihn so spontan jetzt nicht beheben.
Zuvor hat allerdings Alles einigermaßen Funktioniert. Zur Not könnte ich also noch einfach zurückrudern.
Wer den Code in voller Länge betrachten will, kann dies im nachfolgenden Spoiler tun.
[src=c]#ifndef SYNTH_H_INCLUDED
#define SYNTH_H_INCLUDED
#endif // SYNTH_H_INCLUDED
#include <sndfile.h>
#include <math.h>
#include <stdlib.h>
#define SAMPLERATE 44100
#define PI 3.14159265358979323846 //PI definiert, da es mit math.h irgendwie nicht geht
//Bibliothek um einfach mithilfe von libsndfile additive Synthese zu betreiben in Stereo
size_t i = 0; //zählvariable
struct tone{//enthält daten zu einem erzezgtem ton und seiner länge um weiterverarbeitet zu werden
float *data;
double size;
int frequenzy;
};
typedef struct tone tone;
struct snd{ //enhält alle informationen zur Audiodatei
float *buffer;//buffer für audiodatei
double samples;//länge des Buffers
SF_INFO file_info;
};
typedef struct snd snd;//abkürzung
snd create_snd();//erstellt ein snd objekt mit ausgefülltem sf_info
tone* create_tone_sine(float length, int freq, float chanvol1, float chanvol2);//liefert ein struct mit den samples eines tons und seiner länge auf zehntel sekunden genau
void merge(snd* sndobj, tone *tone, float start);//schreibe ton in buffer der audiodatei an gewünschter stelle in sekunden auf zehntel sekunden genau, löscht daten aus tone objekt, additionsverfahren ist glaube ich nicht so schlau gelöst.
void export(snd* sndobj, float mastervol);//schreibe datei, löscht buffer in snd objekt. mastervolume, benötigt eventuell pfadanpassung
float round1(float num);//rundet auf eine nachkommastelle eigentlich nicht nötig und nur einmal verwendet.
tone create_tone_saw(float length, int freq, float chanvol1, float chanvol2);//schreibt eine saw welle in ein tone struct. formel stimmt aber nicht ganz, da die welle verdreht ist
void create_linearfade(float in_time, float out_time, tone *tone );// fadet einen Ton linear aus oder ein. Aus geht noch nicht richtig
void create_harmonic_sine (float ratio, tone *tone, float vol);//addiert einen oberton zu einem bestehenden sinusklang, ratio gibt dabei das verhältnis an, vol bestimmt die lautstärke des tones, mit for schleife bessere alternative zu create_tone_saw
float round1(float num){
return (floorf(num * 10) / 10); //runde auf eine dezimalstelle. nuller an die 2 10er hängen für mehr stellen
}
snd create_snd(){
snd sndobj;
sndobj.samples = 0;
sndobj.buffer = NULL;
sndobj.file_info.channels = 2;
sndobj.file_info.samplerate = SAMPLERATE;
sndobj.file_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
return sndobj;
}
tone* create_tone_sine(float length, int freq, float chanvol1, float chanvol2){
float *chan1, *chan2;
tone tonestr;
tone *toneptr = &tonestr;
toneptr->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));//Speicher für beide Kanäle und zusammengefügten Kanal reservieren
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
toneptr->size = round1(length) * SAMPLERATE * 2;//informationen über die größe in tone objekt aktualisieren
if(chan1 == NULL || chan2 == NULL || toneptr->data == NULL){
printf("Fehler");
return;
}
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = sin(2* PI * (i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1;
chan2 = sin(2* PI * (i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
toneptr->data = chan1[i/2];
toneptr->data[i+1] = chan2[i/2];
}
free(chan1);//speicher freigeben
free(chan2);
return toneptr;
}
void merge(snd *sndobj, tone *tone, float start ){
if(sndobj->samples < round1(start) * SAMPLERATE * 2 + tone->size){// gegebenenfalls neuen speicher nehmen, falls der neue ton nicht hinenpasst
sndobj->buffer = realloc(sndobj->buffer, tone->size * sizeof(float) + (SAMPLERATE * start) * sizeof(float) * 2);
sndobj->samples = tone->size + SAMPLERATE * start * 2 ;
}
for(i = SAMPLERATE * start * 2; i < tone->size + start * 2 * SAMPLERATE ; i++){//ton in den buffer eones snd objekts schreiben
sndobj->buffer = (sndobj->buffer + tone->data[((int)(i - SAMPLERATE * start * 2))]);
}
free((tone->data));
}
void export(snd* sndobj, float mastervol){
float val = 0;
for(i = 0; i < sndobj->samples; i++){//"lautestes" sample finden, normalisieren
if(abs(sndobj->buffer) > val){
val = sndobj->buffer;
}
}
for(i = 0; i < sndobj->samples; i++){//normalisieren und maximallautstärke bestimmen
sndobj->buffer = (sndobj->buffer / val) * mastervol;
}
SNDFILE *file = sf_open("datei.wav", SFM_WRITE, &(sndobj->file_info));
if(file == NULL){
printf("Konnte Datei nicht öffnen");
}
sf_writef_float(file, sndobj->buffer, sndobj->samples/2);
free(sndobj->buffer);
}
tone create_tone_saw(float length, int freq, float chanvol1, float chanvol2){
float *chan1, *chan2;
tone *tone;
tone->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
tone->size = round1(length) * SAMPLERATE * 2;
tone->frequenzy = freq;
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1) * 2 -1;
chan2 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2) * 2 -1;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
tone->data = chan1[i/2];
tone->data[i+1] = chan2[i/2];
}
free(chan1);
free(chan2);
return *tone;
}
void create_linearfade(float in_time, float out_time, tone *tone){
if(in_time !=0 || tone->size > in_time * SAMPLERATE * 2){
for(i = 0; i < in_time * 2 * SAMPLERATE; i = i +2){//Fade-in
tone->data = tone->data * (((float)i * 0.5) / ((float)SAMPLERATE * in_time ) );
tone->data[i+1]= tone->data[i +1] * (((float)i * 0.5) / ((float)SAMPLERATE * in_time ) );
}
}
if(out_time !=0 || tone->size > out_time * SAMPLERATE * 2){//funktionert fast. irgendwas stimmt mit der formel nicht oder der schleife
float y = 0;//andere zähvariable
for(i = tone->size - 2 * out_time * SAMPLERATE ; i < tone->size ; i = i + 2){//fade-out
tone->data = tone->data *(float) ((SAMPLERATE * out_time - (y/2)) / SAMPLERATE * out_time);
tone->data[i+1]= tone->data[i+1] *(float) ((SAMPLERATE * out_time - (y/2)) / SAMPLERATE * out_time);
y += 2;
}
}
}
void create_harmonic_sine (float ratio, tone *tone, float vol){
printf("freq: &f", tone->frequenzy);
for(i = 0; i < tone->size ; i += 2){
tone->data += (sin(2* PI * (i/2) / ((float)SAMPLERATE / (float)(tone->frequenzy * ratio))) * vol) ;
//tone->data[i+1] += (sin(2* PI * (i/2) / ((float)SAMPLERATE / (float)(tone->freq * ratio))) * vol);
}
return;
}
[/src]
#define SYNTH_H_INCLUDED
#endif // SYNTH_H_INCLUDED
#include <sndfile.h>
#include <math.h>
#include <stdlib.h>
#define SAMPLERATE 44100
#define PI 3.14159265358979323846 //PI definiert, da es mit math.h irgendwie nicht geht
//Bibliothek um einfach mithilfe von libsndfile additive Synthese zu betreiben in Stereo
size_t i = 0; //zählvariable
struct tone{//enthält daten zu einem erzezgtem ton und seiner länge um weiterverarbeitet zu werden
float *data;
double size;
int frequenzy;
};
typedef struct tone tone;
struct snd{ //enhält alle informationen zur Audiodatei
float *buffer;//buffer für audiodatei
double samples;//länge des Buffers
SF_INFO file_info;
};
typedef struct snd snd;//abkürzung
snd create_snd();//erstellt ein snd objekt mit ausgefülltem sf_info
tone* create_tone_sine(float length, int freq, float chanvol1, float chanvol2);//liefert ein struct mit den samples eines tons und seiner länge auf zehntel sekunden genau
void merge(snd* sndobj, tone *tone, float start);//schreibe ton in buffer der audiodatei an gewünschter stelle in sekunden auf zehntel sekunden genau, löscht daten aus tone objekt, additionsverfahren ist glaube ich nicht so schlau gelöst.
void export(snd* sndobj, float mastervol);//schreibe datei, löscht buffer in snd objekt. mastervolume, benötigt eventuell pfadanpassung
float round1(float num);//rundet auf eine nachkommastelle eigentlich nicht nötig und nur einmal verwendet.
tone create_tone_saw(float length, int freq, float chanvol1, float chanvol2);//schreibt eine saw welle in ein tone struct. formel stimmt aber nicht ganz, da die welle verdreht ist
void create_linearfade(float in_time, float out_time, tone *tone );// fadet einen Ton linear aus oder ein. Aus geht noch nicht richtig
void create_harmonic_sine (float ratio, tone *tone, float vol);//addiert einen oberton zu einem bestehenden sinusklang, ratio gibt dabei das verhältnis an, vol bestimmt die lautstärke des tones, mit for schleife bessere alternative zu create_tone_saw
float round1(float num){
return (floorf(num * 10) / 10); //runde auf eine dezimalstelle. nuller an die 2 10er hängen für mehr stellen
}
snd create_snd(){
snd sndobj;
sndobj.samples = 0;
sndobj.buffer = NULL;
sndobj.file_info.channels = 2;
sndobj.file_info.samplerate = SAMPLERATE;
sndobj.file_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
return sndobj;
}
tone* create_tone_sine(float length, int freq, float chanvol1, float chanvol2){
float *chan1, *chan2;
tone tonestr;
tone *toneptr = &tonestr;
toneptr->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));//Speicher für beide Kanäle und zusammengefügten Kanal reservieren
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
toneptr->size = round1(length) * SAMPLERATE * 2;//informationen über die größe in tone objekt aktualisieren
if(chan1 == NULL || chan2 == NULL || toneptr->data == NULL){
printf("Fehler");
return;
}
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = sin(2* PI * (i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1;
chan2 = sin(2* PI * (i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
toneptr->data = chan1[i/2];
toneptr->data[i+1] = chan2[i/2];
}
free(chan1);//speicher freigeben
free(chan2);
return toneptr;
}
void merge(snd *sndobj, tone *tone, float start ){
if(sndobj->samples < round1(start) * SAMPLERATE * 2 + tone->size){// gegebenenfalls neuen speicher nehmen, falls der neue ton nicht hinenpasst
sndobj->buffer = realloc(sndobj->buffer, tone->size * sizeof(float) + (SAMPLERATE * start) * sizeof(float) * 2);
sndobj->samples = tone->size + SAMPLERATE * start * 2 ;
}
for(i = SAMPLERATE * start * 2; i < tone->size + start * 2 * SAMPLERATE ; i++){//ton in den buffer eones snd objekts schreiben
sndobj->buffer = (sndobj->buffer + tone->data[((int)(i - SAMPLERATE * start * 2))]);
}
free((tone->data));
}
void export(snd* sndobj, float mastervol){
float val = 0;
for(i = 0; i < sndobj->samples; i++){//"lautestes" sample finden, normalisieren
if(abs(sndobj->buffer) > val){
val = sndobj->buffer;
}
}
for(i = 0; i < sndobj->samples; i++){//normalisieren und maximallautstärke bestimmen
sndobj->buffer = (sndobj->buffer / val) * mastervol;
}
SNDFILE *file = sf_open("datei.wav", SFM_WRITE, &(sndobj->file_info));
if(file == NULL){
printf("Konnte Datei nicht öffnen");
}
sf_writef_float(file, sndobj->buffer, sndobj->samples/2);
free(sndobj->buffer);
}
tone create_tone_saw(float length, int freq, float chanvol1, float chanvol2){
float *chan1, *chan2;
tone *tone;
tone->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
tone->size = round1(length) * SAMPLERATE * 2;
tone->frequenzy = freq;
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1) * 2 -1;
chan2 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2) * 2 -1;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
tone->data = chan1[i/2];
tone->data[i+1] = chan2[i/2];
}
free(chan1);
free(chan2);
return *tone;
}
void create_linearfade(float in_time, float out_time, tone *tone){
if(in_time !=0 || tone->size > in_time * SAMPLERATE * 2){
for(i = 0; i < in_time * 2 * SAMPLERATE; i = i +2){//Fade-in
tone->data = tone->data * (((float)i * 0.5) / ((float)SAMPLERATE * in_time ) );
tone->data[i+1]= tone->data[i +1] * (((float)i * 0.5) / ((float)SAMPLERATE * in_time ) );
}
}
if(out_time !=0 || tone->size > out_time * SAMPLERATE * 2){//funktionert fast. irgendwas stimmt mit der formel nicht oder der schleife
float y = 0;//andere zähvariable
for(i = tone->size - 2 * out_time * SAMPLERATE ; i < tone->size ; i = i + 2){//fade-out
tone->data = tone->data *(float) ((SAMPLERATE * out_time - (y/2)) / SAMPLERATE * out_time);
tone->data[i+1]= tone->data[i+1] *(float) ((SAMPLERATE * out_time - (y/2)) / SAMPLERATE * out_time);
y += 2;
}
}
}
void create_harmonic_sine (float ratio, tone *tone, float vol){
printf("freq: &f", tone->frequenzy);
for(i = 0; i < tone->size ; i += 2){
tone->data += (sin(2* PI * (i/2) / ((float)SAMPLERATE / (float)(tone->frequenzy * ratio))) * vol) ;
//tone->data[i+1] += (sin(2* PI * (i/2) / ((float)SAMPLERATE / (float)(tone->freq * ratio))) * vol);
}
return;
}
[/src]
Die Fehlermeldung aus der Konsole dazu lautet:
'/home/ale/Dokumente/synth/test'
*** Error in `/home/ale/Dokumente/synth/test': double free or corruption (out): 0x00007fff97f097c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80a46)[0x7f79af38fa46]
/home/ale/Dokumente/synth/test[0x40104b]
/home/ale/Dokumente/synth/test[0x401c71]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f79af330ea5]
/home/ale/Dokumente/synth/test[0x400839]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:01 18350101 /home/ale/Dokumente/synth/test
00602000-00603000 r--p 00002000 08:01 18350101 /home/ale/Dokumente/synth/test
00603000-00604000 rw-p 00003000 08:01 18350101 /home/ale/Dokumente/synth/test
01de3000-01e5a000 rw-p 00000000 00:00 0 [heap]
7f79ae24c000-7f79ae260000 r-xp 00000000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae260000-7f79ae460000 ---p 00014000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae460000-7f79ae461000 r--p 00014000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae461000-7f79ae462000 rw-p 00015000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae462000-7f79ae7c0000 rw-p 00000000 00:00 0
7f79ae7c0000-7f79ae7c6000 r-xp 00000000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae7c6000-7f79ae9c5000 ---p 00006000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c5000-7f79ae9c6000 r--p 00005000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c6000-7f79ae9c7000 rw-p 00006000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c7000-7f79ae9f2000 r-xp 00000000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79ae9f2000-7f79aebf2000 ---p 0002b000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf2000-7f79aebf3000 r--p 0002b000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf3000-7f79aebf4000 rw-p 0002c000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf4000-7f79aeea7000 r-xp 00000000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79aeea7000-7f79af0a6000 ---p 002b3000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0a6000-7f79af0c2000 r--p 002b2000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0c2000-7f79af0c3000 rw-p 002ce000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0c3000-7f79af10d000 r-xp 00000000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af10d000-7f79af30d000 ---p 0004a000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30d000-7f79af30e000 r--p 0004a000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30e000-7f79af30f000 rw-p 0004b000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30f000-7f79af4cd000 r-xp 00000000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af4cd000-7f79af6cc000 ---p 001be000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6cc000-7f79af6d0000 r--p 001bd000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6d0000-7f79af6d2000 rw-p 001c1000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6d2000-7f79af6d7000 rw-p 00000000 00:00 0
7f79af6d7000-7f79af7da000 r-xp 00000000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af7da000-7f79af9da000 ---p 00103000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9da000-7f79af9db000 r--p 00103000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9db000-7f79af9dc000 rw-p 00104000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9dc000-7f79afa3b000 r-xp 00000000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afa3b000-7f79afc3b000 ---p 0005f000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3b000-7f79afc3d000 r--p 0005f000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3d000-7f79afc3e000 rw-p 00061000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3e000-7f79afc42000 rw-p 00000000 00:00 0
7f79afc42000-7f79afc65000 r-xp 00000000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7f79afe45000-7f79afe4a000 rw-p 00000000 00:00 0
7f79afe61000-7f79afe64000 rw-p 00000000 00:00 0
7f79afe64000-7f79afe65000 r--p 00022000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7f79afe65000-7f79afe67000 rw-p 00023000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7fff97eeb000-7fff97f0c000 rw-p 00000000 00:00 0 [stack]
7fff97ffe000-7fff98000000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Abgebrochen (Speicherabzug geschrieben)
*** Error in `/home/ale/Dokumente/synth/test': double free or corruption (out): 0x00007fff97f097c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80a46)[0x7f79af38fa46]
/home/ale/Dokumente/synth/test[0x40104b]
/home/ale/Dokumente/synth/test[0x401c71]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f79af330ea5]
/home/ale/Dokumente/synth/test[0x400839]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:01 18350101 /home/ale/Dokumente/synth/test
00602000-00603000 r--p 00002000 08:01 18350101 /home/ale/Dokumente/synth/test
00603000-00604000 rw-p 00003000 08:01 18350101 /home/ale/Dokumente/synth/test
01de3000-01e5a000 rw-p 00000000 00:00 0 [heap]
7f79ae24c000-7f79ae260000 r-xp 00000000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae260000-7f79ae460000 ---p 00014000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae460000-7f79ae461000 r--p 00014000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae461000-7f79ae462000 rw-p 00015000 08:01 12062330 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f79ae462000-7f79ae7c0000 rw-p 00000000 00:00 0
7f79ae7c0000-7f79ae7c6000 r-xp 00000000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae7c6000-7f79ae9c5000 ---p 00006000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c5000-7f79ae9c6000 r--p 00005000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c6000-7f79ae9c7000 rw-p 00006000 08:01 23862612 /usr/lib/x86_64-linux-gnu/libogg.so.0.8.0
7f79ae9c7000-7f79ae9f2000 r-xp 00000000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79ae9f2000-7f79aebf2000 ---p 0002b000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf2000-7f79aebf3000 r--p 0002b000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf3000-7f79aebf4000 rw-p 0002c000 08:01 23862833 /usr/lib/x86_64-linux-gnu/libvorbis.so.0.4.5
7f79aebf4000-7f79aeea7000 r-xp 00000000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79aeea7000-7f79af0a6000 ---p 002b3000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0a6000-7f79af0c2000 r--p 002b2000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0c2000-7f79af0c3000 rw-p 002ce000 08:01 23862835 /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2.0.8
7f79af0c3000-7f79af10d000 r-xp 00000000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af10d000-7f79af30d000 ---p 0004a000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30d000-7f79af30e000 r--p 0004a000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30e000-7f79af30f000 rw-p 0004b000 08:01 23861921 /usr/lib/x86_64-linux-gnu/libFLAC.so.8.2.0
7f79af30f000-7f79af4cd000 r-xp 00000000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af4cd000-7f79af6cc000 ---p 001be000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6cc000-7f79af6d0000 r--p 001bd000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6d0000-7f79af6d2000 rw-p 001c1000 08:01 12062305 /lib/x86_64-linux-gnu/libc-2.17.so
7f79af6d2000-7f79af6d7000 rw-p 00000000 00:00 0
7f79af6d7000-7f79af7da000 r-xp 00000000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af7da000-7f79af9da000 ---p 00103000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9da000-7f79af9db000 r--p 00103000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9db000-7f79af9dc000 rw-p 00104000 08:01 12062353 /lib/x86_64-linux-gnu/libm-2.17.so
7f79af9dc000-7f79afa3b000 r-xp 00000000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afa3b000-7f79afc3b000 ---p 0005f000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3b000-7f79afc3d000 r--p 0005f000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3d000-7f79afc3e000 rw-p 00061000 08:01 23862744 /usr/lib/x86_64-linux-gnu/libsndfile.so.1.0.25
7f79afc3e000-7f79afc42000 rw-p 00000000 00:00 0
7f79afc42000-7f79afc65000 r-xp 00000000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7f79afe45000-7f79afe4a000 rw-p 00000000 00:00 0
7f79afe61000-7f79afe64000 rw-p 00000000 00:00 0
7f79afe64000-7f79afe65000 r--p 00022000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7f79afe65000-7f79afe67000 rw-p 00023000 08:01 12062281 /lib/x86_64-linux-gnu/ld-2.17.so
7fff97eeb000-7fff97f0c000 rw-p 00000000 00:00 0 [stack]
7fff97ffe000-7fff98000000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Abgebrochen (Speicherabzug geschrieben)
Dabei vermute ich stark, dass der Fehler in der Funktion create_tone_sine
[src=c]tone create_tone_saw(float length, int freq, float chanvol1, float chanvol2){
float *chan1, *chan2;
tone *tone;
tone->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
tone->size = round1(length) * SAMPLERATE * 2;
tone->frequenzy = freq;
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1) * 2 -1;
chan2 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2) * 2 -1;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
tone->data = chan1[i/2];
tone->data[i+1] = chan2[i/2];
}
free(chan1);
free(chan2);
return *tone;
}[/src]
float *chan1, *chan2;
tone *tone;
tone->data = calloc(round1(length) * SAMPLERATE *2, sizeof(float));
chan1 = calloc(round1(length) * SAMPLERATE, sizeof(float));
chan2 = calloc(round1(length) * SAMPLERATE, sizeof(float));
tone->size = round1(length) * SAMPLERATE * 2;
tone->frequenzy = freq;
for(i = 0; i < SAMPLERATE * round1(length) ; i++){//fülle beide channel mit sinuswerten
chan1 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol1) * 2 -1;
chan2 = ( ((i / ((float)SAMPLERATE/(float)freq)) - floorf(i / ((float)SAMPLERATE / (float)freq))) * (float)chanvol2) * 2 -1;
}
for(i = 0; i < round1(length) * SAMPLERATE * 2; i = i + 2){//beide channel in einen buffer schreiben
tone->data = chan1[i/2];
tone->data[i+1] = chan2[i/2];
}
free(chan1);
free(chan2);
return *tone;
}[/src]
in Verbindung mit der Funktion merge liegt
[src=c]void merge(snd *sndobj, tone *tone, float start ){
if(sndobj->samples < round1(start) * SAMPLERATE * 2 + tone->size){// gegebenenfalls neuen speicher nehmen, falls der neue ton nicht hinenpasst
sndobj->buffer = realloc(sndobj->buffer, tone->size * sizeof(float) + (SAMPLERATE * start) * sizeof(float) * 2);
sndobj->samples = tone->size + SAMPLERATE * start * 2 ;
}
for(i = SAMPLERATE * start * 2; i < tone->size + start * 2 * SAMPLERATE ; i++){//ton in den buffer eones snd objekts schreiben
sndobj->buffer = (sndobj->buffer + tone->data[((int)(i - SAMPLERATE * start * 2))]);
}
free((tone->data));
}[/src]
if(sndobj->samples < round1(start) * SAMPLERATE * 2 + tone->size){// gegebenenfalls neuen speicher nehmen, falls der neue ton nicht hinenpasst
sndobj->buffer = realloc(sndobj->buffer, tone->size * sizeof(float) + (SAMPLERATE * start) * sizeof(float) * 2);
sndobj->samples = tone->size + SAMPLERATE * start * 2 ;
}
for(i = SAMPLERATE * start * 2; i < tone->size + start * 2 * SAMPLERATE ; i++){//ton in den buffer eones snd objekts schreiben
sndobj->buffer = (sndobj->buffer + tone->data[((int)(i - SAMPLERATE * start * 2))]);
}
free((tone->data));
}[/src]
Zumindest bekomme ich keinen Fehler wenn ich diese aus dem Code eines Testprogrammes auskommentiere.
Das Testprogramm sieht folgendermaßen aus:
[src=c]#include <stdio.h>
#include "synth.h"
int main(){
float z;
snd klang = create_snd();
snd *ptr = &klang;
tone *tone =create_tone_sine(10,440,1,1);
merge(ptr,tone, 1);
export(ptr, 0.5);
return 0;
}[/src]
#include "synth.h"
int main(){
float z;
snd klang = create_snd();
snd *ptr = &klang;
tone *tone =create_tone_sine(10,440,1,1);
merge(ptr,tone, 1);
export(ptr, 0.5);
return 0;
}[/src]
Ich hoffe jemand hat den Mut und die Lust sich da durchzukämpfen. Vielleicht ist es ja aber auch ganz einfach und ich seh den Wald vor lauter Bäumen nicht.
Vielen Dank schonmal im Vorraus