[ fmodex | wxwidgets ] capturer l'output audio + écriture dans un wav

Description

voila, suite a une grosse prise de tete pour effectuer cette opération, je vous propose ce morceau de code qui en ravira plus d' un j' espere;

l'enregistrement est limité a 30s mais on peut en changer ( c'est pour les user du site dont je fais partie, pas plus de 30s sinon taitai la SACEM ), un fichier wav est écrit en sortie de programme, il contient la capture enregistrée;

voila, c'est juste un mini exemple, pas un projet, je me garde les mp3 et tout le tralala, lol;

Enjoy

Source / Exemple :


#include "recorder.h"
#include <cstdio>

#define __PACKED 

MyApp::MyApp()
{
}

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame;

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

BEGIN_EVENT_TABLE(MyFrame, wxFrame)

	EVT_CLOSE(MyFrame::OnClose)
	EVT_TIMER(wxID_ANY, MyFrame::OnTimer)
	EVT_BUTTON(wxID_ANY, MyFrame::OnClickStart)

END_EVENT_TABLE()

MyFrame::MyFrame() : wxFrame(   NULL, 
							    wxID_ANY, 
								_T("Spectrum"), 
								wxDefaultPosition, 
								wxSize(220, 100), 
								wxCAPTION      |
								wxTHICK_FRAME  |
								wxMINIMIZE_BOX |
								wxSTAY_ON_TOP  |
								wxSYSTEM_MENU  | 
								wxCLOSE_BOX    |
								wxFRAME_TOOL_WINDOW	)
{
	StartBtn = new wxButton(this, wxID_ANY, "START");
	InitSoundSystem();
	timer.SetOwner(this, wxID_ANY);
	timer.Start( 10 );
}

MyFrame::~MyFrame(void)
{

}

void MyFrame::InitSoundSystem(void)
{
	sound = NULL;
	system = NULL;

	result = FMOD::System_Create(&system);
	if (result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	result = system->setDriver(0);
	if(result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	result = system->setSoftwareChannels(100);
	if(result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	result = system->setHardwareChannels(32, 64, 32, 64);
	if( result != FMOD_OK )
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	result = system->setOutput(FMOD_OUTPUTTYPE_DSOUND);
	if (result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	result = system->init(200, FMOD_INIT_NORMAL, NULL);
	if (result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}
	result = system->setRecordDriver(0);
	if(result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}
    char name[256];

    result = system->getRecordDriverName(0, name, 256);

	wxLogDebug( name );

	memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));

    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.numchannels      = 1;
    exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
    exinfo.defaultfrequency = 44100;
    exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 30;// 30 s
    
    result = system->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound);
	if (result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}
}

void MyFrame::OnClose(wxCloseEvent &WXUNUSED(event))
{
	system->recordStop();
	timer.Stop();

	SaveToWav( sound );

	Destroy();
}

void MyFrame::OnTimer(wxTimerEvent &WXUNUSED(event))
{
    unsigned int recordpos = 0;
    unsigned int length;

    sound->getLength(&length, FMOD_TIMEUNIT_PCM);
	system->getRecordPosition(&recordpos);

	wxString str;
	str.Printf("durée :%i s, pos: %i s", length, recordpos);

	wxLogDebug(str);
	SetTitle( str );
}

void MyFrame::OnClickStart(wxCommandEvent &WXUNUSED(event))
{
	result = system->recordStart(sound, false);
	if (result != FMOD_OK)
	{
		wxLogError("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
		return;
	}

	sound->setMode(FMOD_LOOP_NORMAL);
}

// Fonction empruntée a FMOD ( thanks )
void MyFrame::SaveToWav(FMOD::Sound *sound)
{
    FILE *fp;
    int             channels, bits;
    float           rate;
    void           *ptr1, *ptr2;
    unsigned int    lenbytes, len1, len2;

    if (!sound)
    {
        return;
    }

    sound->getFormat  (0, 0, &channels, &bits);
    sound->getDefaults(&rate, 0, 0, 0);
    sound->getLength  (&lenbytes, FMOD_TIMEUNIT_PCMBYTES);

    {
        #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
        #pragma pack(1)
        #endif
        
        /*
            WAV Structures

  • /
typedef struct { signed char id[4]; int size; } RiffChunk; struct { RiffChunk chunk __PACKED; unsigned short wFormatTag __PACKED; /* format type */ unsigned short nChannels __PACKED; /* number of channels (i.e. mono, stereo...) */ unsigned int nSamplesPerSec __PACKED; /* sample rate */ unsigned int nAvgBytesPerSec __PACKED; /* for buffer estimation */ unsigned short nBlockAlign __PACKED; /* block size of data */ unsigned short wBitsPerSample __PACKED; /* number of bits per sample of mono data */ } FmtChunk = { {{'f','m','t',' '}, sizeof(FmtChunk) - sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits } __PACKED; struct { RiffChunk chunk; } DataChunk = { {{'d','a','t','a'}, lenbytes } }; struct { RiffChunk chunk; signed char rifftype[4]; } WavHeader = { {{'R','I','F','F'}, sizeof(FmtChunk) + sizeof(RiffChunk) + lenbytes }, {'W','A','V','E'} }; #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) #pragma pack() #endif fp = fopen("record.wav", "wb"); /* Write out the WAV header.
  • /
fwrite(&WavHeader, sizeof(WavHeader), 1, fp); fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp); fwrite(&DataChunk, sizeof(DataChunk), 1, fp); /* Lock the sound to get access to the raw data.
  • /
sound->lock(0, lenbytes, &ptr1, &ptr2, &len1, &len2); /* Write it to disk.
  • /
fwrite(ptr1, len1, 1, fp); /* Unlock the sound to allow FMOD to use it again.
  • /
sound->unlock(ptr1, ptr2, len1, len2); fclose(fp); } }

Conclusion :


-- rien a dire sinon, qu'il faut appuyer sur le bouton pour capturer

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.