// Call int fplay( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData ) { // Da wir RTAUDIO_SINT16 als Format angegeben haben, macht dieser Datentyp // Sinn ! Btw: Bei Inkompatiblen Datentypen können sich ebenfalls "interessante" // Effekte ergeben ! int16_t *buffer = (int16_t *) outputBuffer; // Daten zurückcasten ... 'reinterpret_cast' hat keine Sicherheitsbedenken und castet alles // in alles andere ! SndfileHandle *sndfile = reinterpret_cast<SndfileHandle*>(userData); // Error handling ! if ( status ){ std::cout << "Stream underflow detected!" << std::endl; } // Direkt aus der Soundfile in den OutputBuffer lesen! // Für das Beispiel reicht das, allerdings sollte man in einem 'ernsthaften' Programm // eine andere Lösung finden. Disk I/O ist auch in Zeiten der SSDs eher langsam und // sollte nicht direkt im Audio-Thread stattfinden ! // 'readf()' liest frames // 'read()' liest einzelne Samples ! // ACHTUNG! Frames != Samples // ein Frame = Samples für alle Kanäle // d.h. |Samples| = Kanäle * Frames ! sndfile->readf(buffer, nBufferFrames); return 0; }
static void create_file (const char * fname, int format) { static short buffer [BUFFER_LEN] ; SndfileHandle file ; int channels = 2 ; int srate = 48000 ; printf ("Creating file named '%s'\n", fname) ; file = SndfileHandle (fname, SFM_WRITE, format, channels, srate) ; memset (buffer, 0, sizeof (buffer)) ; const int size = srate*3; float sample[size]; float current =0; for(int i =0; i<size;i++) sample[i] = sin(float(i)/size*M_PI*1500); file.write (&sample[0], size) ; puts ("") ; /* ** The SndfileHandle object will automatically close the file and ** release all allocated memory when the object goes out of scope. ** This is the Resource Acquisition Is Initailization idom. ** See : http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization */ } /* create_file */
void ofApp::setup() { ofSetVerticalSync(true); string filename = "Serato/Serato_CD.aif";// "TraktorMK2/Traktor_MK2_Scribble.wav"; string absoluteFilename = ofToDataPath(filename, true); SndfileHandle myf = SndfileHandle(absoluteFilename.c_str()); bufferFrames = myf.frames(); int n = bufferFrames * myf.channels(); floatBuffer.resize(n); curBuffer.resize(n); myf.read(&floatBuffer[0], n); bufferPosition = 0; ttmPosition = 0; relativePosition = 0; relativeTtm.resize(ofGetWidth()); absoluteTtm.resize(ofGetWidth()); pitchTtm.resize(ofGetWidth()); string timecode = "serato_cd"; // "serato_cd" "serato_a" "traktor_a" float speed = 1.0; // 1.0 is 33 1/3, 1.35 is 45 rpm int sampleRate = 44100; // myf.samplerate() timecoder_init(&timecoder, timecode.c_str(), speed, sampleRate); //timecoder_monitor_init(&timecoder, MIXXX_VINYL_SCOPE_SIZE); bufferSize = 256; exporting = true; soundStream.setup(this, 2, 0, sampleRate, bufferSize, 4); }
void CSignalRecorder::StoreCapturedSamples(SndfileHandle &CaptureWave) { ulong capturedSamples = 0; do { capturedSamples = m_CaptureDevice->GetSamples(m_SamplesBuffer->get_Frame(0), m_FrameSize*m_MaxCaptureChannels); capturedSamples /= m_MaxCaptureChannels; if(capturedSamples > 0) { ulong writtenSamples = 0; if(m_CaptureDevice->get_InputChannelAmount() > 1) { writtenSamples = (ulong)CaptureWave.writef(m_SamplesBuffer->get_Frame(0), capturedSamples); } else { writtenSamples = (ulong)CaptureWave.write(m_SamplesBuffer->get_Frame(0), capturedSamples); } if(writtenSamples < capturedSamples) { KODI->Log(LOG_ERROR, "Failed to write to capture wave file!"); Set_State(STATE_INVALID); } } }while(capturedSamples > 0); }
static int buffer_read_verify(SndfileHandle const & sf, size_t min_length, size_t samplerate) { if (!sf) return -1; if (sf.frames() < min_length) return -2; /* no more frames to read */ if (sf.samplerate() != samplerate) return -3; /* sample rate mismatch */ return 0; }
void AudioManager::testCropping (int sId, int gId) { Sample cropped = getGroundTruthAround(sId, gId); SF_INFO sfinfo; sfinfo.channels = 1; sfinfo.samplerate = FS; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; string file = "output/cropped.wav"; cout << "Saving " << file << endl; SndfileHandle ofile = SndfileHandle(file, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 1, 8000); ofile.write(cropped.audio, cropped.length); }
//-------------------------------------------------------------- void ofxAudioSample::load(string tmpPath, float _hSampleRate) { myPath = ofToDataPath(tmpPath,true).c_str(); SndfileHandle sndFile = SndfileHandle(myPath); myFormat = sndFile.format(); myChannels = sndFile.channels(); mySampleRate = sndFile.samplerate(); resampligFactor = _hSampleRate/mySampleRate; speed = mainSpeed/resampligFactor; bufferSize = 4096 * myChannels; readBuffer = new float[bufferSize]; ofVec2f _wF; int readcount; int readpointer; // convert all multichannel files to mono by averaging the channels float monoAverage; while(readcount = sndFile.readf(readBuffer, 4096)){ readpointer = 0; _wF.set(0,0); for (int i = 0; i < readcount; i++) { // for each frame... monoAverage = 0; for(int j = 0; j < myChannels; j++) { monoAverage += readBuffer[readpointer + j]; } monoAverage /= myChannels; readpointer += myChannels; // add the averaged sample to our vector of samples samples.push_back(monoAverage); // add to the waveform data _wF.x = MIN(_wF.x, monoAverage); _wF.y = MAX(_wF.y, monoAverage); } _waveForm.push_back(_wF); } position = 0; }
void AudioManager::saveSamples () { SF_INFO sfinfo; sfinfo.channels = 1; sfinfo.samplerate = FS; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; for (vector<Sample>::iterator it = samples.begin(); it != samples.end(); ++it) { string file = "output/" + to_string(it->offset) + "-" + it->station + ".wav"; cout << "Saving " << file << endl; SndfileHandle ofile = SndfileHandle(file, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 1, 8000); ofile.write(it->audio, it->length); //sf_write_sync(ofile); //sf_close(ofile); } }
static void read_file (const char * fname) { static short buffer [BUFFER_LEN] ; SndfileHandle file ; file = SndfileHandle (fname) ; printf ("Opened file '%s'\n", fname) ; printf (" Sample rate : %d\n", file.samplerate ()) ; printf (" Channels : %d\n", file.channels ()) ; file.read (buffer, BUFFER_LEN) ; puts ("") ; /* RAII takes care of destroying SndfileHandle object. */ } /* read_file */
void Sound::initData(SndfileHandle sndFile) { nChannels = sndFile.channels(); nFrames = sndFile.frames(); int length = nChannels * nFrames; float buffer [length]; sndFile.read(buffer, length); data.resize(nChannels, std::vector<float>()); for(int channelNum = 0; channelNum < nChannels; ++channelNum) { data[channelNum].resize(nFrames, 0.0); for(int frameNum = 0; frameNum < nFrames; ++frameNum) { int i = frameNum * nChannels + channelNum; data[channelNum][frameNum] = buffer[i]; } } dataInitialized = true; }
/* * Method read input data from file */ int* read_file(string file_name, int *frames_length) { //file handler SndfileHandle inputFile; //read file from input WAV file inputFile = SndfileHandle(file_name); //get number of frames int frames = inputFile.frames(); //set input buffer int *buffer; buffer = new int[frames]; //read data from input file inputFile.read(buffer, frames); *frames_length = frames; return buffer; }
//-------------------------------------------------------------- void testApp::guiEvent(nativeWidget & widget){ ofDisableDataPath(); ofEnableDataPath(); if (widget.name == "newColor"){ float hue = ofRandom(0,255); float sat = ofRandom(190,230); float bri = ofRandom(220,238); color.setHsb(hue, sat, bri); } if (widget.name == "repeatSound"){ if (audioSamples.size() > 0){ counter = 0; bPlaying = true; } } if (widget.name == "textBox" || widget.name == "textBox2" || widget.name == "textBox3" ){ string time = ofGetTimestampString(); string fileName = time + ".aiff"; string fileNameMp3 = time + ".mp3"; string toSay = *((string *)widget.variablePtr); string command = "say -o " + ofToDataPath(fileName) + " " + "\"" + toSay + "\"" + " --data-format=BEI32@44100"; // big endian int 32 bit samples 44100 sample rate system(command.c_str()); ofSleepMillis(100); // sometimes really long files need time to save out. SndfileHandle myf = SndfileHandle(ofToDataPath(fileName).c_str()); float * data = new float[int(myf.frames())]; myf.read (data, int(myf.frames())); audioSamples.clear(); audioSamples.reserve(int(myf.frames())); for (int i = 0; i < int(myf.frames()); i++){ audioSamples.push_back(data[i]); } delete [] data; bPlaying = true; counter = 0; } computeMessageColors(); }
/** General loading function. This is used by the both the load Samples and load Groundtruth */ void AudioManager::loadFiles (string dirname, vector<Sample> &into) { vector<string> filenames = list_all_files(dirname); for (vector<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) { string filename = *it; if (filename.find(".wav") == string::npos) continue; Sample sample; SndfileHandle ff = SndfileHandle(filename); assert(ff.channels() == 1); assert(ff.samplerate() == 8000); double * signal = new double [ff.frames()]; ff.read(signal, ff.frames()); sample.station = ""; sample.offset = 0; sample.filename = filename; sample.audio = signal; sample.length = ff.frames(); into.push_back(sample); } }
int main () { // Damit das Programm funktioniert, muss eine 16Bit PCM Wave-Datei im // gleichen Ordner liegen ! const char * fname = "test.flac" ; // Soundfile-Handle aus der libsndfile-Bibliothek SndfileHandle file = SndfileHandle (fname) ; // Alle möglichen Infos über die Audio-Datei ausgeben ! std::cout << "Reading file: " << fname << std::endl; std::cout << "File format: " << file.format() << std::endl; std::cout << "PCM 16 BIT: " << (SF_FORMAT_WAV | SF_FORMAT_PCM_16) << std::endl; std::cout << "Samples in file: " << file.frames() << std::endl; std::cout << "Samplerate " << file.samplerate() << std::endl; std::cout << "Channels: " << file.channels() << std::endl; // Die RtAudio-Klasse ist gleichermassen dac und adc, wird hier aber nur als dac verwendet ! RtAudio dac; if ( dac.getDeviceCount() < 1 ) { std::cout << "\nNo audio devices found!\n"; return 0; } // Output params ... RtAudio::StreamParameters parameters; parameters.deviceId = dac.getDefaultOutputDevice(); parameters.nChannels = 2; parameters.firstChannel = 0; unsigned int sampleRate = 44100; // ACHTUNG! Frames != Samples // ein Frame = Samples für alle Kanäle // d.h. |Samples| = Kanäle*Frames ! unsigned int bufferFrames = 1024; // Da wir 16 Bit PCM-Daten lesen, sollte als Datenformat RTAUDIO_SINT16 genutzt // werden. // Als Daten wird der Callback-Struktur hier das Soundfile-Handle übergeben. // Sollte man in einer "ernsthaften" Lösung anders machen ! // Inkompatible Formate können übrigens "interessante" Effekte ergeben ! try { dac.openStream( ¶meters, NULL, RTAUDIO_SINT16, sampleRate, &bufferFrames, &fplay, (void *)&file); dac.startStream(); } catch ( RtAudioError& e ) { e.printMessage(); return 0; } char input; std::cout << "\nPlaying ... press <enter> to quit.\n"; std::cin.get( input ); try { // Stop the stream dac.stopStream(); } catch (RtAudioError& e) { e.printMessage(); } if ( dac.isStreamOpen() ) dac.closeStream(); return 0 ; }
int main(int argc, char** argv) { if (argc != 2) { printHelp(); return EXIT_FAILURE; } SndfileHandle inputFile; inputFile = SndfileHandle(argv[1]); int framesCount = inputFile.frames(); int *buffer; buffer = new int[framesCount]; inputFile.read(buffer, inputFile.frames()); #ifdef DEBUG cerr<<"Samples size: "<<framesCount<<endl; #endif double firstAngle; double deltaAngle; string decoded = ""; /* finding angle of a sin between two samples in the input signal */ firstAngle = asin(((double)buffer[0]) / AMPLITUDE); deltaAngle = asin(((double)buffer[1]) / AMPLITUDE) - firstAngle; #ifdef DEBUG cerr<<"deltaAngle: "<<deltaAngle<<" = "<<deltaAngle*180/PI<<"°"<<endl; #endif double actAngle = firstAngle; double deltaX1 = deltaAngle; double deltaX4 = deltaAngle; /* QPSK bauds mapping values */ double expectedAngle1 = addAngle(0, 3*PI/4.0); double expectedAngle2 = addAngle(0, PI/4.0); double expectedAngle3 = addAngle(0, 5*PI/4.0); double expectedAngle4 = addAngle(0, 7*PI/4.0); int changes = 0; int firstChange = 0; int secondChange = 0; int thirdChange = 0; double expectedAngle1b = addNormalize(0, expectedAngle1); double expectedAngle4b = addNormalize(0, expectedAngle4); double *expectedAngle = &expectedAngle1b; /* while 3 changes in sync part of the signal signal */ while (changes < 3) { #ifdef DEBUG cerr<<"loop: "<<thirdChange<<endl; cerr<<"actAngle: "<<actAngle<<" = "<<actAngle*180/PI<<"° "<<sin(actAngle)<<endl; cerr<<"expected: "<<*expectedAngle<<" = "<<*expectedAngle*180/PI<<"° "<<sin(*expectedAngle)<<endl; #endif /* we have a change in a baud */ if (!((actAngle > *expectedAngle - (PI/20))&&(actAngle < *expectedAngle + (PI/20)))) { if (changes == 0) { expectedAngle = &expectedAngle4b; } else if (changes == 1) { expectedAngle = &expectedAngle1b; } changes++; } /* counting samples till first change */ if (changes < 1) { firstChange++; } /* counting samples till second change */ if (changes < 2) { secondChange++; } /* counting samples till third change */ if (changes < 3) { thirdChange++; } /* thirdChange is also a counter for this loop */ actAngle = asin(((double)buffer[thirdChange]) / AMPLITUDE); expectedAngle1b = addNormalizeChangeDelta(expectedAngle1b, &deltaX1); expectedAngle4b = addNormalizeChangeDelta(expectedAngle4b, &deltaX4); } /* preparing values for voting */ secondChange /= 2; thirdChange /=3; int samplesPerBaud = 0; /* voting for samles per baud... we should have at least 2 same * values to claim it as a samples per baud */ if (firstChange == secondChange) { samplesPerBaud = firstChange; } else if (secondChange == thirdChange) { samplesPerBaud = secondChange; } else if (firstChange == thirdChange) { samplesPerBaud = firstChange; } #ifdef DEBUG cerr<<"SPB: "<<samplesPerBaud<< " 1st: "<<firstChange<<" 2nd: "<<secondChange<<" 3rd: "<<thirdChange<<endl; #endif double res1 = 0; double res2 = 0; double res3 = 0; double res4 = 0; /* Iteraes through the all samples. For each baud we are looking * for the sin values that differs the least from actual baud */ for (int i = 0, s = samplesPerBaud; i < framesCount; i++, s--) { /* counting differences for each sin */ res1 += fabs(buffer[i] - sin(expectedAngle1)); res2 += fabs(buffer[i] - sin(expectedAngle2)); res3 += fabs(buffer[i] - sin(expectedAngle3)); res4 += fabs(buffer[i] - sin(expectedAngle4)); /* we have processed a baud and we are looking for the * least change */ if (s == 0 || i == framesCount-1) { s = samplesPerBaud; double res12; double res34; int resId12 = 0; int resId34 = 0; if (res1 < res2) { res12 = res1; resId12 = 1; } else { res12 = res2; resId12 = 2; } if (res3 < res4) { res34 = res3; resId34 = 3; } else { res34 = res4; resId34 = 4; } int resId; if (res12 < res34) { resId = resId12; } else { resId = resId34; } switch(resId) { case 1: decoded += "00"; break; case 2: decoded += "01"; break; case 3: decoded += "10"; break; case 4: decoded += "11"; break; default: break; } res1 = 0; res2 = 0; res3 = 0; res4 = 0; } expectedAngle1 = addAngle(expectedAngle1, -deltaAngle); expectedAngle2 = addAngle(expectedAngle2, -deltaAngle); expectedAngle3 = addAngle(expectedAngle3, -deltaAngle); expectedAngle4 = addAngle(expectedAngle4, -deltaAngle); } #ifdef DEBUG cerr<<decoded<<endl; cerr<<decoded.substr(8); #endif /* writting to an output file */ string outName = string(argv[1]); outName = outName.replace(outName.end()-3, outName.end(), "txt"); ofstream outFile(outName); if (!outFile.is_open()) { cerr<<"Can not open output file\n"; return EXIT_FAILURE; } outFile<<decoded.substr(8); outFile.close(); delete [] buffer; return EXIT_SUCCESS; }