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:
Paul Davis 2006-11-13 17:56:43 +00:00
parent 3984be057b
commit 55a85aa2a9
14 changed files with 179 additions and 111 deletions

View file

@ -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;

View file

@ -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")

View file

@ -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");

View file

@ -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 ();

View file

@ -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;

View file

@ -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);

View file

@ -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; }

View file

@ -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);
};
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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 **);