J'essaie de créer une application de la musique Visualizer à Portaudo, j'ai fait des recherches de base et j'ai trouvé quelques exemples sur la manière d'enregistrer à partir d'un micro à un fichier (temporaire). Mais il n'y avait aucun exemple si les données ne sont pas utilisées du temps d'exécution pendant l'enregistrement.
Alors, comment puis-je démarrer un audio-flux continu où je peux attraper les données du "cadre" actuel? P>
Ceci C'est comme ça que j'ai essayé de le faire: p> mais il donne la sortie suivante: p>
4 Réponses :
update em>: Quel est le but de ce code? p> static void* data;
/* ... */
static int recordCallback(const void* inputBuffer, void* outputBuffer, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData){
testData* data = (testData*)userData;
/* ... */
}
Merci de pointer ces erreurs, j'ai essayé de les réparer le mieux que je pouvais, mais l'erreur reste toujours; Je ne pense pas que cela ait quelque chose à voir avec la répartition de la mémoire, car maintenant (voir la question mise à jour), je reçois toujours l'erreur de flux actif : impossible de lire à partir d'un flux de rappel code> Erreur. Donc, il se casse sur l'appel code> Pa_GetstreamReadAnter CODE>, mais j'ai un microphone utilisable connecté à mon ordinateur. J'aimerais également que l'alternative d'utiliser le son mon propre ordinateur envoie en tant que sortie.
Je n'avais pas le temps de vérifier votre réponse, mais depuis que le temps pour les points est presque terminé, je vous l'accorderai; Je vais vérifier plus tard ce jour!
Eh bien, faites-moi savoir comment cela fonctionne ... Je n'aime pas beaucoup Alsa, mais je suis toujours heureux d'apprendre. Je vais vous aider à comprendre ce qui ne va pas ...
Ah j'ai finalement eu une demi-heure à regarder, ça va à la boucle quand je suppose cette déclaration; Mais je n'ai aucune idée de comment obtenir les données, lorsque j'ajouterai fprintf (stardr, "flux:% s \ n", données-> enregistrements d'enregistrement); code> à la fonction RecordCallback i obtenez
: H� $ � # code> une fois, et quand je l'ajoutez à la boucle tandis que cela reste vide!
@THOMASVERSTEEG Y a-t-il des preuves pour suggérer que Data-> enregistrements d'enregistrement code> pointe sur une chaîne (c'est-à-dire qu'il est garanti d'être
'\ 0' code> terminé)? Sinon, alors
% s code> n'est peut-être pas le spécificateur de format correct. Peut-être que ces données pourraient contenir des octets non imprimables, vous voudrez peut-être le jeter comme hexagonal:
FPRINTF (STDRERR, "Stream:"); pour (x = 0; x
J'ai essayé d'ajouter votre morceau de code sur divers endroits de mon code source mais tout ce que je reçois est un flux vide: code>; Et quand je l'ajoute dans la boucle tandis que
Pa_sleep () Code> Je reçois un flux complet de
flux: code> et il quitte le code 139 (Segfault).
Vous avez fermé le flux err = pa_closetream (flux); code> dans la première itération. Dans la deuxième itération, la chaîne était déjà fermée. Essayez l'opération
err = pa_closetream (flux); code> après toutes les itérations. P>
Lorsque je retire la ligne, vous avez souligné, je ne reçois toujours pas les données.
Pour interagir avec le flux de données en temps réel, vous aurez besoin d'un mécanisme qui dort (occupé attend des fenêtres) pour la période de trame (taux d'échantillonnage / échantillons par image) ou utilise une primitive de synchronisation de fil pour déclencher votre fil Int Main Code> qu'il y a de l'audio prêt à être traité. Cela vous donnera accès à chaque image de données que Portudio fournit lors de son rappel (appelé à partir du fil de Portudio). Voici comment le concept fonctionne à l'aide de Boost :: Condition code> et
Boost :: Mutex code>.
//CAUTION THIS SNIPPET IS ONLY INTENDED TO DEMONSTRATE HOW ONE MIGHT
//SYNCHRONIZE WITH THE PORTAUDIO THREAD
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include "portaudio.h"
boost::condition waitForAudio;
boost::mutex waitForAudioMutex;
boost::mutex audioBufferMutex;
bool trigger = false;
std::deque<char> audioBuffer;
static int recordCallback(const void* inputBuffer, void* outputBuffer, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData){
const char* buffer_ptr = (const char*)inputBuffer;
//Lock mutex to block user thread from modifying data buffer
audioBufferMutex.lock();
//Copy data to user buffer
for(i = 0; i < frameCount; ++i) {
audioBuffer.push_back(buffer_ptr + i);
}
//Unlock mutex, allow user to manipulate buffer
audioBufferMutex.unlock();
//Signal user thread to process audio
waitForAudioMutex.lock();
trigger= true;
waitForAudio.notify_one();
waitForAudioMutex.unlock();
return finished;
}
int main(){
Pa_Initialize();
//OPEN AND START PORTAUDIO STREAM
while(true){ //Catch signal (Ctrl+C) or some other mechanism to interrupt this loop
boost::xtime duration;
boost::xtime_get(&duration, boost::TIME_UTC);
boost::interprocess::scoped_lock<boost::mutex> lock(waitForAudioMutex);
if(!trigger) {
if(!waitForAudio.timed_wait(lock, duration)) {
//Condition timed out -- assume audio stream failed
break;
}
}
trigger= false;
audioBufferMutex.lock();
//VISUALIZE AUDIO HERE
//JUST MAKE SURE TO FINISH BEFORE PORTAUDIO MAKES ANOTHER CALLBACK
audioBufferMutex.unlock();
}
//STOP AND CLOSE PORTAUDIO STEAM
Pa_Terminate();
return 0;
}
@Ashishk Quel est ton doute?
HI @Trukvl Demandez votre suggestion sur cette option s'il vous plaît ( Stackoverflow.com/Questtions/44645466/... )
J'ai résolu de cette façon:
PaStreamParameters inputParameters ,outputParameters; PaStream* stream; PaError err; paTestData data; int i; int totalFrames; int numSamples; int numBytes; err = paNoError; inputParameters.device = 4; data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; data.frameIndex = 0; numSamples = totalFrames * NUM_CHANNELS; numBytes = numSamples * sizeof(SAMPLE); data.recordedSamples = (SAMPLE *) malloc( numBytes ); std::ofstream arch; arch.open("signal.csv"); err = Pa_Initialize(); inputParameters.channelCount = 1; inputParameters.sampleFormat = PA_SAMPLE_TYPE; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; int contador = 0; bool strec = true; while (strec) { err = Pa_OpenStream( &stream, &inputParameters, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, recordCallback, &data ); err = Pa_StartStream( stream ); printf("\n===Grabando.... ===\n"); fflush(stdout); Pa_Sleep(3000); while( ( err = Pa_IsStreamActive(stream) ) == 1 ) { } err = Pa_CloseStream( stream ); for( i=0; i<numSamples; i++ ) { val = data.recordedSamples[i]; arch << val << std::endl; std::cout << std::endl << "valor : " << val; } data.frameIndex = 0; contador++; if (contador >= 100) //if you delete this condition continuously recorded this audio { strec = false; arch.close(); } }
Sur quelle plate-forme travaillez-vous?
Je travaille sur Debian Linux (64 bits)