3737// --------------------------------------------------------------
3838SoundfilePlayer::SoundfilePlayer () : PatchObject(" soundfile player" ){
3939
40- this ->numInlets = 5 ;
40+ this ->numInlets = 7 ;
4141 this ->numOutlets = 3 ;
4242
4343 _inletParams[0 ] = new string (); // control
@@ -48,8 +48,12 @@ SoundfilePlayer::SoundfilePlayer() : PatchObject("soundfile player"){
4848 *(float *)&_inletParams[2 ] = 0 .0f ;
4949 _inletParams[3 ] = new float (); // volume
5050 *(float *)&_inletParams[3 ] = 0 .0f ;
51- _inletParams[4 ] = new float (); // trigger
51+ _inletParams[4 ] = new float (); // cue IN
5252 *(float *)&_inletParams[4 ] = 0 .0f ;
53+ _inletParams[5 ] = new float (); // cue OUT
54+ *(float *)&_inletParams[5 ] = 0 .0f ;
55+ _inletParams[6 ] = new float (); // trigger
56+ *(float *)&_inletParams[6 ] = 0 .0f ;
5357
5458 _outletParams[0 ] = new ofSoundBuffer (); // signal
5559 _outletParams[1 ] = new vector<float >(); // audio buffer
@@ -95,6 +99,8 @@ void SoundfilePlayer::newObject(){
9599 this ->addInlet (VP_LINK_NUMERIC," playhead" );
96100 this ->addInlet (VP_LINK_NUMERIC," speed" );
97101 this ->addInlet (VP_LINK_NUMERIC," volume" );
102+ this ->addInlet (VP_LINK_NUMERIC," cue in" );
103+ this ->addInlet (VP_LINK_NUMERIC," cue out" );
98104 this ->addInlet (VP_LINK_NUMERIC," bang" );
99105
100106 this ->addOutlet (VP_LINK_AUDIO," audioFileSignal" );
@@ -200,6 +206,16 @@ void SoundfilePlayer::updateObjectContent(map<int,shared_ptr<PatchObject>> &patc
200206 volume = ofClamp (*(float *)&_inletParams[3 ],0 .0f ,1 .0f );
201207 }
202208
209+ // cue IN
210+ if (this ->inletsConnected [4 ]){
211+ cueIN = static_cast <double >(ofClamp (*(float *)&_inletParams[4 ],0.0 ,cueOUT-2 ));
212+ }
213+
214+ // cue OUT
215+ if (this ->inletsConnected [5 ]){
216+ cueOUT = static_cast <double >(ofClamp (*(float *)&_inletParams[5 ],cueIN+2 , audiofile.length ()-2 ));
217+ }
218+
203219 // outlet finish bang
204220 if (finishBang){
205221 *(float *)&_outletParams[2 ] = 1 .0f ;
@@ -268,17 +284,23 @@ void SoundfilePlayer::drawObjectNodeGui( ImGuiEx::NodeCanvas& _nodeCanvas ){
268284 // draw player state
269285 if (isPlaying){ // play
270286 _nodeCanvas.getNodeDrawList ()->AddTriangleFilled (ImVec2 (window_pos.x +window_size.x -(50 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(40 *_nodeCanvas.GetCanvasScale ())), ImVec2 (window_pos.x +window_size.x -(50 *_nodeCanvas.GetCanvasScale ()), window_pos.y +window_size.y -(20 *_nodeCanvas.GetCanvasScale ())), ImVec2 (window_pos.x +window_size.x -(30 *_nodeCanvas.GetCanvasScale ()), window_pos.y +window_size.y -(30 *_nodeCanvas.GetCanvasScale ())), IM_COL32 (255 , 255 , 255 , 120 ));
271- }else if (!isPlaying && playhead > 0.0 ){ // pause
287+ }else if (!isPlaying && playhead > cueIN ){ // pause
272288 _nodeCanvas.getNodeDrawList ()->AddRectFilled (ImVec2 (window_pos.x +window_size.x -(50 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(40 *_nodeCanvas.GetCanvasScale ())),ImVec2 (window_pos.x +window_size.x -(42 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(20 *_nodeCanvas.GetCanvasScale ())),IM_COL32 (255 , 255 , 255 , 120 ));
273289 _nodeCanvas.getNodeDrawList ()->AddRectFilled (ImVec2 (window_pos.x +window_size.x -(38 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(40 *_nodeCanvas.GetCanvasScale ())),ImVec2 (window_pos.x +window_size.x -(30 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(20 *_nodeCanvas.GetCanvasScale ())),IM_COL32 (255 , 255 , 255 , 120 ));
274- }else if (!isPlaying && playhead == 0.0 ){ // stop
290+ }else if (!isPlaying && playhead == cueIN ){ // stop
275291 _nodeCanvas.getNodeDrawList ()->AddRectFilled (ImVec2 (window_pos.x +window_size.x -(50 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(40 *_nodeCanvas.GetCanvasScale ())),ImVec2 (window_pos.x +window_size.x -(30 *_nodeCanvas.GetCanvasScale ()),window_pos.y +window_size.y -(20 *_nodeCanvas.GetCanvasScale ())),IM_COL32 (255 , 255 , 255 , 120 ));
276292 }
277293
278294 // draw playhead
279295 float phx = ofMap ( playhead, 0 , audiofile.length ()*0 .98f , 1 , (this ->width *0 .98f *_nodeCanvas.GetCanvasScale ())-(31 *this ->scaleFactor ) );
280296 _nodeCanvas.getNodeDrawList ()->AddLine (ImVec2 (ph_pos.x + phx, ph_pos.y ),ImVec2 (ph_pos.x + phx, window_size.y +ph_pos.y -(26 *this ->scaleFactor )),IM_COL32 (255 , 255 , 255 , 160 ), 2 .0f );
281297
298+ // draw cues IN OUT
299+ float cinx = ofMap ( cueIN, 0 , audiofile.length ()*0 .98f , 1 , (this ->width *0 .98f *_nodeCanvas.GetCanvasScale ())-(31 *this ->scaleFactor ) );
300+ _nodeCanvas.getNodeDrawList ()->AddLine (ImVec2 (ph_pos.x + cinx, ph_pos.y ),ImVec2 (ph_pos.x + cinx, window_size.y +ph_pos.y -(26 *this ->scaleFactor )),IM_COL32 (255 , 0 , 0 , 160 ), 2 .0f );
301+ float coutx = ofMap ( cueOUT, 0 , audiofile.length ()*0 .98f , 1 , (this ->width *0 .98f *_nodeCanvas.GetCanvasScale ())-(31 *this ->scaleFactor ) );
302+ _nodeCanvas.getNodeDrawList ()->AddLine (ImVec2 (ph_pos.x + coutx, ph_pos.y ),ImVec2 (ph_pos.x + coutx, window_size.y +ph_pos.y -(26 *this ->scaleFactor )),IM_COL32 (255 , 0 , 0 , 160 ), 2 .0f );
303+
282304 }else if (loadingFile){
283305 ImGui::Text (" LOADING FILE..." );
284306 }else if (!isNewObject && !audiofile.loaded ()){
@@ -327,14 +349,14 @@ void SoundfilePlayer::drawObjectNodeConfig(){
327349 ImGui::PushStyleColor (ImGuiCol_ButtonActive, VHS_BLUE_OVER);
328350 if (ImGui::Button (ICON_FA_PLAY,ImVec2 (69 *scaleFactor,26 *scaleFactor))){
329351 isPlaying = true ;
330- playhead = 0.0 ;
352+ playhead = cueIN ;
331353 audioWasPlaying = true ;
332354 finishSemaphore = true ;
333355 }
334356 ImGui::SameLine ();
335357 if (ImGui::Button (ICON_FA_STOP,ImVec2 (69 *scaleFactor,26 *scaleFactor))){
336358 isPlaying = false ;
337- playhead = 0.0 ;
359+ playhead = cueIN ;
338360 audioWasPlaying = false ;
339361 }
340362 ImGui::PopStyleColor (3 );
@@ -356,6 +378,24 @@ void SoundfilePlayer::drawObjectNodeConfig(){
356378 ImGui::Spacing ();
357379 ImGui::Checkbox (" LOOP " ICON_FA_REDO,&loop);
358380
381+ ImGui::Spacing ();
382+ float tempcueIN = cueIN;
383+ if (ImGui::SliderFloat (" CUE IN" ,&tempcueIN,0.0 , cueOUT-2 )){
384+ cueIN = static_cast <double >(tempcueIN);
385+ if (playhead < cueIN){
386+ playhead = cueIN;
387+ }
388+
389+ }
390+ ImGui::Spacing ();
391+ float tempcueOUT = cueOUT;
392+ if (ImGui::SliderFloat (" CUE OUT" ,&tempcueOUT,cueIN+2 , audiofile.length ()-2 )){
393+ cueOUT = static_cast <double >(tempcueOUT);
394+ if (playhead > cueOUT){
395+ playhead = cueOUT;
396+ }
397+ }
398+
359399 ImGuiEx::ObjectInfo (
360400 " Audiofile player, it can load .wav, .mp3, .ogg, and .flac files." ,
361401 " https://mosaic.d3cod3.org/reference.php?r=soundfile-player" , scaleFactor);
@@ -386,22 +426,21 @@ void SoundfilePlayer::audioOutObject(ofSoundBuffer &outputBuffer){
386426
387427 // trigger, this needs to run in audio thread
388428 if (this ->inletsConnected [4 ]){
389- if (ofClamp (*(float *)&_inletParams[4 ],0 .0f ,1 .0f ) == 1 .0f && !isNextCycle){
429+ if (ofClamp (*(float *)&_inletParams[6 ],0 .0f ,1 .0f ) == 1 .0f && !isNextCycle){
390430 isNextCycle = true ;
391- playhead = 0.0 ;
431+ playhead = cueIN ;
392432 isPlaying = true ;
393433 finishSemaphore = true ;
394434 }else if (playhead > 6000 ){
395435 isNextCycle = false ;
396436 }
397-
398437 }
399438
400439 if (isFileLoaded && audiofile.loaded () && isPlaying){
401440 for (size_t i = 0 ; i < monoBuffer.getNumFrames (); i++) {
402441 int n = static_cast <int >(floor (playhead));
403442
404- if (n < static_cast <int >(audiofile. length ()- 1 ) ){
443+ if (static_cast <unsigned long long >(n) < cueOUT- 1 ){
405444 float fract = static_cast <float >(playhead - n);
406445 float isample = audiofile.sample (n, 0 )*(1 .0f -fract) + audiofile.sample (n+1 , 0 )*fract; // linear interpolation
407446 monoBuffer.getSample (i,0 ) = isample * volume;
@@ -419,9 +458,9 @@ void SoundfilePlayer::audioOutObject(ofSoundBuffer &outputBuffer){
419458 if (loop){
420459 // backword
421460 if (speed < 0.0 ){
422- playhead = audiofile. length ()- 2 ;
461+ playhead = cueOUT ;
423462 }else if (speed > 0.0 ){
424- playhead = 0.0 ;
463+ playhead = cueIN ;
425464 }
426465 }
427466 }
@@ -488,7 +527,9 @@ void SoundfilePlayer::loadAudioFile(string audiofilepath){
488527 monoBuffer.clear ();
489528 monoBuffer = tmpBuffer;
490529
491- playhead = 0.0 ;
530+ cueIN = 0.0 ;
531+ cueOUT = audiofile.length ()-2 ;
532+ playhead = cueIN;
492533
493534 this ->saveConfig (false );
494535
0 commit comments