mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
display timecode from BWF etc in SF browser; accels for windows now work (misspelling in ardour.bindings); use hide icon in automation tracks
git-svn-id: svn://localhost/ardour2/trunk@1125 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
3984be057b
commit
55a85aa2a9
14 changed files with 179 additions and 111 deletions
|
|
@ -89,6 +89,7 @@ RefPtr<Action>
|
|||
ActionManager::register_action (RefPtr<ActionGroup> group, const char * name, const char * label, slot<void> sl, guint key, Gdk::ModifierType mods)
|
||||
{
|
||||
RefPtr<Action> act = register_action (group, name, label, sl);
|
||||
cerr << "Reset A accel for " << name << endl;
|
||||
AccelMap::add_entry (act->get_accel_path(), key, mods);
|
||||
|
||||
return act;
|
||||
|
|
@ -121,6 +122,7 @@ RefPtr<Action>
|
|||
ActionManager::register_radio_action (RefPtr<ActionGroup> group, RadioAction::Group& rgroup, const char * name, const char * label, slot<void> sl, guint key, Gdk::ModifierType mods)
|
||||
{
|
||||
RefPtr<Action> act = register_radio_action (group, rgroup, name, label, sl);
|
||||
cerr << "Reset B accel for " << name << endl;
|
||||
AccelMap::add_entry (act->get_accel_path(), key, mods);
|
||||
|
||||
return act;
|
||||
|
|
@ -141,6 +143,7 @@ RefPtr<Action>
|
|||
ActionManager::register_toggle_action (RefPtr<ActionGroup> group, const char * name, const char * label, slot<void> sl, guint key, Gdk::ModifierType mods)
|
||||
{
|
||||
RefPtr<Action> act = register_toggle_action (group,name, label, sl);
|
||||
cerr << "Reset C accel for " << name << endl;
|
||||
AccelMap::add_entry (act->get_accel_path(), key, mods);
|
||||
|
||||
return act;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@
|
|||
|
||||
(gtk_accel_path "<Actions>/Common/goto-editor" "<alt>e")
|
||||
(gtk_accel_path "<Actions>/Common/goto-mixer" "<alt>m")
|
||||
(gtk-accel_path "<Actions>/Common/ToggleSoundFileBrowser" "<alt>f")
|
||||
(gtk-accel_path "<Actions>/Common/ToggleLocations" "<alt>l")
|
||||
(gtk-accel_path "<Actions>/Common/ToggleBigClock" "<alt>b")
|
||||
(gtk-accel_path "<Actions>/Common/ToggleColorManager" "<alt>c")
|
||||
(gtk_accel_path "<Actions>/Common/ToggleSoundFileBrowser" "<alt>f")
|
||||
(gtk_accel_path "<Actions>/Common/ToggleLocations" "<alt>l")
|
||||
(gtk_accel_path "<Actions>/Common/ToggleBigClock" "<alt>b")
|
||||
(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<alt>c")
|
||||
|
||||
(gtk_accel_path "<Actions>/Editor/editor-copy" "<control>c")
|
||||
(gtk_accel_path "<Actions>/Common/Quit" "<control>q")
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
|
|||
base_rect->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_automation_track_event),
|
||||
base_rect, this));
|
||||
|
||||
hide_button.add (*(manage (new Gtk::Image (get_xpm("small_x.xpm")))));
|
||||
hide_button.add (*(manage (new Gtk::Image (::get_icon("hide")))));
|
||||
|
||||
height_button.set_name ("TrackSizeButton");
|
||||
auto_button.set_name ("TrackVisualButton");
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ SoundFileBox::SoundFileBox ()
|
|||
main_box.pack_start(format, false, false);
|
||||
main_box.pack_start(channels, false, false);
|
||||
main_box.pack_start(samplerate, false, false);
|
||||
main_box.pack_start(timecode, false, false);
|
||||
main_box.pack_start(field_view, true, true);
|
||||
main_box.pack_start(top_box, false, false);
|
||||
main_box.pack_start(bottom_box, false, false);
|
||||
|
|
@ -129,21 +130,25 @@ SoundFileBox::setup_labels (string filename)
|
|||
path = filename;
|
||||
|
||||
string error_msg;
|
||||
|
||||
if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
length.set_alignment (0.0f, 0.0f);
|
||||
length.set_text (string_compose("Length: %1", PBD::length2string(sf_info.length, sf_info.samplerate)));
|
||||
length.set_text (string_compose(_("Length: %1"), PBD::length2string(sf_info.length, sf_info.samplerate)));
|
||||
|
||||
format.set_alignment (0.0f, 0.0f);
|
||||
format.set_text (sf_info.format_name);
|
||||
|
||||
channels.set_alignment (0.0f, 0.0f);
|
||||
channels.set_text (string_compose("Channels: %1", sf_info.channels));
|
||||
channels.set_text (string_compose(_("Channels: %1"), sf_info.channels));
|
||||
|
||||
samplerate.set_alignment (0.0f, 0.0f);
|
||||
samplerate.set_text (string_compose("Samplerate: %1", sf_info.samplerate));
|
||||
samplerate.set_text (string_compose(_("Samplerate: %1"), sf_info.samplerate));
|
||||
|
||||
timecode.set_alignment (0.0f, 0.0f);
|
||||
timecode.set_text (string_compose (_("Timecode: %1"), PBD::length2string(sf_info.timecode, sf_info.samplerate)));
|
||||
|
||||
setup_fields ();
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class SoundFileBox : public Gtk::VBox
|
|||
Gtk::Label format;
|
||||
Gtk::Label channels;
|
||||
Gtk::Label samplerate;
|
||||
Gtk::Label timecode;
|
||||
|
||||
Gtk::TreeView field_view;
|
||||
Glib::RefPtr<Gtk::ListStore> fields;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ struct SoundFileInfo {
|
|||
uint16_t channels;
|
||||
int64_t length;
|
||||
std::string format_name;
|
||||
int64_t timecode;
|
||||
};
|
||||
|
||||
class AudioFileSource : public AudioSource {
|
||||
|
|
@ -126,7 +127,7 @@ class AudioFileSource : public AudioSource {
|
|||
string _path;
|
||||
Flag _flags;
|
||||
string _take_id;
|
||||
uint64_t timeline_position;
|
||||
int64_t timeline_position;
|
||||
bool file_is_new;
|
||||
|
||||
bool _is_embedded;
|
||||
|
|
@ -141,7 +142,7 @@ class AudioFileSource : public AudioSource {
|
|||
|
||||
static uint64_t header_position_offset;
|
||||
|
||||
virtual void set_timeline_position (nframes_t pos);
|
||||
virtual void set_timeline_position (int64_t pos);
|
||||
virtual void set_header_timeline_position () = 0;
|
||||
|
||||
bool find (std::string path, bool must_exist, bool& is_new);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ class CoreAudioSource : public AudioFileSource {
|
|||
int flush_header () {return 0;};
|
||||
void set_header_timeline_position () {};
|
||||
|
||||
static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg);
|
||||
|
||||
protected:
|
||||
nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const;
|
||||
nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; }
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class DestructiveFileSource : public SndFileSource {
|
|||
|
||||
void init ();
|
||||
nframes_t crossfade (Sample* data, nframes_t cnt, int dir);
|
||||
void set_timeline_position (nframes_t);
|
||||
void set_timeline_position (int64_t);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ class SndFileSource : public AudioFileSource {
|
|||
static void setup_standard_crossfades (nframes_t sample_rate);
|
||||
static const AudioFileSource::Flag default_writable_flags;
|
||||
|
||||
static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg);
|
||||
|
||||
protected:
|
||||
void set_header_timeline_position ();
|
||||
|
||||
|
|
@ -96,10 +98,12 @@ class SndFileSource : public AudioFileSource {
|
|||
Sample* xfade_buf;
|
||||
|
||||
nframes_t crossfade (Sample* data, nframes_t cnt, int dir);
|
||||
void set_timeline_position (nframes_t);
|
||||
void set_timeline_position (int64_t);
|
||||
nframes_t destructive_write_unlocked (Sample *dst, nframes_t cnt);
|
||||
nframes_t nondestructive_write_unlocked (Sample *dst, nframes_t cnt);
|
||||
void handle_header_position_change ();
|
||||
|
||||
static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include <ardour/audiofilesource.h>
|
||||
#include <ardour/sndfile_helpers.h>
|
||||
#include <ardour/sndfilesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/source_factory.h>
|
||||
|
||||
|
|
@ -178,80 +177,16 @@ bool
|
|||
AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
|
||||
{
|
||||
#ifdef HAVE_COREAUDIO
|
||||
OSStatus err = noErr;
|
||||
FSRef ref;
|
||||
ExtAudioFileRef af = 0;
|
||||
size_t size;
|
||||
CFStringRef name;
|
||||
|
||||
err = FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0);
|
||||
if (err != noErr) {
|
||||
ExtAudioFileDispose (af);
|
||||
goto libsndfile;
|
||||
if (CoreAudioSource::get_soundfile_info (path, _info, error_msg) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
err = ExtAudioFileOpen(&ref, &af);
|
||||
if (err != noErr) {
|
||||
ExtAudioFileDispose (af);
|
||||
goto libsndfile;
|
||||
}
|
||||
|
||||
AudioStreamBasicDescription absd;
|
||||
memset(&absd, 0, sizeof(absd));
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
err = ExtAudioFileGetProperty(af,
|
||||
kExtAudioFileProperty_FileDataFormat, &size, &absd);
|
||||
if (err != noErr) {
|
||||
ExtAudioFileDispose (af);
|
||||
goto libsndfile;
|
||||
}
|
||||
|
||||
_info.samplerate = absd.mSampleRate;
|
||||
_info.channels = absd.mChannelsPerFrame;
|
||||
|
||||
size = sizeof(_info.length);
|
||||
err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length);
|
||||
if (err != noErr) {
|
||||
ExtAudioFileDispose (af);
|
||||
goto libsndfile;
|
||||
}
|
||||
|
||||
size = sizeof(CFStringRef);
|
||||
err = AudioFormatGetProperty(
|
||||
kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
|
||||
if (err != noErr) {
|
||||
ExtAudioFileDispose (af);
|
||||
goto libsndfile;
|
||||
}
|
||||
|
||||
_info.format_name = CFStringRefToStdString(name);
|
||||
|
||||
ExtAudioFileDispose (af);
|
||||
return true;
|
||||
|
||||
libsndfile:
|
||||
#endif // HAVE_COREAUDIO
|
||||
|
||||
SNDFILE *sf;
|
||||
SF_INFO sf_info;
|
||||
|
||||
sf_info.format = 0; // libsndfile says to clear this before sf_open().
|
||||
|
||||
if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) {
|
||||
char errbuf[256];
|
||||
error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
|
||||
return false;
|
||||
if (SndFileSource::get_soundfile_info (path, _info, error_msg) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sf_close (sf);
|
||||
|
||||
_info.samplerate = sf_info.samplerate;
|
||||
_info.channels = sf_info.channels;
|
||||
_info.length = sf_info.frames;
|
||||
_info.format_name = string_compose("Format: %1, %2",
|
||||
sndfile_major_format(sf_info.format),
|
||||
sndfile_minor_format(sf_info.format));
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
|
|
@ -540,7 +475,7 @@ AudioFileSource::set_header_position_offset (nframes_t offset)
|
|||
}
|
||||
|
||||
void
|
||||
AudioFileSource::set_timeline_position (nframes_t pos)
|
||||
AudioFileSource::set_timeline_position (int64_t pos)
|
||||
{
|
||||
timeline_position = pos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,3 +185,53 @@ CoreAudioSource::update_header (nframes_t when, struct tm&, time_t)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CoreAudioSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
|
||||
{
|
||||
FSRef ref;
|
||||
ExtAudioFileRef af = 0;
|
||||
size_t size;
|
||||
CFStringRef name;
|
||||
int ret = -1;
|
||||
|
||||
if (FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ExtAudioFileOpen(&ref, &af) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
AudioStreamBasicDescription absd;
|
||||
memset(&absd, 0, sizeof(absd));
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
if (ExtAudioFileGetProperty (af, kExtAudioFileProperty_FileDataFormat, &size, &absd) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
_info.samplerate = absd.mSampleRate;
|
||||
_info.channels = absd.mChannelsPerFrame;
|
||||
|
||||
size = sizeof(_info.length);
|
||||
if (ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = sizeof(CFStringRef);
|
||||
if (AudioFormatGetProperty(kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name) != noErr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
_info.format_name = CFStringRefToStdString(name);
|
||||
|
||||
// XXX it would be nice to find a way to get this information if it exists
|
||||
|
||||
_info.timecode = 0;
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
ExtAudioFileDispose (af);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include <ardour/sndfilesource.h>
|
||||
|
||||
#include <ardour/sndfile_helpers.h>
|
||||
#include <ardour/utils.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
|
@ -243,27 +243,14 @@ SndFileSource::open ()
|
|||
_broadcast_info = new SF_BROADCAST_INFO;
|
||||
memset (_broadcast_info, 0, sizeof (*_broadcast_info));
|
||||
|
||||
/* lookup broadcast info */
|
||||
|
||||
if (sf_command (sf, SFC_GET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
|
||||
bool timecode_info_exists;
|
||||
|
||||
/* if the file has data but no broadcast info, then clearly, there is no broadcast info */
|
||||
set_timeline_position (get_timecode_info (sf, _broadcast_info, timecode_info_exists));
|
||||
|
||||
if (_length) {
|
||||
delete _broadcast_info;
|
||||
_broadcast_info = 0;
|
||||
_flags = Flag (_flags & ~Broadcast);
|
||||
}
|
||||
|
||||
set_timeline_position (header_position_offset);
|
||||
|
||||
} else {
|
||||
|
||||
/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
|
||||
of the time reference.
|
||||
*/
|
||||
|
||||
set_timeline_position ( _broadcast_info->time_reference_low );
|
||||
if (!timecode_info_exists) {
|
||||
delete _broadcast_info;
|
||||
_broadcast_info = 0;
|
||||
_flags = Flag (_flags & ~Broadcast);
|
||||
}
|
||||
|
||||
if (writable()) {
|
||||
|
|
@ -893,7 +880,7 @@ SndFileSource::setup_standard_crossfades (nframes_t rate)
|
|||
}
|
||||
|
||||
void
|
||||
SndFileSource::set_timeline_position (nframes_t pos)
|
||||
SndFileSource::set_timeline_position (int64_t pos)
|
||||
{
|
||||
// destructive track timeline postion does not change
|
||||
// except at instantion or when header_position_offset
|
||||
|
|
@ -903,3 +890,57 @@ SndFileSource::set_timeline_position (nframes_t pos)
|
|||
AudioFileSource::set_timeline_position (pos);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SndFileSource::get_soundfile_info (string path, SoundFileInfo& info, string& error_msg)
|
||||
{
|
||||
SNDFILE *sf;
|
||||
SF_INFO sf_info;
|
||||
SF_BROADCAST_INFO binfo;
|
||||
bool timecode_exists;
|
||||
|
||||
sf_info.format = 0; // libsndfile says to clear this before sf_open().
|
||||
|
||||
if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) {
|
||||
char errbuf[256];
|
||||
error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
info.samplerate = sf_info.samplerate;
|
||||
info.channels = sf_info.channels;
|
||||
info.length = sf_info.frames;
|
||||
info.format_name = string_compose("Format: %1, %2",
|
||||
sndfile_major_format(sf_info.format),
|
||||
sndfile_minor_format(sf_info.format));
|
||||
|
||||
memset (&binfo, 0, sizeof (binfo));
|
||||
info.timecode = get_timecode_info (sf, &binfo, timecode_exists);
|
||||
|
||||
if (!timecode_exists) {
|
||||
info.timecode = 0;
|
||||
}
|
||||
|
||||
sf_close (sf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t
|
||||
SndFileSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
|
||||
{
|
||||
if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
|
||||
exists = false;
|
||||
return (header_position_offset);
|
||||
}
|
||||
|
||||
/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
|
||||
of the time reference.
|
||||
*/
|
||||
|
||||
exists = true;
|
||||
int64_t ret = (uint32_t) binfo->time_reference_high;
|
||||
ret <<= 32;
|
||||
ret |= (uint32_t) binfo->time_reference_low;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include <cmath>
|
||||
#include <stdint.h>
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "pbd/convert.h"
|
||||
|
||||
|
|
@ -190,23 +194,44 @@ url_decode (string& url)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
string
|
||||
length2string (const int32_t frames, const float sample_rate)
|
||||
{
|
||||
int secs = (int) (frames / sample_rate);
|
||||
int hrs = secs / 3600;
|
||||
int32_t secs = (int32_t) (frames / sample_rate);
|
||||
int32_t hrs = secs / 3600;
|
||||
secs -= (hrs * 3600);
|
||||
int mins = secs / 60;
|
||||
int32_t mins = secs / 60;
|
||||
secs -= (mins * 60);
|
||||
|
||||
int total_secs = (hrs * 3600) + (mins * 60) + secs;
|
||||
int frames_remaining = (int) floor (frames - (total_secs * sample_rate));
|
||||
int32_t total_secs = (hrs * 3600) + (mins * 60) + secs;
|
||||
int32_t frames_remaining = (int) floor (frames - (total_secs * sample_rate));
|
||||
float fractional_secs = (float) frames_remaining / sample_rate;
|
||||
|
||||
char duration_str[32];
|
||||
sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs);
|
||||
sprintf (duration_str, "%02" PRIi32 ":%02" PRIi32 ":%05.2f", hrs, mins, (float) secs + fractional_secs);
|
||||
|
||||
return duration_str;
|
||||
}
|
||||
#endif
|
||||
|
||||
string
|
||||
length2string (const int64_t frames, const double sample_rate)
|
||||
{
|
||||
int64_t secs = (int64_t) floor (frames / sample_rate);
|
||||
int64_t hrs = secs / 3600LL;
|
||||
secs -= (hrs * 3600LL);
|
||||
int64_t mins = secs / 60LL;
|
||||
secs -= (mins * 60LL);
|
||||
|
||||
int64_t total_secs = (hrs * 3600LL) + (mins * 60LL) + secs;
|
||||
int64_t frames_remaining = (int64_t) floor (frames - (total_secs * sample_rate));
|
||||
float fractional_secs = (float) frames_remaining / sample_rate;
|
||||
|
||||
char duration_str[64];
|
||||
sprintf (duration_str, "%02" PRIi64 ":%02" PRIi64 ":%05.2f", hrs, mins, (float) secs + fractional_secs);
|
||||
|
||||
return duration_str;
|
||||
}
|
||||
|
||||
} // namespace PBD
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ int atoi (const std::string&);
|
|||
double atof (const std::string&);
|
||||
void url_decode (std::string&);
|
||||
|
||||
std::string length2string (const int32_t frames, const float sample_rate);
|
||||
// std::string length2string (const int32_t frames, const float sample_rate);
|
||||
std::string length2string (const int64_t frames, const double sample_rate);
|
||||
|
||||
std::vector<std::string> internationalize (const char *, const char **);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue