[ fmod | wxwidgets]rendu spectrum -- mp3

Description

voila, un tout petit projet sympa, lit les fichiers audio, affiche un spectre, pour débutants...

le spectre a été développé avec une mackie cfx20 ( je me suis bien fait ch** ), normalement assez fidéle.

Cela dit, ce programme peux constituer un bon exemple a tout débutant wxWIDGETS ou meme FMOD;

Le rendu est opéré dans des threads séparés avec des wxMemoryDC.

Ce programme ne marche probablement que sous windows, enfin, je dis ca car je n'ai rien fait pour la portabilité, a tester donc...

voila, pas d'améliorations prévues, mais toute remarque sera la bienvenue;
Enjoy

Source / Exemple :


// main.cpp [ seul et unique fichier ]
#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

#include <fmod.h>
#include <fmod_errors.h>

#include <fstream>

WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);

#define ZONESPECTRE_WIDTH 350
#define ZONESPECTRE_HEIGHT 116

class MyFrame;
class ControlWin;
class MyRenderThread;
class MyControlThread;
class MyLevelThread;

class PaneControl : public wxFrame
{
	DECLARE_EVENT_TABLE()

public:
	PaneControl(MyFrame *m_parent);
	virtual ~PaneControl();

	MyFrame *m_pFrame;

	MyLevelThread *CreateLevelThread(void);

	void StartLevelThread(void);

private:
	void PaintInitialScreen(wxDC &dc);

protected:
	void OnPaint(wxPaintEvent &event);
};

class MyLevelThread : public wxThread
{
	PaneControl *m_pPaneWin;
	MyFrame     *m_pFrame;
	ControlWin  *m_pControlWin;

public:
	MyLevelThread(PaneControl *m_paneWindow, MyFrame *m_frame, ControlWin *m_controlwin);

	virtual void *Entry(void);

	virtual void OnExit(void);

	void RenderPane(wxDC &dc);
};

class ControlWin : public wxFrame
{
	DECLARE_EVENT_TABLE()

public:
	ControlWin(MyFrame *m_parent);
	virtual ~ControlWin();

	MyFrame *m_pFrame;

	MyControlThread *CreateControlThread(void);

	void StartControlThread(void);

private:
	void PaintInitialScreen(wxDC &dc);

protected:
	void OnPaint(wxPaintEvent &event);
};

class DSPWnd : public wxWindow
{
	DECLARE_EVENT_TABLE()

public:
	DSPWnd(MyFrame *m_parent);
	virtual ~DSPWnd();

	MyFrame *m_pFrame;

	MyRenderThread *CreateRenderThread(void);

	void StartRenderThread(void);

	void PaintInitialScreen(wxDC &dc);

protected:
	void OnPaint(wxPaintEvent &event);

	void OnSize(wxSizeEvent &event);
};

class MyControlThread : public wxThread
{
	ControlWin *m_pControlWin;
	MyFrame *m_pFrame;

public:
	MyControlThread(ControlWin *m_controlwin, MyFrame *m_frame);

	virtual void *Entry(void);

	virtual void OnExit(void);

	void RenderInfos(wxDC &dc);
};

class MyRenderThread : public wxThread
{
	DSPWnd *m_pRenderWin;
	ControlWin *m_pControlWin;
	MyFrame *m_pFrame;
	
public:
	MyRenderThread(MyFrame *m_frame, DSPWnd *m_renderwin, ControlWin *m_controlwin);

	virtual void *Entry(void);

	virtual void OnExit(void);

	void RenderSpectrum(wxDC &dc, bool uselog);

	bool IsFinished;
};

class MyApp : public wxApp
{
public:
	MyApp();
    virtual bool OnInit();

	wxCriticalSection m_critsect;

	wxSemaphore m_semAllDone;

	bool m_waitingUntilAllDone;
	
	wxArrayThread m_threads;
};

DECLARE_APP(MyApp)

class MyFrame : public wxFrame
{
	DECLARE_EVENT_TABLE()
	
public:
	DSPWnd        *m_pRenderWin;
	ControlWin    *m_pControlWin;
	PaneControl   *m_pPaneControl;

	FSOUND_STREAM *m_pStream;

	bool IsQuit;
	bool IsFinished;
	int channel;
	char *data;

    MyFrame();
	virtual ~MyFrame();

private:
	void PlayFile(const wxString &filename);

protected:
	void OnClose(wxCloseEvent &event);

