changeset 7:3a41ba527b4a

* Add command history class, and basic undo/redo menus. No actual commands to undo/redo yet. Selecting the placeholders sometimes seems to cause a crash, so this looks a little uncertain so far. * Add Rename Layer * Remove models from playback when their layers are removed (and ref counts hit zero) * Don't hang around waiting so much when there's work to be done in the audio buffer fill thread * Put more sensible names on layers generated from transforms * Add basic editing to time-value layer like existing editing in time-instants layer, and make both of them snap to the appropriate resolution during drag
author Chris Cannam
date Mon, 30 Jan 2006 17:51:56 +0000
parents f3d777b693f7
children 24b500216029
files audioio/AudioCallbackPlaySource.cpp audioio/AudioCallbackPlaySource.h
diffstat 2 files changed, 34 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/audioio/AudioCallbackPlaySource.cpp	Fri Jan 27 18:04:07 2006 +0000
+++ b/audioio/AudioCallbackPlaySource.cpp	Mon Jan 30 17:51:56 2006 +0000
@@ -622,7 +622,7 @@
 
 		got = rb->read(buffer[ch], request);
 	    
-#ifdef DEBUG_AUDIO_PLAY_SOURCE
+#ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
 		std::cout << "AudioCallbackPlaySource::getSamples: got " << got << " samples on channel " << ch << ", signalling for more (possibly)" << std::endl;
 #endif
 	    }
@@ -684,13 +684,13 @@
 	}
     }
 
-    if (m_slowdownCounter == 0) m_condition.wakeAll();
+//!!!    if (m_slowdownCounter == 0) m_condition.wakeAll();
     m_slowdownCounter = (m_slowdownCounter + 1) % timeStretcher->getFactor();
     return count;
 }
 
 // Called from fill thread, m_playing true, mutex held
-void
+bool
 AudioCallbackPlaySource::fillBuffers()
 {
     static float *tmp = 0;
@@ -705,7 +705,7 @@
 	}
     }
     
-    if (space == 0) return;
+    if (space == 0) return false;
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
     std::cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << std::endl;
@@ -754,7 +754,7 @@
 
 	// orig must be a multiple of generatorBlockSize
 	orig = (orig / generatorBlockSize) * generatorBlockSize;
-	if (orig == 0) return;
+	if (orig == 0) return false;
 
 	size_t work = std::max(orig, space);
 
@@ -838,7 +838,7 @@
 
 	// space must be a multiple of generatorBlockSize
 	space = (space / generatorBlockSize) * generatorBlockSize;
-	if (space == 0) return;
+	if (space == 0) return false;
 
 	if (tmpSize < channels * space) {
 	    delete[] tmp;
@@ -873,6 +873,8 @@
 	m_bufferedToFrame = f;
 	//!!! how do we know when ended? need to mark up a fully-buffered flag and check this if we find the buffers empty in getSourceSamples
     }
+
+    return true;
 }    
 
 size_t
@@ -1020,7 +1022,7 @@
     }
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
-    std::cerr << "Returning selection playback at " << nextChunkStart << std::endl;
+    std::cerr << "Returning selection playback " << processed << " frames to " << nextChunkStart << std::endl;
 #endif
 
     frame = nextChunkStart;
@@ -1039,6 +1041,7 @@
     s.m_mutex.lock();
 
     bool previouslyPlaying = s.m_playing;
+    bool work = false;
 
     while (!s.m_exiting) {
 
@@ -1049,27 +1052,35 @@
 	}
 	
 	s.m_bufferScavenger.scavenge();
-
 	s.m_timeStretcherScavenger.scavenge();
 
-	float ms = 100;
-	if (s.getSourceSampleRate() > 0) {
-	    ms = float(m_ringBufferSize) / float(s.getSourceSampleRate()) * 1000.0;
+	if (work && s.m_playing && s.getSourceSampleRate()) {
+
+	    s.m_mutex.unlock();
+	    s.m_mutex.lock();
+
+	} else {
+	    
+	    float ms = 100;
+	    if (s.getSourceSampleRate() > 0) {
+		ms = float(m_ringBufferSize) / float(s.getSourceSampleRate()) * 1000.0;
+	    }
+	    
+	    if (s.m_playing) ms /= 10;
+	    
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
+	    std::cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << std::endl;
+#endif
+	    
+	    s.m_condition.wait(&s.m_mutex, size_t(ms));
 	}
 
-	if (!s.m_playing) ms *= 10;
-	ms = ms / 8;
-
-#ifdef DEBUG_AUDIO_PLAY_SOURCE
-	std::cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << std::endl;
-#endif
-
-	s.m_condition.wait(&s.m_mutex, size_t(ms));
-
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
 	std::cout << "AudioCallbackPlaySourceFillThread: awoken" << std::endl;
 #endif
 
+	work = false;
+
 	if (!s.getSourceSampleRate()) continue;
 
 	bool playing = s.m_playing;
@@ -1085,7 +1096,7 @@
 	}
 	previouslyPlaying = playing;
 
-	s.fillBuffers();
+	work = s.fillBuffers();
     }
 
     s.m_mutex.unlock();
--- a/audioio/AudioCallbackPlaySource.h	Fri Jan 27 18:04:07 2006 +0000
+++ b/audioio/AudioCallbackPlaySource.h	Mon Jan 30 17:51:56 2006 +0000
@@ -253,7 +253,8 @@
     Scavenger<TimeStretcherData> m_timeStretcherScavenger;
 
     // Called from fill thread, m_playing true, mutex held
-    void fillBuffers();
+    // Return true if work done
+    bool fillBuffers();
     
     // Called from fillBuffers.  Return the number of frames written,
     // which will be count or fewer.  Return in the frame argument the