Imitiert die WAVEHDR-Eingabe, um ein Spektrogramm aus einer Datei zu streamenC++

Programme in C++. Entwicklerforum
Guest
 Imitiert die WAVEHDR-Eingabe, um ein Spektrogramm aus einer Datei zu streamen

Post by Guest »

Ich habe Code, der Eingaben vom Mikrofon entgegennimmt und das Spektrogramm über OpenCV streamt. Das funktioniert gut:

Code: Select all

while (cv::waitKey(10) != 27) {

waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));              /* Prepare header for input         */
if (waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR))) return -1;   /* Insert a wave input buffer       */
if (waveInStart(hWaveIn)) return -1;                                    /* Commence sampling input          */
/* Wait until finished recording    */
do {} while (waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);

addInput(WaveInHdr);
cv::imshow("Spectrogram", spectrogram.getDetailedSpectrogram(20, cv::COLORMAP_JET));
}
Die obige Eingabe vom Mikrofon wird über die Funktion „addInput“ verarbeitet. Dann wird es einer Short-Time-Fourier-Transformation unterzogen und wie folgt in einzelne Spaltenvektoren zerlegt:

Code: Select all

hconcat(line, spectrogram->colRange(0, spectrogram->cols - 1), *spectrogram);
Ich wollte das Gleiche tun können, aber mit Spannungsamplituden, die in einer CSV-Datei aufgezeichnet wurden. Ich kann die Spektrogramme grafisch darstellen, bin mir aber nicht sicher, wie ich sie „streamen“ soll.
Im Grunde versuche ich, das zu tun, was der Mikrofoncode tut, nämlich die Daten zu streamen anstatt nur einen einzelnen Plot zu erstellen, und ich bin mir nicht sicher, wie ich das aus einer Datei machen soll. Ursprünglich wollte ich versuchen, die WAVEHDR-Klasse nachzuahmen, den Mikrofoncode wiederzuverwenden und meinen Amplitudenvektor irgendwie in lpData umzuwandeln, aber das scheint viel zu kompliziert zu sein.
(Hinweis: Der Code Das Spektrogramm, das ich für das Mikrofon verwende, wurde von https://github.com/njanakiev/audio-spectrogram angepasst)
Bearbeiten: Ich versuche, lpData mit meiner Amplitude in Einklang zu bringen Vektor:

Code: Select all

void FileStream::read_file(std::string filePath, size_t bufferSize) {

std::ifstream file;
file.open(filePath);
std::vector times, x;
char* chBuffer = new char[bufferSize];
while (file)
{
file.read(chBuffer, bufferSize);
auto bytesRead = file.gcount();
if (bytesRead == 0) {
break;
}

std::string str = chBuffer;
int beg = 0, end = 0;
while (end = str.find('\n', beg + 1))
{
std::string input_str = str.substr(beg, end - beg);
int pos = input_str.find_first_of(' ');
double amplitude = std::atof((input_str.substr(pos + 1)).c_str());
if (end == -1)
{
x.push_back(amplitude);
std::copy(x.begin(), x.end(), samples);
get_sample(32e3, 1);
x.clear();
break;
}
x.push_back(amplitude);
beg = end;
}
}
}
Und die get_sample-Funktion

Code: Select all

int FileStream::get_sample(int fs, int channels)
{
using namespace little_endian_io;
const int bitDepth = 16;
std::ofstream f("example.wav", std::ios::binary);

// Write the file headers
f

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post