	void OnDrop(wxDropFilesEvent &event);
};

MyApp::MyApp() : m_semAllDone()
{
	m_waitingUntilAllDone = false;
}

bool MyApp::OnInit()
{
	int width, height, x, y;

	wxClientDisplayRect(&x, &y, &width, &height);

	wxPoint m_point(width-ZONESPECTRE_WIDTH, height-200);

    MyFrame *frame = new MyFrame;

	frame->SetSize(ZONESPECTRE_WIDTH, 200);
	frame->SetPosition(m_point);

    frame->Show(true);
    return true;
}

MyLevelThread::MyLevelThread(PaneControl *m_paneWindow, MyFrame *m_frame, ControlWin *m_controlwin) : wxThread()
{
	m_pFrame      = m_frame;
	m_pPaneWin    = m_paneWindow;
	m_pControlWin = m_controlwin;
}

void *MyLevelThread::Entry(void)
{
	if( TestDestroy() )
		return NULL;

	wxWindowDC dc(m_pPaneWin);
	RenderPane(dc);

	return NULL;
}

void MyLevelThread::OnExit(void)
{
    wxCriticalSectionLocker locker( wxGetApp().m_critsect );

	wxArrayThread& threads = wxGetApp().m_threads;
    threads.Remove(this);

    if( threads.IsEmpty() )
    {
        if( wxGetApp().m_waitingUntilAllDone )
        {
            wxGetApp().m_waitingUntilAllDone = false;

            wxGetApp().m_semAllDone.Post();
        }
    }

	if( !m_pFrame->IsQuit && !m_pFrame->IsFinished )
	{
		m_pPaneWin->StartLevelThread();
	}
}

void MyLevelThread::RenderPane(wxDC &dc)
{
#define offset(_x) (y - 20) - _x
	
	Sleep( 24 );

	int   time           = FSOUND_Stream_GetTime(m_pFrame->m_pStream);
	int   length         = FSOUND_Stream_GetLengthMs(m_pFrame->m_pStream);
	if( time == length || m_pFrame->IsQuit )
	{
		m_pFrame->IsFinished = true;
		return;
	}	

	float l, r;
	int R, G, B, x, y, MyLevelL, MyLevelR;
	m_pPaneWin->GetClientSize(&x, &y);

	FSOUND_GetCurrentLevels(m_pFrame->channel, &l, &r);
	MyLevelL = (int) (l * 100.0f);
	MyLevelR = (int) (r * 100.0f);
	
	wxBitmap bmp(x-20, y-15);
	wxMemoryDC memdc;
	memdc.SelectObject( bmp );

	dc.SetDeviceOrigin( 3, 35 );

	for( int l = x/2 - 12; l < ( x/2 - 12 ) + 10; l++)
	{
		for( int h = 0; h < MyLevelL; h++ )
		{
			R = h << 1;
			G = 0xFF - (h << 1);
			B = 0x1F;

			if( R <= 0xFF && G <= 0xFF )
				memdc.SetPen( wxColour(R, G, B) );
			else memdc.SetPen( *wxRED );

			memdc.BeginDrawing();
			memdc.DrawPoint( l, offset(h) );
			memdc.EndDrawing();
		}
	}
	for( int l = x/2; l < x/2 + 10; l++)
	{
		for( int h = 0; h < MyLevelR; h++ )
		{
			if( MyLevelR >= y - 15)
				MyLevelR = y - 16;

			R = h << 1;
			G = 0xFF - (h << 1);
			B = 0x1F;

			if( R <= 0xFF && G <= 0xFF )
				memdc.SetPen( wxColour(R, G, B) );
			else memdc.SetPen( *wxRED );

			memdc.BeginDrawing();
			memdc.DrawPoint( l, offset(h) );
			memdc.EndDrawing();
		}
	}
	dc.Blit(0, 0, x, y, &memdc, 0, 0);

	wxMemoryDC mmdc;
	wxBitmap mmbmp(120, 12);
	mmdc.SelectObject(mmbmp);
	mmdc.SetFont(*wxITALIC_FONT);
    mmdc.SetTextForeground( *wxLIGHT_GREY );

	wxString str;
	str.Printf("Thread 0x%lx DSPP run", GetId());

	mmdc.DrawText(str, 1, 0);

	wxWindowDC Cdc(m_pControlWin);
	Cdc.Blit( 3, 138, 120, 12, &mmdc, 0, 0, wxCOPY );
}

