diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audiofilesource.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/coreaudiosource.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/msvc_libardour.h | 99 | ||||
-rw-r--r-- | libs/ardour/ardour/silentfilesource.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfilesource.h | 1 | ||||
-rw-r--r-- | libs/ardour/audiofile_tagger.cc | 2 | ||||
-rw-r--r-- | libs/ardour/import.cc | 8 | ||||
-rw-r--r-- | libs/ardour/io.cc | 2 | ||||
-rw-r--r-- | libs/ardour/msvc/msvc_libardour.cc | 276 | ||||
-rw-r--r-- | libs/ardour/sndfilesource.cc | 24 |
10 files changed, 414 insertions, 2 deletions
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index c5fd7b3af2..af5dabe388 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -64,6 +64,7 @@ public: virtual void clear_capture_marks() {} virtual bool one_of_several_channels () const { return false; } + virtual void flush () = 0; virtual int update_header (framepos_t when, struct tm&, time_t) = 0; virtual int flush_header () = 0; diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h index 820fa0b9d8..30c66069f6 100644 --- a/libs/ardour/ardour/coreaudiosource.h +++ b/libs/ardour/ardour/coreaudiosource.h @@ -43,6 +43,8 @@ class CoreAudioSource : public AudioFileSource { void set_header_timeline_position () {}; bool clamped_at_unity () const { return false; } + void flush () {} + static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg); protected: diff --git a/libs/ardour/ardour/msvc_libardour.h b/libs/ardour/ardour/msvc_libardour.h new file mode 100644 index 0000000000..75c932905e --- /dev/null +++ b/libs/ardour/ardour/msvc_libardour.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2009 John Emmas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef __msvc_libardour_h__ +#define __msvc_libardour_h__ + +#include <limits.h> + +#ifdef LIBARDOUR_IS_IN_WIN_STATIC_LIB // #define if your project uses libardour (under Windows) as a static library +#define LIBARDOUR_IS_IN_WINDLL 0 +#endif + +#if !defined(LIBARDOUR_IS_IN_WINDLL) + #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW) + // If you need '__declspec' compatibility, add extra compilers to the above as necessary + #define LIBARDOUR_IS_IN_WINDLL 1 + #else + #define LIBARDOUR_IS_IN_WINDLL 0 + #endif +#endif + +#if LIBARDOUR_IS_IN_WINDLL && !defined(LIBARDOUR_API) + #if defined(BUILDING_LIBARDOUR) + #define LIBARDOUR_API __declspec(dllexport) + #define LIBARDOUR_APICALLTYPE __stdcall + #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point + #define LIBARDOUR_API __declspec(dllimport) + #define LIBARDOUR_APICALLTYPE __stdcall + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#elif !defined(LIBARDOUR_API) + // Other compilers / platforms could be accommodated here + #define LIBARDOUR_API + #define LIBARDOUR_APICALLTYPE +#endif + +#ifndef _MAX_PATH +#define _MAX_PATH 260 +#endif +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif + +namespace ARDOUR { + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// LIBARDOUR_API char* LIBARDOUR_APICALLTYPE placeholder_for_non_msvc_specific_function(s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +} // namespace ARDOUR + +#ifdef COMPILER_MSVC +#include <rpc.h> +//#include <io.h> + +#ifndef __THROW +#define __THROW throw() +#endif +#include <ardourext/sys/time.h> + +namespace ARDOUR { + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +LIBARDOUR_API int LIBARDOUR_APICALLTYPE symlink(const char *dest, const char *shortcut, const char *working_directory = 0); +LIBARDOUR_API int LIBARDOUR_APICALLTYPE readlink(const char *__restrict shortcut, char *__restrict buf, size_t bufsize); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +} // namespace ARDOUR + +#endif // COMPILER_MSVC +#endif // __mavc_libardour_h__ diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h index 5cdade3751..b8ac40e178 100644 --- a/libs/ardour/ardour/silentfilesource.h +++ b/libs/ardour/ardour/silentfilesource.h @@ -32,6 +32,7 @@ public: float sample_rate () const { return _sample_rate; } void set_length (framecnt_t len) { _length = len; } + void flush () {} bool destructive() const { return false; } bool can_be_analysed() const { return false; } diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 3f63f1c598..bed431c490 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -46,6 +46,7 @@ class SndFileSource : public AudioFileSource { float sample_rate () const; int update_header (framepos_t when, struct tm&, time_t); int flush_header (); + void flush (); framepos_t natural_position () const; diff --git a/libs/ardour/audiofile_tagger.cc b/libs/ardour/audiofile_tagger.cc index d27b9c97af..53b9afdd3e 100644 --- a/libs/ardour/audiofile_tagger.cc +++ b/libs/ardour/audiofile_tagger.cc @@ -24,7 +24,7 @@ #include "pbd/convert.h" -#include "taglib/taglib/fileref.h" +#include "taglib/fileref.h" #include "taglib/flac/flacfile.h" #include "taglib/ogg/oggfile.h" #include "taglib/tag.h" diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 9be72a9966..b66f354224 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -334,6 +334,14 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status, uint32_t chn; if ((nread = source->read (data.get(), nframes)) == 0) { +#ifdef PLATFORM_WINDOWS + /* Flush the data once we've finished importing the file. Windows can */ + /* cache the data for very long periods of time (perhaps not writing */ + /* it to disk until Ardour closes). So let's force it to flush now. */ + for (chn = 0; chn < channels; ++chn) + if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) + afs->flush (); +#endif break; } diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index c7bf163d27..a9d37d4315 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -1391,7 +1391,7 @@ IO::build_legal_port_name (DataType type) snprintf (&buf1[0], name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str()); int port_number = find_port_hole (&buf1[0]); - snprintf (&buf2[0], name_size+1, "%s %d", buf1, port_number); + snprintf (&buf2[0], name_size+1, "%s %d", &buf1[0], port_number); return string (&buf2[0]); } diff --git a/libs/ardour/msvc/msvc_libardour.cc b/libs/ardour/msvc/msvc_libardour.cc new file mode 100644 index 0000000000..bd186728ea --- /dev/null +++ b/libs/ardour/msvc/msvc_libardour.cc @@ -0,0 +1,276 @@ +/* + Copyright (C) 2009 John Emmas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#if (defined(PLATFORM_WINDOWS) && !defined(COMPILER_CYGWIN)) +#include <shlobj.h> +#include <glibmm.h> +#ifdef COMPILER_MSVC +#pragma warning(disable:4996) +#endif +#else +#include <glib.h> +#endif + +#include <string.h> +#include <stdlib.h> +#include <ardour/msvc_libardour.h> + +namespace ARDOUR { + +//*************************************************************** +// +// placeholder_for_non_msvc_specific_function() +// +// Description +// +// Returns: +// +// On Success: +// +// On Failure: +// +/* LIBARDOUR_API char* LIBARDOUR_APICALLTYPE + placeholder_for_non_msvc_specific_function() +{ +char *pRet = buffer; + + return (pRet); +} +*/ + +} // namespace ARDOUR + +#ifdef COMPILER_MSVC + +#include <errno.h> + +namespace ARDOUR { + +//*************************************************************** +// +// symlink() +// +// Emulates POSIX symlink() but creates a Windows shortcut. To +// create a Windows shortcut the supplied shortcut name must end +// in ".lnk" +// Note that you can only create a shortcut in a folder for which +// you have appropriate access rights. Note also that the folder +// must already exist. If it doesn't exist or if you don't have +// sufficient access rights to it, symlink() will generate an +// error (in common with its POSIX counterpart). +// +// Returns: +// +// On Success: Zero +// On Failure: -1 ('errno' will contain the specific error) +// +LIBARDOUR_API int LIBARDOUR_APICALLTYPE +symlink(const char *dest, const char *shortcut, const char *working_directory /*= NULL */) +{ +IShellLinkA *pISL = NULL; +IPersistFile *ppf = NULL; +int ret = (-1); + + if ((NULL == dest) || (NULL == shortcut) || (strlen(shortcut) < 5) || (strlen(dest) == 0)) + _set_errno(EINVAL); + else if ((strlen(shortcut) > _MAX_PATH) || (strlen(dest) > _MAX_PATH)) + _set_errno(ENAMETOOLONG); + else if (Glib::file_test(shortcut, Glib::FILE_TEST_EXISTS)) + _set_errno(EEXIST); + else + { + HRESULT hRet = 0; + + if (SUCCEEDED (hRet = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL))) + { + if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + char sc_path_lower_case[_MAX_PATH]; + WCHAR shortcut_path[_MAX_PATH]; + + // Fail if the path isn't a shortcut + strcpy(sc_path_lower_case, shortcut); + strlwr(sc_path_lower_case); + const char *p = strlen(sc_path_lower_case) + sc_path_lower_case - 4; + + if (0 == strcmp(p, ".lnk")) + { + HRESULT hr; + + // We're apparently been given valid Windows shortcut name + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut, -1, shortcut_path, _MAX_PATH); + + // Create the shortcut + if (FAILED (hr = ppf->Load(shortcut_path, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE))) + hr = ppf->Save(shortcut_path, TRUE); + + if (S_OK == hr) + { + // Set its target path + if (S_OK == pISL->SetPath(dest)) + { + // Set its working directory + if (working_directory) + p = working_directory; + else + p = ""; + + if (S_OK == pISL->SetWorkingDirectory(p)) + { + // Set its 'Show' command + if (S_OK == pISL->SetShowCmd(SW_SHOWNORMAL)) + { + // And finally, set its icon to the same file as the target. + // For the time being, don't fail if the target has no icon. + if (Glib::file_test(dest, Glib::FILE_TEST_IS_DIR)) + pISL->SetIconLocation("%SystemRoot%\\system32\\shell32.dll", 1); + else + pISL->SetIconLocation(dest, 0); + + if (S_OK == ppf->Save(shortcut_path, FALSE)) + { + Sleep(1500); + + ret = 0; + // _set_errno(0); + } + else + _set_errno(EACCES); + } + else + _set_errno(EACCES); + } + else + _set_errno(EACCES); + } + else + _set_errno(EACCES); + } + else + _set_errno(EBADF); + } + else + _set_errno(EACCES); + } + else + _set_errno(EBADF); + } + else + { + if (E_POINTER == hRet) + _set_errno(EINVAL); + else + _set_errno(EIO); + } + } + + return (ret); +} + + +//*************************************************************** +// +// readlink() +// +// Emulates POSIX readlink() but using Windows shortcuts +// Doesn't (currently) resolve shortcuts to shortcuts. This would +// be quite simple to incorporate but we'd need to check for +// recursion (i.e. a shortcut that points to an earlier shortcut +// in the same chain). +// +// Returns: +// +// On Success: Zero +// On Failure: -1 ('errno' will contain the specific error) +// +LIBARDOUR_API int LIBARDOUR_APICALLTYPE +readlink(const char *__restrict shortcut, char *__restrict buf, size_t bufsize) +{ +IShellLinkA *pISL = NULL; +IPersistFile *ppf = NULL; +int ret = (-1); + + if ((NULL == shortcut) || (NULL == buf) || (strlen(shortcut) < 5) || (bufsize == 0)) + _set_errno(EINVAL); + else if ((bufsize > _MAX_PATH) || (strlen(shortcut) > _MAX_PATH)) + _set_errno(ENAMETOOLONG); + else + { + HRESULT hRet = 0; + + if (SUCCEEDED (hRet = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL))) + { + if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + char target_path[_MAX_PATH]; + WCHAR shortcut_path[_MAX_PATH]; + + // Fail if the path isn't a shortcut + strcpy(target_path, shortcut); // Use 'target_path' temporarily + strlwr(target_path); + const char *p = strlen(target_path) + target_path - 4; + + if (0 == strcmp(p, ".lnk")) + { + // We're apparently pointing to a valid Windows shortcut + MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut, -1, shortcut_path, _MAX_PATH); + + // Load the shortcut into our persistent file + if (SUCCEEDED (ppf->Load(shortcut_path, 0))) + { + // Read the target information from the shortcut object + if (S_OK == (pISL->GetPath (target_path, _MAX_PATH, NULL, SLGP_UNCPRIORITY))) + { + strncpy(buf, target_path, bufsize); + ret = ((ret = strlen(buf)) > bufsize) ? bufsize : ret; + // _set_errno(0); + } + else + _set_errno(EACCES); + } + else + _set_errno(EBADF); + } + else + _set_errno(EINVAL); + } + else + _set_errno(EBADF); + } + else + { + if (E_POINTER == hRet) + _set_errno(EINVAL); + else + _set_errno(EIO); + } + + if (ppf) + ppf->Release(); + + if (pISL) + pISL->Release(); + } + + return (ret); +} + +} // namespace ARDOUR + +#endif // COMPILER_MSVC diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index b5d821ffda..1c3144f164 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -550,6 +550,30 @@ SndFileSource::flush_header () return r; } +void +SndFileSource::flush () +{ + if (!_open) { + warning << string_compose (_("attempt to flush an un-opened audio file source (%1)"), _path) << endmsg; + return; + } + + if (!writable()) { + warning << string_compose (_("attempt to flush a non-writable audio file source (%1)"), _path) << endmsg; + return; + } + + SNDFILE* sf = _descriptor->allocate (); + if (sf == 0) { + error << string_compose (_("could not allocate file %1 to flush contents"), _path) << endmsg; + return; + } + + // Hopefully everything OK + sf_write_sync (sf); + _descriptor->release (); +} + int SndFileSource::setup_broadcast_info (framepos_t /*when*/, struct tm& now, time_t /*tnow*/) { |