J’utilise l’API Windows pour obtenir une entrée audio. J’ai suivi toutes les étapes sur MSDN et j’ai réussi à enregistrer de l’audio dans un fichier WAV. Aucun problème. J’utilise plusieurs tampons et tout ça. Je voudrais faire plus avec les tampons que simplement écrire dans un fichier, donc maintenant j’ai un callback configuré. Cela fonctionne très bien et j’obtiens les données, mais je ne sais pas quoi en faire une fois que je les ai.
Voici mon rappel … tout fonctionne ici:
// Media API callback void CALLBACK AudioRecorder::waveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { // Data received if (uMsg == WIM_DATA) { // Get wav header LPWAVEHDR mBuffer = (WAVEHDR *)dwParam1; // Now what? for (unsigned i = 0; i != mBuffer->dwBytesRecorded; ++i) { // I can see the char, how do get them into my file and audio buffers? cout <lpData[i] << "\n"; } // Re-use buffer mResultHnd = waveInAddBuffer(hWaveIn, mBuffer, sizeof(mInputBuffer[0])); // mInputBuffer is a const WAVEHDR * } } // waveInOpen cannot use an instance method as its callback, // so we create a static method which calls the instance version void CALLBACK AudioRecorder::staticWaveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { // Call instance version of method reinterpret_cast(dwParam1)->waveInProc(hWaveIn, uMsg, dwInstance, dwParam1, dwParam2); }
Comme je l’ai dit, cela fonctionne très bien, mais j’essaie de faire ce qui suit:
J’ai beaucoup travaillé avec FMOD et je suis familier avec l’entrelacement et tout ça. Mais le FMOD fait tout pour devenir des flotteurs. Dans ce cas, je vais dans l’autre sens. Je suppose que je cherche essentiellement des ressources sur comment passer du LPSTR au caractère court, flottant et non signé.
Merci beaucoup d’avance!
typedef struct { LPSTR lpData; // etc.. } WAVEHDR;
Hmya, type maladroit là-bas. Ce n’est pas une STR bien sûr, cela aurait dû être un PVOID. Il suffit de le lancer sur le type dont vous avez besoin:
short* data = (short*)(mBuffer->lpData); unsigned samples = mBuffer->dwBytesRecorded / sizeof(short); // etc..
J’ai fait tout cela mais c’est juste trop d’informations pour tout expliquer en détail ici. Je vous suggère de regarder le code source de PortAudio : c’est une très bonne implémentation de MME, bien que certaines parties soient un peu trop compliquées à mon goût, mais elles contiennent tout ce que vous recherchez, y compris les conversions.
Tableau de conversion 8/16/32 bits / échantillon en float-array:
void src_BYTE_to_float_array(const unsigned char* in, float* out, int len) { while (len) { len--; out[len]= (float) (in [len] / (1.0 * 0x80) -1.0); } } void src_short_to_float_array(const short* in, float* out, int len) { while (len) { len--; out[len]= (float) (in [len] / (1.0 * 0x8000)) ; } } void src_int_to_float_array(const int* in, float* out, int len) { while (len) { len--; out[len]= (float) (in [len] / (8.0 * 0x10000000)) ; } }
Pour jouer les samples, vous devrez faire le contraire:
void src_float_to_BYTE_array(const float* in, unsigned char* out, int len) { double scaled_value; while (len) { len--; scaled_value= in[len] * (8.0 * 0x10000000); if (scaled_value >= (1.0 * 0x7FFFFFFF)) { out[len]= 255; continue ; } out[len]= (unsigned char)((lrint(scaled_value) >> 24) + 0x80); } } void src_float_to_short_array(const float* in, short* out, int len) { double scaled_value; while (len) { len--; scaled_value= in[len] * (8.0 * 0x10000000); if (scaled_value >= (1.0 * 0x7FFFFFFF)) { out[len]= 32767; continue ; } out[len]= (short)(lrint(scaled_value) >> 16); } } void src_float_to_int_array(const float* in, int* out, int len) { double scaled_value; while (len) { len--; scaled_value= in[len] * (8.0 * 0x10000000); if (scaled_value >= (1.0 * 0x7FFFFFFF)) { out[len]= 0x7fffffff; continue; } out[len]= lrint(scaled_value); } }