MyControlThread::MyControlThread(ControlWin *m_controlwin, MyFrame *m_frame) : wxThread()
{
	m_pFrame = m_frame;
	m_pControlWin = m_controlwin;
}

void *MyControlThread::Entry(void)
{
	if( TestDestroy() )
		return NULL;

	wxWindowDC dc(m_pControlWin);
	RenderInfos(dc);

	return NULL;
}

void MyControlThread::OnExit(void)
{
    wxCriticalSectionLocker locker( wxGetApp().m_critsect );

	wxArrayThread& threads = wxGetApp().m_threads;
    threads.Remove(this);

    if( threads.IsEmpty() )
    {
        if( wxGetApp().m_waitingUntilAllDone )
        {
            wxGetApp().m_waitingUntilAllDone = false;

            wxGetApp().m_semAllDone.Post();
        }
    }

	if( !m_pFrame->IsQuit && !m_pFrame->IsFinished )
	{
		m_pControlWin->StartControlThread();
	}	
}

void MyControlThread::RenderInfos(wxDC &dc)
{
	Sleep(20);

	float RIGHT, LEFT;
	int   time           = FSOUND_Stream_GetTime(m_pFrame->m_pStream);
	int   length         = FSOUND_Stream_GetLengthMs(m_pFrame->m_pStream);
	if( time == length || m_pFrame->IsQuit )
	{
		m_pFrame->IsFinished = true;
		return;
	}	
	wxString status, cpu, cput, rate, memorystats, Rlevel, Llevel, threads;
	unsigned int currentalloced, maxalloced;

	float m_cpuf         = FSOUND_GetCPUUsage();
	int   irate          = FSOUND_GetFrequency(m_pFrame->channel);

	FSOUND_GetCurrentLevels(m_pFrame->channel, &RIGHT, &LEFT);

	FSOUND_GetMemoryStats(&currentalloced,&maxalloced);

	threads.Printf("Thread 0x%lx CTR run", GetId());

	Rlevel.Printf("Rlevel : %f", RIGHT*10);

	Llevel.Printf("Llevel : %f", LEFT*10);

	memorystats.Printf("Mem alloced: %d", currentalloced);

	rate.Printf("Rate: %dHZ", irate);

	cpu.Printf("%f", m_cpuf);
	cpu << " % CPU";

	status.Printf("%d ms / %d", time, length);

	int x, y;
	m_pControlWin->GetClientSize(&x, &y);

	wxBitmap bmp(x, y);
	wxMemoryDC memdc;
	memdc.SelectObject(bmp);

	memdc.SetFont(*wxITALIC_FONT);
    memdc.SetTextForeground( *wxLIGHT_GREY );

	memdc.DrawText(status,      1, 0);
	memdc.DrawText(cpu,         1, 12);
	memdc.DrawText(rate,        1, 24);
	memdc.DrawText(memorystats, 1, 36);
	memdc.DrawText(Rlevel,      1, 48);
	memdc.DrawText(Llevel,      1, 60);
	memdc.DrawText(threads,     1, 72);

	dc.Blit(3, 42, x-6, 84, &memdc, 0, 0);
}

MyRenderThread::MyRenderThread(MyFrame *m_frame, DSPWnd *m_renderwin, ControlWin *m_controlwin) : wxThread( )
{
	m_pFrame      = m_frame;
	m_pRenderWin  = m_renderwin;
	m_pControlWin = m_controlwin;
}

void *MyRenderThread::Entry(void)
{
	if( TestDestroy() )
		return NULL;

	wxWindowDC m_dc( m_pRenderWin );
	RenderSpectrum(m_dc, true);

	return NULL;
}

void MyRenderThread::OnExit(void)
{
	wxCriticalSectionLocker locker(wxGetApp().m_critsect);

	wxArrayThread& threads = wxGetApp().m_threads;
	
	threads.Remove(this);
	
    if( threads.IsEmpty() )
    {
        if( wxGetApp().m_waitingUntilAllDone )
        {
            wxGetApp().m_waitingUntilAllDone = false;

            wxGetApp().m_semAllDone.Post();
        }
    }
	if( !m_pFrame->IsQuit && !m_pFrame->IsFinished )
	{
		m_pRenderWin->StartRenderThread();
	}
}

