генерация тона с помощью sdl_mixer завершается с ошибкой сегментации в ubuntu 12.04 64 bit

Я должен написать простой синтезатор в университете, который использует sdl_mixer для генерации синусоидальных волн. Я получил код от своего учителя, который правильно работает на Windows, но в Ubuntu он выходит из-за ошибки сегментации.
Я установил оба пакета: sdl_mixer1.2-dev и sdl1.2-dev.
Я попробовал код, который генерирует тон с sdl_audio. Это работало нормально, но я слышал, что для многоканального воспроизведения, sdl_mixer является решением.
Часть кода getch () работает хорошо, проблема в части менеджера звука.

Может кто-нибудь помочь мне решить эту проблему?

Вот мой код:

#include <iostream>
#include <termios.h>
#include <stdio.h>
#include<cmath>
#include <SDL/SDL_mixer.h>
#include<vector>

using namespace std;class SoundManager
{
int channelnum;
vector<Mix_Chunk*> chunks;
public:
void init()
{
if (Mix_OpenAudio(48000,AUDIO_S16, 2, 1024) == -1)
{
cerr << "audio hiba" << endl;
exit(1);
}
}
SoundManager(int asked_channelnum=64)
{
channelnum = Mix_AllocateChannels(asked_channelnum);
chunks.assign(channelnum, (Mix_Chunk*)0);
}
int get_channelnum() const
{
return channelnum;
}
void play_stereo(const vector<short int>& v, int volume=128)
{
const short int *p = &(v[0]);
//        short int * p = new short int[v.size()];
//        for (size_t i=0;i<v.size();i++) {
//            p[i]=v[i];
//        }
Mix_Chunk * ownsample = new Mix_Chunk;
ownsample->alen = v.size()*2;
ownsample->abuf = (Uint8*)p;
ownsample->allocated = 1;
ownsample->volume = volume;
int playchannel = Mix_PlayChannel(-1, ownsample, 0);
if (playchannel != -1 && chunks[playchannel])
{
delete[] chunks[playchannel]->abuf;
Mix_FreeChunk(chunks[playchannel]);
}
if (playchannel != -1)
chunks[playchannel] = ownsample;
}
};

Mix_Chunk *ownsample = 0;
Mix_Chunk *samples = 0;

void hang()
{
if (Mix_OpenAudio(48000,AUDIO_S16, 2, 1024) == -1)
{
cerr << "audio hiba" << endl;
exit(1);
}
vector<short> s(48000*2,0);
for (int i=0; i<s.size()/2; i++)
{
s[i*2] = sin(i/10.0+i*i/10000.0)*32000*(1/sqrt(i/100.0));
s[i*2+1] = sin(i/10.0)*32000*(1/sqrt(i/100.0));
}
samples = Mix_LoadWAV("ding.wav");
ownsample = new Mix_Chunk;
ownsample->alen = s.size()*2;
ownsample->abuf =(unsigned char*) &(s[0]);
ownsample->allocated = 0;
ownsample->volume = 128;
cout << samples->alen << endl;
if (!samples)
{
cerr << "wav 'ding.wav' open error" << endl;
exit(1);
}
int channelnum = Mix_AllocateChannels(64);

if (channelnum != 64)
{
cerr << "warning: not as many channels are reserved as attended"<<endl;
}
if (Mix_PlayChannel(-1, ownsample, 0)==-1 )
{
cerr << "error on play" << endl;
}
//    if (Mix_PlayChannel(-1, samples, 0)==-1 ) {
//        cerr << "error on play" << endl;
//    }

}void pitty(SoundManager &sm)
{
vector<short> s(48000*2,0);
for (int i=0; i<s.size()/2; i++)
{
s[i*2] = sin(i/10.0+i*i/10000.0)*32000*(1/sqrt(i/100.0));

s[i*2+1] = sin(i/10.0)*32000*(1/sqrt(i/100.0));
}
sm.play_stereo(s);
}static struct termios old, New;

/* Initialize New terminal i/o settings */
void initTermios(int echo)
{
tcgetattr(0, &old); /* grab old terminal i/o settings */
New = old; /* make New settings same as old settings */
New.c_lflag &= ~ICANON; /* disable buffered i/o */
New.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */
tcsetattr(0, TCSANOW, &New); /* use these New terminal i/o settings now */
}

/* Restore old terminal i/o settings */
void resetTermios(void)
{
tcsetattr(0, TCSANOW, &old);
}

/* Read 1 character - echo defines echo mode */
char getch_(int echo)
{
int ch;
initTermios(echo);
ch = getchar();
resetTermios();
return ch;
}

/* Read 1 character without echo */
int getch(void)
{
return getch_(o);
}

/* Read 1 character with echo */
int getche(void)
{
return getch_(1);
}
int main(void)
{
SoundManager sm(16);
sm.init();
vector<short> s(48000*2,0);
for (int i=0; i<s.size()/2; i++)
{
s[i*2] = sin(i/10.0+i*i/10000.0)*32000*(1/sqrt(i/100.0));

s[i*2+1] = sin(i/10.0)*32000*(1/sqrt(i/100.0));
}

int c;
while (1)
{
c = getch();
cout <<"keycode:\n";
cout <<c;
sm.play_stereo(s);
}
return 0;
}

Спасибо за вашу помощь заранее.

Привет,
Иштван Велеги

0

Решение

(1) если вы получаете ошибку сегментации, можете ли вы перекомпилировать код с включенными символами отладки (если вы используете g ++ или clang ++); используйте -g3.

(2) запустите программу с помощью отладчика и получите трассировку стека, где происходит ошибка сегментации кода (используйте gdb).

0

Другие решения

Это выглядит абсолютно фиктивно:

void play_stereo(const vector<short int>& v, int volume=128)
{
const short int *p = &(v[0]);

//...

ownsample->abuf = (Uint8*)p;

//...
delete[] chunks[playchannel]->abuf;

Да я понимаю chunks[playchannel] не ownsample еще, но ты делаешь ownsample в chunks очередь, так что в конце концов вы вернетесь и попытаться delete[] внутреннее хранилище массива vector<short int>,

Это очень плохо.

Этот закомментированный код на самом деле кажется правильным const short int *p = &(v[0]):

//        short int * p = new short int[v.size()];
//        for (size_t i=0;i<v.size();i++) {
//            p[i]=v[i];
//        }
0

По вопросам рекламы [email protected]