mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Track.cpp does not depend directly on its subclasses
This commit is contained in:
parent
98960c4fc3
commit
291bd7258f
@ -45,13 +45,14 @@ RecordingRecoveryHandler::RecordingRecoveryHandler(AudacityProject* proj)
|
||||
|
||||
int RecordingRecoveryHandler::FindTrack() const
|
||||
{
|
||||
WaveTrackArray tracks = TrackList::Get( *mProject ).GetWaveTrackArray(false);
|
||||
int index;
|
||||
auto tracks = TrackList::Get( *mProject ).Any< const WaveTrack >();
|
||||
int index = 0;
|
||||
if (mAutoSaveIdent)
|
||||
{
|
||||
for (index = 0; index < (int)tracks.size(); index++)
|
||||
auto iter = tracks.begin(), end = tracks.end();
|
||||
for (; iter != end; ++iter, ++index)
|
||||
{
|
||||
if (tracks[index]->GetAutoSaveIdent() == mAutoSaveIdent)
|
||||
if ((*iter)->GetAutoSaveIdent() == mAutoSaveIdent)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -78,7 +79,7 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag,
|
||||
return false;
|
||||
}
|
||||
|
||||
WaveTrackArray tracks = TrackList::Get( *mProject ).GetWaveTrackArray(false);
|
||||
auto tracks = TrackList::Get( *mProject ).Any< WaveTrack >();
|
||||
int index = FindTrack();
|
||||
// We need to find the track and sequence where the blockfile belongs
|
||||
|
||||
@ -89,7 +90,9 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag,
|
||||
return false;
|
||||
}
|
||||
|
||||
WaveTrack* track = tracks[index].get();
|
||||
auto iter = tracks.begin();
|
||||
std::advance( iter, index );
|
||||
WaveTrack* track = *iter;
|
||||
WaveClip* clip = track->NewestOrNewClip();
|
||||
Sequence* seq = clip->GetSequence();
|
||||
|
||||
@ -164,7 +167,7 @@ void RecordingRecoveryHandler::HandleXMLEndTag(const wxChar *tag)
|
||||
// Still in inner loop
|
||||
return;
|
||||
|
||||
WaveTrackArray tracks = TrackList::Get( *mProject ).GetWaveTrackArray(false);
|
||||
auto tracks = TrackList::Get( *mProject ).Any< WaveTrack >();
|
||||
int index = FindTrack();
|
||||
// We need to find the track and sequence where the blockfile belongs
|
||||
|
||||
@ -173,7 +176,9 @@ void RecordingRecoveryHandler::HandleXMLEndTag(const wxChar *tag)
|
||||
wxASSERT(false);
|
||||
}
|
||||
else {
|
||||
WaveTrack* track = tracks[index].get();
|
||||
auto iter = tracks.begin();
|
||||
std::advance( iter, index );
|
||||
WaveTrack* track = *iter;
|
||||
WaveClip* clip = track->NewestOrNewClip();
|
||||
Sequence* seq = clip->GetSequence();
|
||||
|
||||
|
@ -144,7 +144,7 @@ void MixAndRender(TrackList *tracks, TrackFactory *trackFactory,
|
||||
endTime = mixEndTime;
|
||||
}
|
||||
|
||||
auto timeTrack = tracks->GetTimeTrack();
|
||||
auto timeTrack = *tracks->Any<TimeTrack>().begin();
|
||||
Mixer mixer(waveArray,
|
||||
// Throw to abort mix-and-render if read fails:
|
||||
true,
|
||||
|
@ -176,7 +176,7 @@ DefaultPlayOptions( AudacityProject &project )
|
||||
ProjectSettings::Get( project ).GetRate() };
|
||||
options.captureMeter = projectAudioIO.GetCaptureMeter();
|
||||
options.playbackMeter = projectAudioIO.GetPlaybackMeter();
|
||||
auto timeTrack = TrackList::Get( project ).GetTimeTrack();
|
||||
auto timeTrack = *TrackList::Get( project ).Any<TimeTrack>().begin();
|
||||
options.envelope = timeTrack ? timeTrack->GetEnvelope() : nullptr;
|
||||
options.listener = &ProjectAudioManager::Get( project );
|
||||
return options;
|
||||
@ -195,7 +195,7 @@ DefaultSpeedPlayOptions( AudacityProject &project )
|
||||
AudioIOStartStreamOptions options{ &project, PlayAtSpeedRate };
|
||||
options.captureMeter = projectAudioIO.GetCaptureMeter();
|
||||
options.playbackMeter = projectAudioIO.GetPlaybackMeter();
|
||||
auto timeTrack = TrackList::Get( project ).GetTimeTrack();
|
||||
auto timeTrack = *TrackList::Get( project ).Any<TimeTrack>().begin();
|
||||
options.envelope = timeTrack ? timeTrack->GetEnvelope() : nullptr;
|
||||
options.listener = &ProjectAudioManager::Get( project );
|
||||
return options;
|
||||
|
104
src/Track.cpp
104
src/Track.cpp
@ -35,10 +35,6 @@ and TimeTrack.
|
||||
#include <wx/textfile.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include "TimeTrack.h"
|
||||
#include "WaveTrack.h"
|
||||
#include "NoteTrack.h"
|
||||
#include "LabelTrack.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectSettings.h"
|
||||
#include "DirManager.h"
|
||||
@ -1070,106 +1066,6 @@ size_t TrackList::size() const
|
||||
return cnt;
|
||||
}
|
||||
|
||||
TimeTrack *TrackList::GetTimeTrack()
|
||||
{
|
||||
return *Any<TimeTrack>().begin();
|
||||
}
|
||||
|
||||
const TimeTrack *TrackList::GetTimeTrack() const
|
||||
{
|
||||
return const_cast<TrackList*>(this)->GetTimeTrack();
|
||||
}
|
||||
|
||||
unsigned TrackList::GetNumExportChannels(bool selectionOnly) const
|
||||
{
|
||||
/* counters for tracks panned different places */
|
||||
int numLeft = 0;
|
||||
int numRight = 0;
|
||||
//int numMono = 0;
|
||||
/* track iteration kit */
|
||||
|
||||
// Want only unmuted wave tracks.
|
||||
for (auto tr :
|
||||
Any< const WaveTrack >()
|
||||
+ (selectionOnly ? &Track::IsSelected : &Track::Any)
|
||||
- &WaveTrack::GetMute
|
||||
) {
|
||||
// Found a left channel
|
||||
if (tr->GetChannel() == Track::LeftChannel) {
|
||||
numLeft++;
|
||||
}
|
||||
|
||||
// Found a right channel
|
||||
else if (tr->GetChannel() == Track::RightChannel) {
|
||||
numRight++;
|
||||
}
|
||||
|
||||
// Found a mono channel, but it may be panned
|
||||
else if (tr->GetChannel() == Track::MonoChannel) {
|
||||
float pan = tr->GetPan();
|
||||
|
||||
// Figure out what kind of channel it should be
|
||||
if (pan == -1.0) { // panned hard left
|
||||
numLeft++;
|
||||
}
|
||||
else if (pan == 1.0) { // panned hard right
|
||||
numRight++;
|
||||
}
|
||||
else if (pan == 0) { // panned dead center
|
||||
// numMono++;
|
||||
}
|
||||
else { // panned somewhere else
|
||||
numLeft++;
|
||||
numRight++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is stereo content, report 2, else report 1
|
||||
if (numRight > 0 || numLeft > 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<typename Array, typename TrackRange>
|
||||
Array GetTypedTracks(const TrackRange &trackRange,
|
||||
bool selectionOnly, bool includeMuted)
|
||||
{
|
||||
using Type = typename std::remove_reference<
|
||||
decltype( *std::declval<Array>()[0] )
|
||||
>::type;
|
||||
auto subRange =
|
||||
trackRange.template Filter<Type>();
|
||||
if ( selectionOnly )
|
||||
subRange = subRange + &Track::IsSelected;
|
||||
if ( ! includeMuted )
|
||||
subRange = subRange - &Type::GetMute;
|
||||
return transform_range<Array>( subRange.begin(), subRange.end(),
|
||||
[]( Type *t ){ return t->template SharedPointer<Type>(); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WaveTrackArray TrackList::GetWaveTrackArray(bool selectionOnly, bool includeMuted)
|
||||
{
|
||||
return GetTypedTracks<WaveTrackArray>(Any(), selectionOnly, includeMuted);
|
||||
}
|
||||
|
||||
WaveTrackConstArray TrackList::GetWaveTrackConstArray(bool selectionOnly, bool includeMuted) const
|
||||
{
|
||||
return GetTypedTracks<WaveTrackConstArray>(Any(), selectionOnly, includeMuted);
|
||||
}
|
||||
|
||||
#if defined(USE_MIDI)
|
||||
NoteTrackConstArray TrackList::GetNoteTrackConstArray(bool selectionOnly) const
|
||||
{
|
||||
return GetTypedTracks<NoteTrackConstArray>(Any(), selectionOnly, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
int TrackList::GetHeight() const
|
||||
{
|
||||
int height = 0;
|
||||
|
18
src/Track.h
18
src/Track.h
@ -1416,24 +1416,6 @@ public:
|
||||
bool MoveDown(Track * t);
|
||||
bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); }
|
||||
|
||||
TimeTrack *GetTimeTrack();
|
||||
const TimeTrack *GetTimeTrack() const;
|
||||
|
||||
/** \brief Find out how many channels this track list mixes to
|
||||
*
|
||||
* This is used in exports of the tracks to work out whether to export in
|
||||
* Mono, Stereo etc. @param selectionOnly Whether to consider the entire track
|
||||
* list or only the selected members of it
|
||||
*/
|
||||
unsigned GetNumExportChannels(bool selectionOnly) const;
|
||||
|
||||
WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted = true);
|
||||
WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted = true) const;
|
||||
|
||||
#if defined(USE_MIDI)
|
||||
NoteTrackConstArray GetNoteTrackConstArray(bool selectionOnly) const;
|
||||
#endif
|
||||
|
||||
/// Mainly a test function. Uses a linear search, so could be slow.
|
||||
bool Contains(const Track * t) const;
|
||||
|
||||
|
@ -2624,7 +2624,7 @@ void WaveTrack::AddInvalidRegion(sampleCount startSample, sampleCount endSample)
|
||||
clip->AddInvalidRegion(startSample, endSample);
|
||||
}
|
||||
|
||||
int WaveTrack::GetAutoSaveIdent()
|
||||
int WaveTrack::GetAutoSaveIdent() const
|
||||
{
|
||||
return mAutoSaveIdent;
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ private:
|
||||
// AutoSave related
|
||||
//
|
||||
// Retrieve the unique autosave ID
|
||||
int GetAutoSaveIdent();
|
||||
int GetAutoSaveIdent() const;
|
||||
// Set the unique autosave ID
|
||||
void SetAutoSaveIdent(int id);
|
||||
|
||||
|
@ -248,9 +248,14 @@ std::unique_ptr<Mixer> ExportPlugin::CreateMixer(const TrackList &tracks,
|
||||
double outRate, sampleFormat outFormat,
|
||||
bool highQuality, MixerSpec *mixerSpec)
|
||||
{
|
||||
const WaveTrackConstArray inputTracks =
|
||||
tracks.GetWaveTrackConstArray(selectionOnly, false);
|
||||
const TimeTrack *timeTrack = tracks.GetTimeTrack();
|
||||
WaveTrackConstArray inputTracks;
|
||||
auto range = tracks.Any< const WaveTrack >()
|
||||
+ (selectionOnly ? &Track::IsSelected : &Track::Any )
|
||||
- &WaveTrack::GetMute;
|
||||
for (auto pTrack: range)
|
||||
inputTracks.push_back(
|
||||
pTrack->SharedPointer< const WaveTrack >() );
|
||||
const auto timeTrack = *tracks.Any<const TimeTrack>().begin();
|
||||
auto envelope = timeTrack ? timeTrack->GetEnvelope() : nullptr;
|
||||
// MB: the stop time should not be warped, this was a bug.
|
||||
return std::make_unique<Mixer>(inputTracks,
|
||||
|
@ -646,6 +646,57 @@ bool ExportMultiple::DirOk()
|
||||
return fn.Mkdir(0777, wxPATH_MKDIR_FULL);
|
||||
}
|
||||
|
||||
static unsigned GetNumExportChannels( const TrackList &tracks )
|
||||
{
|
||||
/* counters for tracks panned different places */
|
||||
int numLeft = 0;
|
||||
int numRight = 0;
|
||||
//int numMono = 0;
|
||||
/* track iteration kit */
|
||||
|
||||
// Want only unmuted wave tracks.
|
||||
for (auto tr :
|
||||
tracks.Any< const WaveTrack >() - &WaveTrack::GetMute
|
||||
) {
|
||||
// Found a left channel
|
||||
if (tr->GetChannel() == Track::LeftChannel) {
|
||||
numLeft++;
|
||||
}
|
||||
|
||||
// Found a right channel
|
||||
else if (tr->GetChannel() == Track::RightChannel) {
|
||||
numRight++;
|
||||
}
|
||||
|
||||
// Found a mono channel, but it may be panned
|
||||
else if (tr->GetChannel() == Track::MonoChannel) {
|
||||
float pan = tr->GetPan();
|
||||
|
||||
// Figure out what kind of channel it should be
|
||||
if (pan == -1.0) { // panned hard left
|
||||
numLeft++;
|
||||
}
|
||||
else if (pan == 1.0) { // panned hard right
|
||||
numRight++;
|
||||
}
|
||||
else if (pan == 0) { // panned dead center
|
||||
// numMono++;
|
||||
}
|
||||
else { // panned somewhere else
|
||||
numLeft++;
|
||||
numRight++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there is stereo content, report 2, else report 1
|
||||
if (numRight > 0 || numLeft > 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: JKC July2016: Merge labels/tracks duplicated export code.
|
||||
// TODO: JKC Apr2019: Doubly so merge these! Too much duplication.
|
||||
ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName,
|
||||
@ -664,7 +715,7 @@ ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName,
|
||||
}
|
||||
|
||||
// Figure out how many channels we should export.
|
||||
auto channels = mTracks->GetNumExportChannels(false);
|
||||
auto channels = GetNumExportChannels( *mTracks );
|
||||
|
||||
FilePaths otherNames; // keep track of file names we will use, so we
|
||||
// don't duplicate them
|
||||
|
@ -118,7 +118,7 @@ bool DoPasteNothingSelected(AudacityProject &project)
|
||||
},
|
||||
[&](const TimeTrack *) {
|
||||
// Maintain uniqueness of the time track!
|
||||
pNewTrack = tracks.GetTimeTrack();
|
||||
pNewTrack = *tracks.Any<TimeTrack>().begin();
|
||||
if (!pNewTrack)
|
||||
uNewTrack = trackFactory.NewTimeTrack(),
|
||||
pNewTrack = uNewTrack.get();
|
||||
|
@ -889,7 +889,7 @@ void OnNewTimeTrack(const CommandContext &context)
|
||||
auto &trackPanel = TrackPanel::Get( project );
|
||||
auto &window = ProjectWindow::Get( project );
|
||||
|
||||
if (tracks.GetTimeTrack()) {
|
||||
if ( *tracks.Any<TimeTrack>().begin() ) {
|
||||
AudacityMessageBox(_("This version of Audacity only allows one time track for each project window."));
|
||||
return;
|
||||
}
|
||||
@ -1205,7 +1205,9 @@ void OnScoreAlign(const CommandContext &context)
|
||||
Mixer mix(
|
||||
waveTracks, // const WaveTrackConstArray &inputTracks
|
||||
false, // mayThrow -- is this right?
|
||||
Mixer::WarpOptions{ tracks->GetTimeTrack() }, // const WarpOptions &warpOptions
|
||||
Mixer::WarpOptions{
|
||||
*tracks->Any<const TimeTrack >().begin()
|
||||
}, // const WarpOptions &warpOptions
|
||||
0.0, // double startTime
|
||||
endTime, // double stopTime
|
||||
2, // int numOutChannels
|
||||
|
@ -1545,13 +1545,28 @@ void ControlToolBar::CancelRecording()
|
||||
TrackList::Get( *project ).ClearPendingTracks();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
#include "NoteTrack.h"
|
||||
#endif
|
||||
|
||||
TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool useMidi)
|
||||
{
|
||||
TransportTracks result;
|
||||
result.playbackTracks = trackList.GetWaveTrackArray(selectedOnly);
|
||||
{
|
||||
auto range = trackList.Any< WaveTrack >()
|
||||
+ (selectedOnly ? &Track::IsSelected : &Track::Any );
|
||||
for (auto pTrack: range)
|
||||
result.playbackTracks.push_back(
|
||||
pTrack->SharedPointer< WaveTrack >() );
|
||||
}
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
if (useMidi)
|
||||
result.midiTracks = trackList.GetNoteTrackConstArray(selectedOnly);
|
||||
if (useMidi) {
|
||||
auto range = trackList.Any< const NoteTrack >() +
|
||||
(selectedOnly ? &Track::IsSelected : &Track::Any );
|
||||
for (auto pTrack: range)
|
||||
result.midiTracks.push_back(
|
||||
pTrack->SharedPointer< const NoteTrack >() );
|
||||
}
|
||||
#else
|
||||
WXUNUSED(useMidi);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user