void MyRenderThread::RenderSpectrum(wxDC &dc, bool uselog)
{
	Sleep(25);

	int x, y;
	int r, g, b, ampli;
	float max, val, db;
	int   time   = FSOUND_Stream_GetTime(m_pRenderWin->m_pFrame->m_pStream);
	int   length = FSOUND_Stream_GetLengthMs(m_pRenderWin->m_pFrame->m_pStream);

	if( time == length || m_pRenderWin->m_pFrame->IsQuit )
	{
		m_pRenderWin->m_pFrame->IsFinished = true;
		m_pRenderWin->PaintInitialScreen( dc );
		return;
	}

	m_pRenderWin->GetClientSize(&x, &y);

	dc.SetDeviceOrigin(15, 0);

	wxBitmap bmp(x - 15, y - 12);

	wxMemoryDC memdc;
	memdc.SelectObject(bmp);	
	
	float *m_spectr = FSOUND_DSP_GetSpectrum();
 /*
    1.0   = 0db
    0.5   = -6db
    0.25  = -12db
    0.125 = -24db

  • /
max = 0.0f; for(int i = 0; i < x; i++) { if( x > 512 + ( i * 10 ) ) x = 512 + (i * 10); /* val = ( m_spectr[i] + m_spectr[i+1] + m_spectr[i+2] + m_spectr[i+3] + m_spectr[i+4] + m_spectr[i+6] + m_spectr[i+7] + m_spectr[i+8] + m_spectr[i+9] ) / 10;
  • /
val = m_spectr[i]; if( val > max ) max = val; if(uselog) { db = 10.0f * (float)log10(val) * 2.0f; val = db; if (val < -150) { val = -150; } val /= -150.0f; val = 1.0f - val; ampli = (int)( val * (float)ZONESPECTRE_HEIGHT ); } else { ampli = (int)( val / max * (float)ZONESPECTRE_HEIGHT ); } for(int j = ampli - 10; j < ampli; j++) { r = j << 1; g = 0xFF - (j << 1); b = 0x1F; if( r <= 0xFF && g <= 0xFF ) memdc.SetPen( wxColour(r, g, b) ); else memdc.SetPen( *wxRED ); #define AMPLITUDE(_x) (y - 12) - _x memdc.BeginDrawing(); for(int l = i; l < i + 10; l++) { memdc.DrawPoint( l, AMPLITUDE( j ) ); } memdc.EndDrawing(); } i = i + 10; } memdc.SetPen(wxNullPen); dc.Blit( 0, 0, x, y, &memdc, 0, 0, wxCOPY ); wxMemoryDC mmdc; wxBitmap mmbmp(120, 12); mmdc.SelectObject(mmbmp); mmdc.SetFont(*wxITALIC_FONT); mmdc.SetTextForeground( *wxLIGHT_GREY ); wxString str; str.Printf("Thread 0x%lx DSP run", GetId()); mmdc.DrawText(str, 1, 0); wxWindowDC Cdc(m_pControlWin); Cdc.Blit( 3, 126, 110, 12, &mmdc, 0, 0, wxCOPY ); } BEGIN_EVENT_TABLE(PaneControl, wxFrame) EVT_PAINT(PaneControl::OnPaint) END_EVENT_TABLE() PaneControl::PaneControl(MyFrame *m_parent) : wxFrame ( NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(75, 160), wxCAPTION | wxMINIMIZE_BOX | //wxSTAY_ON_TOP | wxSYSTEM_MENU | wxFRAME_TOOL_WINDOW | wxNO_BORDER ), m_pFrame(m_parent) { SetBackgroundColour(*wxBLACK); SetTitle(_T("Levels")); int width, height, x, y; wxClientDisplayRect(&x, &y, &width, &height); wxPoint m_point(width - ZONESPECTRE_WIDTH - 130 - 75, height-160); SetPosition(m_point); Show( true ); } PaneControl::~PaneControl() { } void PaneControl::OnPaint(wxPaintEvent &WXUNUSED(event)) { wxPaintDC m_dc(this); m_dc.Clear(); PaintInitialScreen(m_dc); } void PaneControl::PaintInitialScreen(wxDC &dc) { dc.SetFont(wxFont(8, wxTELETYPE, wxNORMAL, wxNORMAL) ); dc.SetTextForeground( *wxGREEN ); dc.DrawText("LEVELS", 1, 1 ); } MyLevelThread *PaneControl::CreateLevelThread( void ) { MyLevelThread *thread = new MyLevelThread(this, m_pFrame, m_pFrame->m_pControlWin); if ( thread->Create() != wxTHREAD_NO_ERROR ) { wxLogError(_T("Can't create thread!")); } wxCriticalSectionLocker enter( wxGetApp().m_critsect ); wxGetApp().m_threads.Add(thread); return thread; } void PaneControl::StartLevelThread( void ) { wxThread *thr = CreateLevelThread(); if ( thr->Run() != wxTHREAD_NO_ERROR ) { wxLogError(wxT("Can't start thread!")); } thr->SetPriority(WXTHREAD_DEFAULT_PRIORITY); } BEGIN_EVENT_TABLE(ControlWin, wxFrame) EVT_PAINT(ControlWin::OnPaint) END_EVENT_TABLE() ControlWin::ControlWin(MyFrame *m_parent) : wxFrame ( NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(130, 200), wxCAPTION | wxMINIMIZE_BOX | wxSYSTEM_MENU | wxFRAME_TOOL_WINDOW | wxNO_BORDER ), m_pFrame(m_parent) { int width, height, x, y; wxClientDisplayRect(&x, &y, &width, &height); wxPoint m_point(width - ZONESPECTRE_WIDTH - 130, height-200); SetPosition(m_point); SetTitle(_T("Controler")); SetBackgroundColour(*wxBLACK); Show( true ); } ControlWin::~ControlWin() { } void ControlWin::OnPaint(wxPaintEvent &WXUNUSED(event)) { wxPaintDC dc( this ); PaintInitialScreen( dc ); } void ControlWin::PaintInitialScreen(wxDC &dc) { dc.SetFont(wxFont(8, wxTELETYPE, wxNORMAL, wxNORMAL) ); dc.SetTextForeground( *wxGREEN ); dc.DrawText("CONTROLER", 1, 1 ); } MyControlThread *ControlWin::CreateControlThread(void) { MyControlThread *thread = new MyControlThread(this, m_pFrame); if ( thread->Create() != wxTHREAD_NO_ERROR ) { wxLogError(_T("Can't create thread!")); } wxCriticalSectionLocker enter( wxGetApp().m_critsect ); wxGetApp().m_threads.Add(thread); return thread; } void ControlWin::StartControlThread(void) { wxThread *thr = CreateControlThread(); if ( thr->Run() != wxTHREAD_NO_ERROR ) { wxLogError(wxT("Can't start thread!")); } thr->SetPriority(WXTHREAD_MIN_PRIORITY); } BEGIN_EVENT_TABLE(DSPWnd, wxWindow) EVT_PAINT(DSPWnd::OnPaint) EVT_SIZE(DSPWnd::OnSize) END_EVENT_TABLE() DSPWnd::DSPWnd(MyFrame *m_parent) : wxWindow( m_parent, wxID_ANY, wxPoint(-1,-1), wxSize(-1,-1), NULL, "" ), m_pFrame(m_parent) { SetBackgroundColour(*wxBLACK); FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true); if( !FSOUND_DSP_GetActive( FSOUND_DSP_GetFFTUnit() ) ) { wxLogError("Can't active spctrum"); return; } } DSPWnd::~DSPWnd() { } void DSPWnd::PaintInitialScreen(wxDC &dc) { int w, h, db, freq; wxString sDb, sFreq; GetClientSize(&w, &h); db = -24; freq = 0; dc.Clear(); dc.SetPen(*wxWHITE); dc.SetFont( wxFont(5, wxSWISS, wxNORMAL, wxNORMAL) ); dc.SetTextForeground( *wxWHITE ); for(int i = 15; i < w; i++) { dc.DrawLine(i, h-2, i, h); i = i + 2; } for(int i = 5; i < h-10; i++) { dc.DrawLine(0, i, 2, i); i = i + 2; } for(int i = h; i > 0; i--) { i = i - 16; if(db <= 0) { sDb.Printf("%d", db); } else { sDb.Printf("+%d", db); } dc.DrawText( sDb, 3.2f, i ); db = db + 4; } for(int i = 13; i < w; i++) { sFreq.Printf("%d", freq); dc.DrawText( sFreq, i, h-10 ); freq = i * (float)43.06640625f; i = i + 23; } } void DSPWnd::OnPaint(wxPaintEvent &WXUNUSED(event)) { wxPaintDC dc(this); PaintInitialScreen( dc ); } void DSPWnd::OnSize(wxSizeEvent &WXUNUSED(event)) { Refresh(); } MyRenderThread *DSPWnd::CreateRenderThread() { MyRenderThread *thread = new MyRenderThread(m_pFrame, this, m_pFrame->m_pControlWin); if ( thread->Create() != wxTHREAD_NO_ERROR ) { wxLogError(_T("Can't create thread!")); } wxCriticalSectionLocker enter( wxGetApp().m_critsect ); wxGetApp().m_threads.Add(thread); return thread; } void DSPWnd::StartRenderThread(void) { wxThread *thr = CreateRenderThread(); if ( thr->Run() != wxTHREAD_NO_ERROR ) { wxLogError(wxT("Can't start thread!")); } size_t n = wxGetApp().m_threads.GetCount(); if ( n == 0 ) thr->SetPriority(WXTHREAD_MIN_PRIORITY); else if ( n == 1 ) thr->SetPriority(WXTHREAD_MAX_PRIORITY); else thr->SetPriority(WXTHREAD_DEFAULT_PRIORITY); } IMPLEMENT_APP(MyApp) BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_CLOSE(MyFrame::OnClose) EVT_DROP_FILES(MyFrame::OnDrop) END_EVENT_TABLE() MyFrame::MyFrame() : wxFrame( NULL, wxID_ANY, _T("Spectrum"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCLOSE_BOX | wxFRAME_TOOL_WINDOW ) { m_pStream = NULL; data = NULL; IsQuit = false; IsFinished = false; channel = 0; FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); if (FSOUND_GetVersion() < FMOD_VERSION) { wxLogError("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return; } if(!FSOUND_Init(44100, 32, NULL)) { wxLogError("%s\n", FMOD_ErrorString(FSOUND_GetError())); return; } FSOUND_Stream_SetBufferSize(100); m_pControlWin = new ControlWin( this ); m_pRenderWin = new DSPWnd( this ); m_pPaneControl = new PaneControl( this ); DragAcceptFiles( true ); } MyFrame::~MyFrame(void) { IsQuit = true; IsFinished = true; wxThread *thread; wxGetApp().m_critsect.Enter(); const wxArrayThread& threads = wxGetApp().m_threads; size_t count = threads.GetCount(); if ( count ) { wxGetApp().m_waitingUntilAllDone = true; while ( ! threads.IsEmpty() ) { thread = threads.Last(); wxGetApp().m_critsect.Leave(); thread->Delete(); wxGetApp().m_critsect.Enter(); } } wxGetApp().m_critsect.Leave(); if ( count ) { wxGetApp().m_semAllDone.Wait(); } if( FSOUND_GetChannelsPlaying() > 0 ) FSOUND_Stream_Close(m_pStream); FSOUND_Close(); m_pControlWin->Destroy(); m_pPaneControl->Destroy(); if( data ) delete [] data; } void MyFrame::OnClose(wxCloseEvent &WXUNUSED(event)) { Destroy(); } void MyFrame::OnDrop(wxDropFilesEvent &event) { IsFinished = true; wxThread::Sleep( 5 ); wxString *arr; wxString strstream; arr = event.GetFiles(); strstream = arr[0]; PlayFile( strstream ); } void MyFrame::PlayFile(const wxString &filename) { int length; std::ifstream file; file.open(filename, std::ios::binary ); file.seekg(0, std::ios::end); length = file.tellg(); file.seekg(0, std::ios::beg); data = new char[length]; file.read(data, length); file.close(); if( FSOUND_GetChannelsPlaying() > 0 ) FSOUND_Stream_Close(m_pStream); m_pStream = FSOUND_Stream_Open(data, FSOUND_NORMAL | FSOUND_MPEGACCURATE | FSOUND_LOADMEMORY, 0, length); channel = FSOUND_Stream_PlayEx(FSOUND_FREE, m_pStream, NULL, false); if(channel == -1) { wxLogError("Invalid Channel"); return; } IsFinished = false; FSOUND_SetVolume(channel, 250); FSOUND_SetSurround(channel, true); if( wxGetApp().m_threads.IsEmpty() ) { m_pRenderWin->StartRenderThread(); m_pPaneControl->StartLevelThread(); m_pControlWin->StartControlThread(); } }

Conclusion :


pour utiliser ce programme, glisser un fichier audio sur le fenetre du spectrum...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.