diff options
Diffstat (limited to 'libs')
353 files changed, 7046 insertions, 1401 deletions
diff --git a/libs/ardour/ardour/async_midi_port.h b/libs/ardour/ardour/async_midi_port.h index e7eeb8ee30..c5babf6135 100644 --- a/libs/ardour/ardour/async_midi_port.h +++ b/libs/ardour/ardour/async_midi_port.h @@ -53,10 +53,16 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port { /* called from non-RT context */ void parse (framecnt_t timestamp); - int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp); + int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp); int read (MIDI::byte *buf, size_t bufsize); void drain (int check_interval_usecs); - int selectable () const { return xthread.selectable(); } + int selectable () const { +#ifdef PLATFORM_WINDOWS + return false; +#else + return xthread.selectable(); +#endif + } static void set_process_thread (pthread_t); static pthread_t get_process_thread () { return _process_thread; } @@ -67,8 +73,22 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port { MIDI::timestamp_t _last_write_timestamp; RingBuffer< Evoral::Event<double> > output_fifo; Evoral::EventRingBuffer<MIDI::timestamp_t> input_fifo; - Glib::Threads::Mutex output_fifo_lock; - CrossThreadChannel xthread; + Glib::Threads::Mutex output_fifo_lock; +#ifndef PLATFORM_WINDOWS + CrossThreadChannel xthread; +#endif + + int create_port (); + + /** Channel used to signal to the MidiControlUI that input has arrived */ + + std::string _connections; + PBD::ScopedConnection connect_connection; + PBD::ScopedConnection halt_connection; + void flush (void* jack_port_buffer); + void jack_halted (); + void make_connections (); + void init (std::string const &, Flags); void flush_output_fifo (pframes_t); diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index 723c734a49..53819c1c9e 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/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index c3d10b6030..c4196dc3b6 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -29,7 +29,6 @@ namespace ARDOUR { class Session; -class Region; class AudioRegion; class Source; class AudioPlaylist; diff --git a/libs/ardour/ardour/backend_search_path.h b/libs/ardour/ardour/backend_search_path.h index 2adc22bd6f..e8a5082c71 100644 --- a/libs/ardour/ardour/backend_search_path.h +++ b/libs/ardour/ardour/backend_search_path.h @@ -32,7 +32,7 @@ namespace ARDOUR { * contain the user and system directories which may contain audio/MIDI * backends. */ - PBD::SearchPath backend_search_path (); + PBD::Searchpath backend_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/butler.h b/libs/ardour/ardour/butler.h index 21af5fb691..efdaad1621 100644 --- a/libs/ardour/ardour/butler.h +++ b/libs/ardour/ardour/butler.h @@ -20,14 +20,22 @@ #ifndef __ardour_butler_h__ #define __ardour_butler_h__ +#include <pthread.h> + #include <glibmm/threads.h> +#ifdef PLATFORM_WINDOWS +#include "pbd/glib_semaphore.h" +#endif + #include "pbd/ringbuffer.h" #include "pbd/pool.h" #include "ardour/libardour_visibility.h" #include "ardour/types.h" #include "ardour/session_handle.h" + + namespace ARDOUR { /** @@ -72,15 +80,43 @@ class LIBARDOUR_API Butler : public SessionHandleRef Glib::Threads::Cond paused; bool should_run; mutable gint should_do_transport_work; - int request_pipe[2]; framecnt_t audio_dstream_capture_buffer_size; framecnt_t audio_dstream_playback_buffer_size; uint32_t midi_dstream_buffer_size; RingBuffer<CrossThreadPool*> pool_trash; +#ifdef PLATFORM_WINDOWS + PBD::atomic_counter m_request_state; + PBD::GlibSemaphore m_request_sem; +#else + int request_pipe[2]; +#endif + private: void empty_pool_trash (); void config_changed (std::string); + +#ifndef PLATFORM_WINDOWS + int setup_request_pipe (); +#endif + + /** + * return true if there are requests to be processed + */ + bool wait_for_requests (); + + /** + * Remove request from butler request queue + * + * return true if there was another request and req is valid + */ + bool dequeue_request (Request::Type& req); + + /** + * Add request to butler thread request queue + */ + void queue_request (Request::Type r); + }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h index 11fb6fea9d..9f9fd07543 100644 --- a/libs/ardour/ardour/chan_count.h +++ b/libs/ardour/ardour/chan_count.h @@ -26,6 +26,10 @@ #include "pbd/xml++.h" #include "ardour/data_type.h" +#ifdef INFINITE +#undef INFINITE +#endif + namespace ARDOUR { diff --git a/libs/ardour/ardour/control_protocol_search_path.h b/libs/ardour/ardour/control_protocol_search_path.h index 8795f4501a..4fe790ef80 100644 --- a/libs/ardour/ardour/control_protocol_search_path.h +++ b/libs/ardour/ardour/control_protocol_search_path.h @@ -25,15 +25,15 @@ namespace ARDOUR { /** - * return a SearchPath containing directories in which to look for + * return a Searchpath containing directories in which to look for * control surface plugins. * - * If ARDOUR_SURFACES_PATH is defined then the SearchPath returned + * If ARDOUR_SURFACES_PATH is defined then the Searchpath returned * will contain only those directories specified in it, otherwise it will * contain the user and system directories which may contain control * surface plugins. */ - PBD::SearchPath control_protocol_search_path (); + PBD::Searchpath control_protocol_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h index 84ad434809..f12a67ded7 100644 --- a/libs/ardour/ardour/coreaudiosource.h +++ b/libs/ardour/ardour/coreaudiosource.h @@ -43,6 +43,8 @@ class LIBARDOUR_API 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/cycles.h b/libs/ardour/ardour/cycles.h index 01e1d55221..dc1095db7b 100644 --- a/libs/ardour/ardour/cycles.h +++ b/libs/ardour/ardour/cycles.h @@ -216,7 +216,10 @@ static inline cycles_t get_cycles (void) /* debian: sparc, arm, m68k */ +#ifndef COMPILER_MSVC +/* GRRR... Annoyingly, #warning aborts the compilation for MSVC !! */ #warning You are compiling libardour on a platform for which ardour/cycles.h needs work +#endif #include <sys/time.h> diff --git a/libs/ardour/ardour/export_formats_search_path.h b/libs/ardour/ardour/export_formats_search_path.h index 7b6fcea09b..771c6f9bd3 100644 --- a/libs/ardour/ardour/export_formats_search_path.h +++ b/libs/ardour/ardour/export_formats_search_path.h @@ -24,10 +24,10 @@ namespace ARDOUR { /** - * return a SearchPath containing directories in which to look for + * return a Searchpath containing directories in which to look for * export_formats. */ - PBD::SearchPath export_formats_search_path (); + PBD::Searchpath export_formats_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/export_profile_manager.h b/libs/ardour/ardour/export_profile_manager.h index 935df25528..2757795ff3 100644 --- a/libs/ardour/ardour/export_profile_manager.h +++ b/libs/ardour/ardour/export_profile_manager.h @@ -103,7 +103,7 @@ class LIBARDOUR_API ExportProfileManager std::vector<std::string> find_file (std::string const & pattern); std::string export_config_dir; - PBD::SearchPath search_path; + PBD::Searchpath search_path; /* Timespans */ public: diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index 568bc3204b..4b1dbf2b6c 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -79,7 +79,7 @@ public: virtual void set_path (const std::string&); - static PBD::Signal3<int,std::string,std::string,std::vector<std::string> > AmbiguousFileName; + static PBD::Signal2<int,std::string,std::vector<std::string> > AmbiguousFileName; protected: FileSource (Session& session, DataType type, diff --git a/libs/ardour/ardour/filesystem_paths.h b/libs/ardour/ardour/filesystem_paths.h index b96cd05137..0bf25c5153 100644 --- a/libs/ardour/ardour/filesystem_paths.h +++ b/libs/ardour/ardour/filesystem_paths.h @@ -43,14 +43,14 @@ namespace ARDOUR { * @return the search path to be used when looking for per-system * configuration files. This may include user configuration files. */ - LIBARDOUR_API PBD::SearchPath ardour_config_search_path (); + LIBARDOUR_API PBD::Searchpath ardour_config_search_path (); /** * @return the search path to be used when looking for data files * that could be shared by systems (h/w and configuration independent * files, such as icons, XML files, etc) */ - LIBARDOUR_API PBD::SearchPath ardour_data_search_path (); + LIBARDOUR_API PBD::Searchpath ardour_data_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/interthread_info.h b/libs/ardour/ardour/interthread_info.h index 2cc786c6e2..49055de5d0 100644 --- a/libs/ardour/ardour/interthread_info.h +++ b/libs/ardour/ardour/interthread_info.h @@ -30,7 +30,7 @@ namespace ARDOUR { class InterThreadInfo { public: - InterThreadInfo () : done (false), cancel (false), progress (0), thread (0) {} + InterThreadInfo () : done (false), cancel (false), progress (0), thread () {} volatile bool done; volatile bool cancel; diff --git a/libs/ardour/ardour/jack_utils.h b/libs/ardour/ardour/jack_utils.h new file mode 100644 index 0000000000..40eb30f9ea --- /dev/null +++ b/libs/ardour/ardour/jack_utils.h @@ -0,0 +1,253 @@ +/* + Copyright (C) 2011 Tim Mayberry + + 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. + +*/ + +#include <stdint.h> + +#include <vector> +#include <map> +#include <string> + +namespace ARDOUR { + + // Names for the drivers on all possible systems + extern const char * const portaudio_driver_name; + extern const char * const coreaudio_driver_name; + extern const char * const alsa_driver_name; + extern const char * const oss_driver_name; + extern const char * const freebob_driver_name; + extern const char * const ffado_driver_name; + extern const char * const netjack_driver_name; + extern const char * const dummy_driver_name; + + /** + * Get a list of possible JACK audio driver names based on platform + */ + void get_jack_audio_driver_names (std::vector<std::string>& driver_names); + + /** + * Get the default JACK audio driver based on platform + */ + void get_jack_default_audio_driver_name (std::string& driver_name); + + /** + * Get a list of possible JACK midi driver names based on platform + */ + void get_jack_midi_system_names (const std::string& driver, std::vector<std::string>& driver_names); + + /** + * Get the default JACK midi driver based on platform + */ + void get_jack_default_midi_system_name (const std::string& driver_name, std::string& midi_system); + + /** + * Get a list of possible samplerates supported be JACK + */ + void get_jack_sample_rate_strings (std::vector<std::string>& sample_rates); + + /** + * @return The default samplerate + */ + std::string get_jack_default_sample_rate (); + + /** + * @return true if sample rate string was able to be converted + */ + bool get_jack_sample_rate_value_from_string (const std::string& srs, uint32_t& srv); + + /** + * Get a list of possible period sizes supported be JACK + */ + void get_jack_period_size_strings (std::vector<std::string>& samplerates); + + /** + * @return The default period size + */ + std::string get_jack_default_period_size (); + + /** + * @return true if period size string was able to be converted + */ + bool get_jack_period_size_value_from_string (const std::string& pss, uint32_t& psv); + + /** + * These are driver specific I think, so it may require a driver arg + * in future + */ + void get_jack_dither_mode_strings (const std::string& driver, std::vector<std::string>& dither_modes); + + /** + * @return The default dither mode + */ + std::string get_jack_default_dither_mode (const std::string& driver); + + /** + * @return Estimate of latency + * + * API matches current use in GUI + */ + std::string get_jack_latency_string (std::string samplerate, float periods, std::string period_size); + + /** + * @return true if a JACK server is running + */ + bool jack_server_running (); + + /** + * Key being a readable name to display in a GUI + * Value being name used in a jack commandline + */ + typedef std::map<std::string, std::string> device_map_t; + + /** + * Use library specific code to find out what what devices exist for a given + * driver that might work in JACK. There is no easy way to find out what + * modules the JACK server supports so guess based on platform. For instance + * portaudio is cross-platform but we only return devices if built for + * windows etc + */ + void get_jack_alsa_device_names (device_map_t& devices); + void get_jack_portaudio_device_names (device_map_t& devices); + void get_jack_coreaudio_device_names (device_map_t& devices); + void get_jack_oss_device_names (device_map_t& devices); + void get_jack_freebob_device_names (device_map_t& devices); + void get_jack_ffado_device_names (device_map_t& devices); + void get_jack_netjack_device_names (device_map_t& devices); + void get_jack_dummy_device_names (device_map_t& devices); + + /* + * @return true if there were devices found for the driver + * + * @param driver The driver name returned by get_jack_audio_driver_names + * @param devices The map used to insert the drivers into, devices will be cleared before + * adding the available drivers + */ + bool get_jack_device_names_for_audio_driver (const std::string& driver, device_map_t& devices); + + /* + * @return a list of readable device names for a specific driver. + */ + std::vector<std::string> get_jack_device_names_for_audio_driver (const std::string& driver); + + /** + * @return true if the driver supports playback and recording + * on separate devices + */ + bool get_jack_audio_driver_supports_two_devices (const std::string& driver); + + bool get_jack_audio_driver_supports_latency_adjustment (const std::string& driver); + + bool get_jack_audio_driver_supports_setting_period_count (const std::string& driver); + + /** + * The possible names to use to try and find servers, this includes + * any file extensions like .exe on Windows + * + * @return true if the JACK application names for this platform could be guessed + */ + bool get_jack_server_application_names (std::vector<std::string>& server_names); + + /** + * Sets the PATH environment variable to contain directories likely to contain + * JACK servers so that if the JACK server is auto-started it can find the server + * executable. + * + * This is only modifies PATH on the mac at the moment. + */ + void set_path_env_for_jack_autostart (const std::vector<std::string>&); + + /** + * Get absolute paths to directories that might contain JACK servers on the system + * + * @return true if !server_paths.empty() + */ + bool get_jack_server_dir_paths (std::vector<std::string>& server_dir_paths); + + /** + * Get absolute paths to JACK servers on the system + * + * @return true if a server was found + */ + bool get_jack_server_paths (const std::vector<std::string>& server_dir_paths, + const std::vector<std::string>& server_names, + std::vector<std::string>& server_paths); + + + bool get_jack_server_paths (std::vector<std::string>& server_paths); + + /** + * Get absolute path to default JACK server + */ + bool get_jack_default_server_path (std::string& server_path); + + /** + * @return The name of the jack server config file + */ + std::string get_jack_server_config_file_name (); + + std::string get_jack_server_user_config_dir_path (); + + std::string get_jack_server_user_config_file_path (); + + bool write_jack_config_file (const std::string& config_file_path, const std::string& command_line); + + struct JackCommandLineOptions { + + // see implementation for defaults + JackCommandLineOptions (); + + //operator bool + //operator ostream + + std::string server_path; + uint32_t timeout; + bool no_mlock; + uint32_t ports_max; + bool realtime; + uint32_t priority; + bool unlock_gui_libs; + bool verbose; + bool temporary; + bool playback_only; + bool capture_only; + std::string driver; + std::string input_device; + std::string output_device; + uint32_t num_periods; + uint32_t period_size; + uint32_t samplerate; + uint32_t input_latency; + uint32_t output_latency; + bool hardware_metering; + bool hardware_monitoring; + std::string dither_mode; + bool force16_bit; + bool soft_mode; + std::string midi_driver; + }; + + /** + * @return true if able to build a valid command line based on options + */ + bool get_jack_command_line_string (const JackCommandLineOptions& options, std::string& command_line); + + /** + * We don't need this at the moment because the gui stores all its settings + */ + //std::string get_jack_command_line_from_config_file (const std::string& config_file_path); +} diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index 4444686dcb..a3b99575fe 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -23,8 +23,8 @@ #include <set> #include <vector> #include <string> -#include <dlfcn.h> +#include <glibmm/module.h> #include "pbd/stateful.h" @@ -39,7 +39,7 @@ class Session; class LIBARDOUR_API LadspaPlugin : public ARDOUR::Plugin { public: - LadspaPlugin (void *module, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, framecnt_t sample_rate); + LadspaPlugin (std::string module_path, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, framecnt_t sample_rate); LadspaPlugin (const LadspaPlugin &); ~LadspaPlugin (); @@ -122,7 +122,8 @@ class LIBARDOUR_API LadspaPlugin : public ARDOUR::Plugin void connect_port (uint32_t port, float *ptr) { _descriptor->connect_port (_handle, port, ptr); } private: - void* _module; + std::string _module_path; + Glib::Module* _module; const LADSPA_Descriptor* _descriptor; LADSPA_Handle _handle; framecnt_t _sample_rate; @@ -134,7 +135,7 @@ class LIBARDOUR_API LadspaPlugin : public ARDOUR::Plugin void find_presets (); - void init (void *mod, uint32_t index, framecnt_t rate); + void init (std::string module_path, uint32_t index, framecnt_t rate); void run_in_place (pframes_t nsamples); void latency_compute_run (); int set_state_2X (const XMLNode&, int version); diff --git a/libs/ardour/ardour/ladspa_search_path.h b/libs/ardour/ardour/ladspa_search_path.h new file mode 100644 index 0000000000..bc184b5248 --- /dev/null +++ b/libs/ardour/ardour/ladspa_search_path.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2011 Tim Mayberry + + 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 ARDOUR_LADSPA_SEARCH_PATH_INCLUDED +#define ARDOUR_LADSPA_SEARCH_PATH_INCLUDED + +#include "pbd/search_path.h" + +namespace ARDOUR { + + /** + * return a Searchpath containing directories in which to look for + * LADSPA plugins. + * + * If LADSPA_PATH is defined then the Searchpath returned + * will contain the directories specified in it as well as the + * user and system directories. + */ + PBD::Searchpath ladspa_search_path (); + +} // namespace ARDOUR + +#endif diff --git a/libs/ardour/ardour/lv2_bundled_search_path.h b/libs/ardour/ardour/lv2_bundled_search_path.h index f5780c5e0e..9314ee27d4 100644 --- a/libs/ardour/ardour/lv2_bundled_search_path.h +++ b/libs/ardour/ardour/lv2_bundled_search_path.h @@ -25,10 +25,10 @@ namespace ARDOUR { /** - * return a SearchPath containing directories in which to look for + * return a Searchpath containing directories in which to look for * lv2 plugins. */ - PBD::SearchPath lv2_bundled_search_path (); + PBD::Searchpath lv2_bundled_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index a9cb2cb260..034101ee41 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -29,6 +29,8 @@ #include "ardour/worker.h" #include "pbd/ringbuffer.h" +typedef struct LV2_Evbuf_Impl LV2_Evbuf; + namespace ARDOUR { // a callback function for lilv_state_new_from_instance(). friend of LV2Plugin diff --git a/libs/ardour/ardour/midi_patch_search_path.h b/libs/ardour/ardour/midi_patch_search_path.h index 5d27823461..168e75af4a 100644 --- a/libs/ardour/ardour/midi_patch_search_path.h +++ b/libs/ardour/ardour/midi_patch_search_path.h @@ -24,15 +24,15 @@ namespace ARDOUR { /** - * return a SearchPath containing directories in which to look for + * return a Searchpath containing directories in which to look for * MIDI patch files ("*.midnam") aka MIDNAM files * - * If ARDOUR_MIDI_PATCH_PATH is defined then the SearchPath returned + * If ARDOUR_MIDI_PATCH_PATH is defined then the Searchpath returned * will contain only those directories specified in it, otherwise it will * contain the user and system directories which may contain control * surface plugins. */ - PBD::SearchPath midi_patch_search_path (); + PBD::Searchpath midi_patch_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index e53b4a4ee0..b118214c9e 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -32,7 +32,6 @@ namespace ARDOUR { class Session; -class Region; class MidiRegion; class Source; template<typename T> class MidiRingBuffer; diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 7e53c5a292..cf6d3f7b64 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -20,6 +20,8 @@ #ifndef __ardour_midi_track_h__ #define __ardour_midi_track_h__ +#include "pbd/ffs.h" + #include "ardour/track.h" #include "ardour/midi_ring_buffer.h" @@ -183,7 +185,7 @@ private: /* if mode is ForceChannel, force mask to the lowest set channel or 1 if no * channels are set. */ -#define force_mask(mode,mask) (((mode) == ForceChannel) ? (((mask) ? (1<<(ffs((mask))-1)) : 1)) : mask) +#define force_mask(mode,mask) (((mode) == ForceChannel) ? (((mask) ? (1<<(PBD::ffs((mask))-1)) : 1)) : mask) void _set_playback_channel_mode(ChannelMode mode, uint16_t mask) { mask = force_mask (mode, mask); diff --git a/libs/ardour/ardour/msvc_libardour.h b/libs/ardour/ardour/msvc_libardour.h new file mode 100644 index 0000000000..52aa65d95c --- /dev/null +++ b/libs/ardour/ardour/msvc_libardour.h @@ -0,0 +1,71 @@ +/* + 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 "ardour/visibility.h" +#include <limits.h> + +#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/panner.h b/libs/ardour/ardour/panner.h index 47b102989b..48f583c185 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -35,6 +35,18 @@ #include "ardour/automation_control.h" #include "ardour/automatable.h" + +/* This section is for actual panners to use. They will include this file, + * declare ARDOURPANNER_DLL_EXPORTS during compilation, and ... voila. + */ + +#ifdef ARDOURPANNER_DLL_EXPORTS // defined if we are building a panner implementation + #define ARDOURPANNER_API LIBARDOUR_DLL_EXPORT + #else + #define ARDOURPANNER_API LIBARDOUR_DLL_IMPORT + #endif +#define ARDOURPANNER_LOCAL LIBARDOUR_DLL_LOCAL + namespace ARDOUR { class Session; diff --git a/libs/ardour/ardour/panner_manager.h b/libs/ardour/ardour/panner_manager.h index 619beb454f..80f8e8010a 100644 --- a/libs/ardour/ardour/panner_manager.h +++ b/libs/ardour/ardour/panner_manager.h @@ -20,7 +20,8 @@ #ifndef __ardour_panner_manager_h__ #define __ardour_panner_manager_h__ -#include <dlfcn.h> +#include <glibmm/module.h> + #include "ardour/panner.h" #include "ardour/session_handle.h" @@ -28,15 +29,15 @@ namespace ARDOUR { struct LIBARDOUR_API PannerInfo { PanPluginDescriptor descriptor; - void* module; + Glib::Module* module; - PannerInfo (PanPluginDescriptor& d, void* handle) + PannerInfo (PanPluginDescriptor& d, Glib::Module* m) : descriptor (d) - , module (handle) + , module (m) {} ~PannerInfo () { - dlclose (module); + delete module; } }; diff --git a/libs/ardour/ardour/panner_search_path.h b/libs/ardour/ardour/panner_search_path.h index 889b9efb23..23004223b4 100644 --- a/libs/ardour/ardour/panner_search_path.h +++ b/libs/ardour/ardour/panner_search_path.h @@ -24,15 +24,15 @@ namespace ARDOUR { /** - * return a SearchPath containing directories in which to look for + * return a Searchpath containing directories in which to look for * panner plugins. * - * If ARDOUR_PANNER_PATH is defined then the SearchPath returned + * If ARDOUR_PANNER_PATH is defined then the Searchpath returned * will contain only those directories specified in it, otherwise it will * contain the user and system directories which may contain control * surface plugins. */ - PBD::SearchPath panner_search_path (); + PBD::Searchpath panner_search_path (); } // namespace ARDOUR diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 08ecd10853..5629a04629 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -41,13 +41,13 @@ #include "evoral/types.hpp" #include "ardour/ardour.h" +#include "ardour/region.h" #include "ardour/session_object.h" #include "ardour/data_type.h" namespace ARDOUR { class Session; -class Region; class Playlist; class Crossfade; diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index 73de0eb704..bee1c68704 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -52,7 +52,6 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable { void refresh (); - int add_ladspa_directory (std::string dirpath); int add_windows_vst_directory (std::string dirpath); int add_lxvst_directory (std::string dirpath); @@ -104,7 +103,6 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable { std::map<uint32_t, std::string> rdf_type; - std::string ladspa_path; std::string windows_vst_path; std::string lxvst_path; @@ -128,7 +126,6 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable { int lxvst_discover_from_path (std::string path); int lxvst_discover (std::string path); - int ladspa_discover_from_path (std::string path); int ladspa_discover (std::string path); std::string get_ladspa_category (uint32_t id); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 01a2cc9054..08f4c1315a 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -830,7 +830,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void request_resume_timecode_transmission (); bool timecode_transmission_suspended () const; - std::string source_search_path(DataType) const; + std::vector<std::string> source_search_path(DataType) const; void ensure_search_path_includes (const std::string& path, DataType type); std::list<std::string> unknown_processors () const; diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h index 0af357a613..cf6462247a 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 9b3da1701d..25b8f003b2 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -46,6 +46,7 @@ class LIBARDOUR_API 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/async_midi_port.cc b/libs/ardour/async_midi_port.cc index 5bc8e22833..bd583328c3 100644 --- a/libs/ardour/async_midi_port.cc +++ b/libs/ardour/async_midi_port.cc @@ -19,6 +19,9 @@ */ #include <iostream> +#include <vector> + +#include <glibmm/timer.h> #include "pbd/error.h" #include "pbd/stacktrace.h" @@ -35,7 +38,7 @@ using namespace std; using namespace PBD; namespace Evoral { - template class EventRingBuffer<timestamp_t>; + template class EventRingBuffer<MIDI::timestamp_t>; } pthread_t AsyncMIDIPort::_process_thread; @@ -49,7 +52,9 @@ AsyncMIDIPort::AsyncMIDIPort (string const & name, PortFlags flags) , _last_write_timestamp (0) , output_fifo (512) , input_fifo (1024) +#ifndef PLATFORM_WINDOWS , xthread (true) +#endif { } @@ -58,7 +63,7 @@ AsyncMIDIPort::~AsyncMIDIPort () } void -AsyncMIDIPort::flush_output_fifo (pframes_t nframes) +AsyncMIDIPort::flush_output_fifo (MIDI::pframes_t nframes) { RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0 } }; size_t written; @@ -89,7 +94,7 @@ AsyncMIDIPort::flush_output_fifo (pframes_t nframes) } void -AsyncMIDIPort::cycle_start (pframes_t nframes) +AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes) { _currently_in_cycle = true; MidiPort::cycle_start (nframes); @@ -113,16 +118,17 @@ AsyncMIDIPort::cycle_start (pframes_t nframes) for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) { input_fifo.write (when, (Evoral::EventType) 0, (*b).size(), (*b).buffer()); } - + +#ifndef PLATFORM_WINDOWS if (!mb.empty()) { xthread.wakeup (); } +#endif } - } void -AsyncMIDIPort::cycle_end (pframes_t nframes) +AsyncMIDIPort::cycle_end (MIDI::pframes_t nframes) { if (ARDOUR::Port::sends_output()) { /* move any additional data from output FIFO into the port @@ -161,12 +167,12 @@ AsyncMIDIPort::drain (int check_interval_usecs) if (vec.len[0] + vec.len[1] >= output_fifo.bufsize() - 1) { break; } - usleep (check_interval_usecs); + Glib::usleep (check_interval_usecs); } } int -AsyncMIDIPort::write (const byte * msg, size_t msglen, timestamp_t timestamp) +AsyncMIDIPort::write (const MIDI::byte * msg, size_t msglen, MIDI::timestamp_t timestamp) { int ret = 0; @@ -219,7 +225,7 @@ AsyncMIDIPort::write (const byte * msg, size_t msglen, timestamp_t timestamp) } if (timestamp >= _cycle_nframes) { - std::cerr << "attempting to write MIDI event of " << msglen << " bytes at time " + std::cerr << "attempting to write MIDI event of " << msglen << " MIDI::bytes at time " << timestamp << " of " << _cycle_nframes << " (this will not work - needs a code fix)" << std::endl; @@ -268,9 +274,9 @@ AsyncMIDIPort::read (MIDI::byte *, size_t) timestamp_t time; Evoral::EventType type; uint32_t size; - byte buffer[input_fifo.capacity()]; + vector<MIDI::byte> buffer(input_fifo.capacity()); - while (input_fifo.read (&time, &type, &size, buffer)) { + while (input_fifo.read (&time, &type, &size, &buffer[0])) { _parser->set_timestamp (time); for (uint32_t i = 0; i < size; ++i) { _parser->scanner (buffer[i]); @@ -281,7 +287,7 @@ AsyncMIDIPort::read (MIDI::byte *, size_t) } void -AsyncMIDIPort::parse (framecnt_t) +AsyncMIDIPort::parse (MIDI::framecnt_t) { MIDI::byte buf[1]; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index a9f9f40d64..f4d10c2043 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -27,8 +27,6 @@ #include <fcntl.h> #include <cstdlib> #include <ctime> -#include <sys/stat.h> -#include <sys/mman.h> #include "pbd/error.h" #include "pbd/xml++.h" @@ -925,7 +923,7 @@ AudioDiskstream::internal_playback_seek (framecnt_t distance) boost::shared_ptr<ChannelList> c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->playback_buf->increment_read_ptr (std::llabs(distance)); + (*chan)->playback_buf->increment_read_ptr (llabs(distance)); } if (first_recordable_frame < max_framepos) { diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc index c2b2f1bff7..4a6089dac3 100644 --- a/libs/ardour/audio_library.cc +++ b/libs/ardour/audio_library.cc @@ -17,11 +17,18 @@ */ +#ifdef WAF_BUILD +#include "libardour-config.h" +#endif + #include <sstream> #include <libxml/uri.h> +#ifdef HAVE_LRDF #include <lrdf.h> +#endif + #include <glibmm/miscutils.h> #include <glibmm/convert.h> @@ -57,7 +64,9 @@ AudioLibrary::AudioLibrary () touch_file(sfdb_file_path); +#ifdef HAVE_LRDF lrdf_read_file(src.c_str()); +#endif } AudioLibrary::~AudioLibrary () @@ -67,14 +76,17 @@ AudioLibrary::~AudioLibrary () void AudioLibrary::save_changes () { +#ifdef HAVE_LRDF if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) { PBD::warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg; } +#endif } void AudioLibrary::set_tags (string member, vector<string> tags) { +#ifdef HAVE_LRDF sort (tags.begin(), tags.end()); tags.erase (unique(tags.begin(), tags.end()), tags.end()); @@ -85,12 +97,14 @@ AudioLibrary::set_tags (string member, vector<string> tags) for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) { lrdf_add_triple (src.c_str(), file_uri.c_str(), TAG, (*i).c_str(), lrdf_literal); } +#endif } vector<string> AudioLibrary::get_tags (string member) { vector<string> tags; +#ifdef HAVE_LRDF lrdf_statement pattern; pattern.subject = strdup(Glib::filename_to_uri(member).c_str()); @@ -111,13 +125,14 @@ AudioLibrary::get_tags (string member) lrdf_free_statements (matches); sort (tags.begin(), tags.end()); - +#endif return tags; } void AudioLibrary::search_members_and (vector<string>& members, const vector<string>& tags) { +#ifdef HAVE_LRDF lrdf_statement **head; lrdf_statement* pattern = 0; lrdf_statement* old = 0; @@ -153,4 +168,5 @@ AudioLibrary::search_members_and (vector<string>& members, const vector<string>& pattern = pattern->next; delete old; } +#endif } diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 7f77f637a3..a82c109cba 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -315,7 +315,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram if (!lm.locked()) { boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes); - if (can_internal_playback_seek(std::llabs(playback_distance))) { + if (can_internal_playback_seek(llabs(playback_distance))) { /* TODO should declick */ internal_playback_seek(playback_distance); } diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 538a905ca2..1a24977399 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -34,6 +34,7 @@ #include <glibmm/threads.h> #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> +#include <glib/gstdio.h> #include "ardour/ardour.h" #include "ardour/audioengine.h" @@ -2453,7 +2454,7 @@ AUPluginInfo::save_cached_info () if (!tree.write (path)) { error << string_compose (_("could not save AU cache to %1"), path) << endmsg; - unlink (path.c_str()); + g_unlink (path.c_str()); } } diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 82564ebaf2..cb167c9595 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -34,8 +34,6 @@ #include "pbd/stacktrace.h" #include "pbd/unknown_type.h" -#include <jack/weakjack.h> - #include "midi++/port.h" #include "midi++/mmc.h" @@ -474,8 +472,17 @@ AudioEngine::discover_backends () Glib::PatternSpec so_extension_pattern("*backend.so"); Glib::PatternSpec dylib_extension_pattern("*backend.dylib"); - Glib::PatternSpec dll_extension_pattern("*backend.dll"); +#if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS) + #if defined(DEBUG) || defined(_DEBUG) + Glib::PatternSpec dll_extension_pattern("*backendD.dll"); + #else + Glib::PatternSpec dll_extension_pattern("*backendRDC.dll"); + #endif +#else + Glib::PatternSpec dll_extension_pattern("*backend.dll"); +#endif + find_matching_files_in_search_path (backend_search_path (), so_extension_pattern, backend_modules); diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 13b03f8f48..014baa9031 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -40,6 +40,7 @@ #include <sndfile.h> +#include <glib/gstdio.h> #include <glibmm/miscutils.h> #include <glibmm/fileutils.h> #include <glibmm/threads.h> @@ -133,8 +134,8 @@ AudioFileSource::~AudioFileSource () { DEBUG_TRACE (DEBUG::Destruction, string_compose ("AudioFileSource destructor %1, removable? %2\n", _path, removable())); if (removable()) { - unlink (_path.c_str()); - unlink (peakpath.c_str()); + ::g_unlink (_path.c_str()); + ::g_unlink (peakpath.c_str()); } } @@ -292,7 +293,7 @@ AudioFileSource::mark_streaming_write_completed () int AudioFileSource::move_dependents_to_trash() { - return ::unlink (peakpath.c_str()); + return ::g_unlink (peakpath.c_str()); } void diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 3c6d4f81b8..d0b6205cb2 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -17,12 +17,15 @@ */ -#include <sys/stat.h> +#ifdef COMPILER_MSVC +#include <sys/utime.h> +#else #include <unistd.h> +#include <utime.h> +#endif +#include <sys/stat.h> #include <fcntl.h> -#include <poll.h> #include <float.h> -#include <utime.h> #include <cerrno> #include <ctime> #include <cmath> @@ -31,6 +34,12 @@ #include <algorithm> #include <vector> +#include <glib.h> +#include <glib/gstdio.h> + +#include <boost/scoped_array.hpp> +#include <boost/scoped_ptr.hpp> + #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> @@ -42,6 +51,8 @@ #include "i18n.h" +#include "ardour/debug.h" + using namespace std; using namespace ARDOUR; using namespace PBD; @@ -173,9 +184,9 @@ AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnect void AudioSource::touch_peakfile () { - struct stat statbuf; + GStatBuf statbuf; - if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) { + if (g_stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) { return; } @@ -184,7 +195,7 @@ AudioSource::touch_peakfile () tbuf.actime = statbuf.st_atime; tbuf.modtime = time ((time_t*) 0); - utime (peakpath.c_str(), &tbuf); + g_utime (peakpath.c_str(), &tbuf); } int @@ -195,7 +206,7 @@ AudioSource::rename_peakfile (string newpath) string oldpath = peakpath; if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) { - if (rename (oldpath.c_str(), newpath.c_str()) != 0) { + if (g_rename (oldpath.c_str(), newpath.c_str()) != 0) { error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg; return -1; } @@ -209,17 +220,19 @@ AudioSource::rename_peakfile (string newpath) int AudioSource::initialize_peakfile (string audio_path) { - struct stat statbuf; + GStatBuf statbuf; peakpath = peak_path (audio_path); + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", peakpath, audio_path)); + /* if the peak file should be there, but isn't .... */ if (!empty() && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { peakpath = find_broken_peakfile (peakpath, audio_path); } - if (stat (peakpath.c_str(), &statbuf)) { + if (g_stat (peakpath.c_str(), &statbuf)) { if (errno != ENOENT) { /* it exists in the peaks dir, but there is some kind of error */ @@ -227,7 +240,7 @@ AudioSource::initialize_peakfile (string audio_path) return -1; } - /* peakfile does not exist */ + DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", peakpath)); _peaks_built = false; @@ -236,7 +249,7 @@ AudioSource::initialize_peakfile (string audio_path) /* we found it in the peaks dir, so check it out */ if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) { - // empty + DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", peakpath)); _peaks_built = false; } else { // Check if the audio file has changed since the peakfile was built. @@ -248,6 +261,7 @@ AudioSource::initialize_peakfile (string audio_path) /* no audio path - nested source or we can't read it or ... whatever, use the peakfile as-is. */ + DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", peakpath)); _peaks_built = true; _peak_byte_max = statbuf.st_size; @@ -316,28 +330,15 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t int32_t to_read; uint32_t nread; framecnt_t zero_fill = 0; - int ret = -1; - PeakData* staging = 0; - Sample* raw_staging = 0; - FdFileDescriptor* peakfile_descriptor = new FdFileDescriptor (peakpath, false, 0664); + boost::scoped_ptr<FdFileDescriptor> peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664)); int peakfile_fd = -1; expected_peaks = (cnt / (double) samples_per_file_peak); scale = npeaks/expected_peaks; -#undef DEBUG_READ_PEAKS -#ifdef DEBUG_READ_PEAKS - cerr << "======>RP: npeaks = " << npeaks - << " start = " << start - << " cnt = " << cnt - << " len = " << _length - << " samples_per_visual_peak =" << samples_per_visual_peak - << " expected was " << expected_peaks << " ... scale = " << scale - << " PD ptr = " << peaks - <<endl; - -#endif + DEBUG_TRACE (DEBUG::Peaks, string_compose (" ======>RP: npeaks = %1 start = %2 cnt = %3 len = %4 samples_per_visual_peak = %5 expected was %6 ... scale = %7 PD ptr = %8\n" + , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks)); /* fix for near-end-of-file conditions */ @@ -353,16 +354,15 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (npeaks == cnt) { -#ifdef DEBUG_READ_PEAKS - cerr << "RAW DATA\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n"); + /* no scaling at all, just get the sample data and duplicate it for both max and min peak values. */ - Sample* raw_staging = new Sample[cnt]; + boost::scoped_array<Sample> raw_staging(new Sample[cnt]); - if (read_unlocked (raw_staging, start, cnt) != cnt) { + if (read_unlocked (raw_staging.get(), start, cnt) != cnt) { error << _("cannot read sample data for unscaled peak computation") << endmsg; return -1; } @@ -372,43 +372,35 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t peaks[i].min = raw_staging[i]; } - delete peakfile_descriptor; - delete [] raw_staging; return 0; } if (scale == 1.0) { + off_t offset = 0; off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData); - + ssize_t bytes_to_read = sizeof (PeakData)* npeaks; /* open, read, close */ if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - delete peakfile_descriptor; return -1; } -#ifdef DEBUG_READ_PEAKS - cerr << "DIRECT PEAKS\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n"); - nread = ::pread (peakfile_fd, peaks, sizeof (PeakData)* npeaks, first_peak_byte); - - if (nread != sizeof (PeakData) * npeaks) { - cerr << "AudioSource[" - << _name - << "]: cannot read peaks from peakfile! (read only " - << nread - << " not " - << npeaks - << "at sample " - << start - << " = byte " - << first_peak_byte - << ')' - << endl; - delete peakfile_descriptor; + offset = lseek (peakfile_fd, first_peak_byte, SEEK_SET); + + if (offset != first_peak_byte) { + error << string_compose(_("AudioSource: could not seek to correct location in peak file \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; + return -1; + } + + nread = ::read (peakfile_fd, peaks, bytes_to_read); + + if (nread != bytes_to_read) { + DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: Cannot read peaks from peakfile! (read only %2 not %3 at sample %4 = byte %5 )\n" + , _name, nread, npeaks, start, first_peak_byte)); return -1; } @@ -416,7 +408,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - delete peakfile_descriptor; return 0; } @@ -425,9 +416,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (scale < 1.0) { -#ifdef DEBUG_READ_PEAKS - cerr << "DOWNSAMPLE\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n"); + /* the caller wants: - more frames-per-peak (lower resolution) than the peakfile, or to put it another way, @@ -440,7 +430,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0); - staging = new PeakData[chunksize]; + boost::scoped_array<PeakData> staging(new PeakData[chunksize]); /* compute the rounded up frame position */ @@ -461,8 +451,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - delete peakfile_descriptor; - delete [] staging; return 0; } @@ -473,33 +461,27 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t uint32_t start_byte = current_stored_peak * sizeof(PeakData); tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks); to_read = min (chunksize, tnp); + ssize_t bytes_to_read = sizeof (PeakData) * to_read; -#ifdef DEBUG_READ_PEAKS - cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl; -#endif + DEBUG_TRACE (DEBUG::Peaks, string_compose ("reading %1 bytes from peakfile @ %2\n" + , bytes_to_read, start_byte)); - if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte)) - != sizeof (PeakData) * to_read) { - off_t fend = lseek (peakfile_fd, 0, SEEK_END); + off_t offset = lseek (peakfile_fd, start_byte, SEEK_SET); - cerr << "AudioSource[" - << _name - << "]: cannot read peak data from peakfile (" - << (nread / sizeof(PeakData)) - << " peaks instead of " - << to_read - << ") (" - << strerror (errno) - << ')' - << " at start_byte = " << start_byte - << " _length = " << _length << " versus len = " << fend - << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak - << " npeaks was " << npeaks - << endl; - goto out; + if (offset != start_byte) { + error << string_compose(_("AudioSource: could not seek to correct location in peak file \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; + return -1; } + if ((nread = ::read (peakfile_fd, staging.get(), bytes_to_read)) != bytes_to_read) { + + off_t fend = lseek (peakfile_fd, 0, SEEK_END); + + DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: cannot read peak data from peakfile (%2 peaks instead of %3) (%4) at start_byte = %5 _length = %6 versus len = %7 expected maxpeaks = %8 npeaks was %9" + , _name, (nread / sizeof(PeakData)), to_read, g_strerror (errno), start_byte, _length, fend, ((_length - current_frame)/samples_per_file_peak), npeaks)); + return -1; + } i = 0; stored_peaks_read = nread / sizeof(PeakData); } @@ -531,13 +513,10 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - ret = 0; - } else { -#ifdef DEBUG_READ_PEAKS - cerr << "UPSAMPLE\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n"); + /* the caller wants - less frames-per-peak (more resolution) @@ -552,7 +531,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t framecnt_t i = 0; framecnt_t nvisual_peaks = 0; framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096); - raw_staging = new Sample[chunksize]; + boost::scoped_array<Sample> raw_staging(new Sample[chunksize]); framepos_t frame_pos = start; double pixel_pos = floor (frame_pos / samples_per_visual_peak); @@ -577,18 +556,18 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t this loop early */ - memset (raw_staging, 0, sizeof (Sample) * chunksize); + memset (raw_staging.get(), 0, sizeof (Sample) * chunksize); } else { to_read = min (chunksize, (_length - current_frame)); - if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) { + if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) { error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"), _name, to_read, current_frame, _length, strerror (errno)) << endmsg; - goto out; + return -1; } } @@ -616,32 +595,19 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (zero_fill) { memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - - ret = 0; } - out: - delete peakfile_descriptor; - - delete [] staging; - delete [] raw_staging; - -#ifdef DEBUG_READ_PEAKS - cerr << "RP DONE\n"; -#endif - - return ret; + DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n"); + return 0; } -#undef DEBUG_PEAK_BUILD - int AudioSource::build_peaks_from_scratch () { - Sample* buf = 0; - const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal + DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n"); + int ret = -1; { @@ -657,20 +623,20 @@ AudioSource::build_peaks_from_scratch () framecnt_t cnt = _length; _peaks_built = false; - buf = new Sample[bufsize]; + boost::scoped_array<Sample> buf(new Sample[bufsize]); while (cnt) { framecnt_t frames_to_read = min (bufsize, cnt); framecnt_t frames_read; - if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) { + if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) { error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg; done_with_peakfile_writes (false); goto out; } - if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) { + if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) { break; } @@ -691,11 +657,10 @@ AudioSource::build_peaks_from_scratch () out: if (ret) { - unlink (peakpath.c_str()); + DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath)); + ::g_unlink (peakpath.c_str()); } - delete [] buf; - return ret; } @@ -739,15 +704,13 @@ int AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt, bool force, bool intermediate_peaks_ready, framecnt_t fpp) { - Sample* buf2 = 0; framecnt_t to_do; uint32_t peaks_computed; - PeakData* peakbuf = 0; - int ret = -1; framepos_t current_frame; framecnt_t frames_done; const size_t blocksize = (128 * 1024); off_t first_peak_byte; + boost::scoped_array<Sample> buf2; if (_peakfile_descriptor == 0) { prepare_for_peakfile_writes (); @@ -770,9 +733,16 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData); - if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { + off_t offset = lseek (_peakfile_fd, byte, SEEK_SET); + + if (offset != byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; + return -1; } _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); @@ -798,19 +768,19 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame /* make a new contiguous buffer containing leftovers and the new stuff */ to_do = cnt + peak_leftover_cnt; - buf2 = new Sample[to_do]; + buf2.reset(new Sample[to_do]); /* the remnants */ - memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample)); + memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample)); /* the new stuff */ - memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample)); + memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample)); /* no more leftovers */ peak_leftover_cnt = 0; /* use the temporary buffer */ - buf = buf2; + buf = buf2.get(); /* make sure that when we write into the peakfile, we startup where we left off */ @@ -820,7 +790,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame to_do = cnt; } - peakbuf = new PeakData[(to_do/fpp)+1]; + boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]); peaks_computed = 0; current_frame = first_frame; frames_done = 0; @@ -877,18 +847,31 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize); if (endpos < target_length) { + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath)); if (ftruncate (_peakfile_fd, target_length)) { /* error doesn't actually matter so continue on without testing */ } } } - if (::pwrite (_peakfile_fd, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { + + off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET); + + if (offset != first_peak_byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed; + + ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write); + + if (bytes_written != bytes_to_write) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; + return -1; } - _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); + _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write)); if (frames_done) { Glib::Threads::Mutex::Lock lm (_peaks_ready_lock); @@ -898,13 +881,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame } } - ret = 0; - - out: - delete [] peakbuf; - delete [] buf2; - - return ret; + return 0; } void @@ -921,6 +898,7 @@ AudioSource::truncate_peakfile () off_t end = lseek (_peakfile_fd, 0, SEEK_END); if (end > _peak_byte_max) { + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath)); if (ftruncate (_peakfile_fd, _peak_byte_max)) { error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"), peakpath, _peak_byte_max, errno) << endmsg; diff --git a/libs/ardour/automation_watch.cc b/libs/ardour/automation_watch.cc index 16e10c95f9..91fe4d38ed 100644 --- a/libs/ardour/automation_watch.cc +++ b/libs/ardour/automation_watch.cc @@ -19,6 +19,8 @@ #include <iostream> +#include <glibmm/timer.h> + #include "pbd/compose.h" #include "ardour/automation_control.h" @@ -134,7 +136,7 @@ void AutomationWatch::thread () { while (_run_thread) { - usleep ((useconds_t) floor (Config->get_automation_interval_msecs() * 1000)); + Glib::usleep ((gulong) floor (Config->get_automation_interval_msecs() * 1000)); timer (); } } diff --git a/libs/ardour/backend_search_path.cc b/libs/ardour/backend_search_path.cc index 9a0425094b..4c5ff40e7d 100644 --- a/libs/ardour/backend_search_path.cc +++ b/libs/ardour/backend_search_path.cc @@ -31,14 +31,14 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath backend_search_path () { - SearchPath spath(user_config_directory ()); + Searchpath spath(user_config_directory ()); spath += ardour_dll_directory (); spath.add_subdirectory_to_paths(backend_dir_name); - spath += SearchPath(Glib::getenv(backend_env_variable_name)); + spath += Searchpath(Glib::getenv(backend_env_variable_name)); return spath; } diff --git a/libs/ardour/broadcast_info.cc b/libs/ardour/broadcast_info.cc index a7fa41aaf9..a08d2c7991 100644 --- a/libs/ardour/broadcast_info.cc +++ b/libs/ardour/broadcast_info.cc @@ -22,6 +22,7 @@ #include <iostream> #include <sstream> #include <iomanip> +#include <vector> #include <glibmm.h> @@ -37,15 +38,15 @@ namespace ARDOUR static void snprintf_bounded_null_filled (char* target, size_t target_size, char const * fmt, ...) { - char buf[target_size+1]; + std::vector<char> buf(target_size+1); va_list ap; va_start (ap, fmt); - vsnprintf (buf, target_size+1, fmt, ap); + vsnprintf (&buf[0], target_size+1, fmt, ap); va_end (ap); memset (target, 0, target_size); - memcpy (target, buf, target_size); + memcpy (target, &buf[0], target_size); } @@ -84,7 +85,7 @@ BroadcastInfo::set_originator_ref_from_session (Session const & /*session*/) /* random code is 9 digits */ - int random_code = random() % 999999999; + int random_code = g_random_int() % 999999999; /* Serial number is 12 chars */ diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index 89b2cc1303..1fe1524618 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -20,7 +20,11 @@ #include <errno.h> #include <fcntl.h> #include <unistd.h> + +#ifndef PLATFORM_WINDOWS #include <poll.h> +#endif + #include "pbd/error.h" #include "pbd/pthread_utils.h" #include "ardour/butler.h" @@ -38,7 +42,7 @@ namespace ARDOUR { Butler::Butler(Session& s) : SessionHandleRef (s) - , thread(0) + , thread() , audio_dstream_capture_buffer_size(0) , audio_dstream_playback_buffer_size(0) , midi_dstream_buffer_size(0) @@ -68,25 +72,10 @@ Butler::config_changed (std::string p) } } +#ifndef PLATFORM_WINDOWS int -Butler::start_thread() +Butler::setup_request_pipe () { - const float rate = (float)_session.frame_rate(); - - /* size is in Samples, not bytes */ - audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * rate); - audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * rate); - - /* size is in bytes - * XXX: Jack needs to tell us the MIDI buffer size - * (i.e. how many MIDI bytes we might see in a cycle) - */ - midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * rate); - - MidiDiskstream::set_readahead_frames ((framecnt_t) (Config->get_midi_readahead() * rate)); - - should_run = false; - if (pipe (request_pipe)) { error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg; @@ -104,6 +93,32 @@ Butler::start_thread() strerror (errno)) << endmsg; return -1; } + return 0; +} +#endif + +int +Butler::start_thread() +{ + const float rate = (float)_session.frame_rate(); + + /* size is in Samples, not bytes */ + audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * rate); + audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * rate); + + /* size is in bytes + * XXX: Jack needs to tell us the MIDI buffer size + * (i.e. how many MIDI bytes we might see in a cycle) + */ + midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * rate); + + MidiDiskstream::set_readahead_frames ((framecnt_t) (Config->get_midi_readahead() * rate)); + + should_run = false; + +#ifndef PLATFORM_WINDOWS + if (setup_request_pipe() != 0) return -1; +#endif if (pthread_create_and_store ("disk butler", &thread, _thread_work, this)) { error << _("Session: could not create butler thread") << endmsg; @@ -118,12 +133,9 @@ Butler::start_thread() void Butler::terminate_thread () { - if (thread) { - void* status; - const char c = Request::Quit; - (void) ::write (request_pipe[1], &c, 1); - pthread_join (thread, &status); - } + void* status; + queue_request (Request::Quit); + pthread_join (thread, &status); } void * @@ -134,28 +146,25 @@ Butler::_thread_work (void* arg) return ((Butler *) arg)->thread_work (); } -void * -Butler::thread_work () +bool +Butler::wait_for_requests () { - uint32_t err = 0; - +#ifndef PLATFORM_WINDOWS struct pollfd pfd[1]; - bool disk_work_outstanding = false; - RouteList::iterator i; - while (true) { - pfd[0].fd = request_pipe[0]; - pfd[0].events = POLLIN|POLLERR|POLLHUP; + pfd[0].fd = request_pipe[0]; + pfd[0].events = POLLIN|POLLERR|POLLHUP; - if (poll (pfd, 1, (disk_work_outstanding ? 0 : -1)) < 0) { + while(true) { + if (poll (pfd, 1, -1) < 0) { if (errno == EINTR) { continue; } error << string_compose (_("poll on butler request pipe failed (%1)"), - strerror (errno)) - << endmsg; + strerror (errno)) + << endmsg; break; } @@ -165,16 +174,60 @@ Butler::thread_work () } if (pfd[0].revents & POLLIN) { + return true; + } + } + return false; +#else + m_request_sem.wait (); + return true; +#endif +} - char req; +bool +Butler::dequeue_request (Request::Type& r) +{ +#ifndef PLATFORM_WINDOWS + char req; + size_t nread = ::read (request_pipe[0], &req, sizeof (req)); + if (nread == 1) { + r = (Request::Type) req; + return true; + } else if (nread == 0) { + return false; + } else if (errno == EAGAIN) { + return false; + } else { + fatal << _("Error reading from butler request pipe") << endmsg; + /*NOTREACHED*/ + } +#else + r = (Request::Type) m_request_state.get(); +#endif + return false; +} - /* empty the pipe of all current requests */ + void * +Butler::thread_work () +{ + uint32_t err = 0; - while (1) { - size_t nread = ::read (request_pipe[0], &req, sizeof (req)); - if (nread == 1) { + bool disk_work_outstanding = false; + RouteList::iterator i; - switch ((Request::Type) req) { + while (true) { + if(!disk_work_outstanding) { + if (wait_for_requests ()) { + Request::Type req; + + /* empty the pipe of all current requests */ +#ifdef PLATFORM_WINDOWS + dequeue_request (req); + { +#else + while(dequeue_request(req)) { +#endif + switch (req) { case Request::Run: should_run = true; @@ -192,14 +245,6 @@ Butler::thread_work () default: break; } - - } else if (nread == 0) { - break; - } else if (errno == EAGAIN) { - break; - } else { - fatal << _("Error reading from butler request pipe") << endmsg; - /*NOTREACHED*/ } } } @@ -338,18 +383,28 @@ Butler::schedule_transport_work () } void -Butler::summon () +Butler::queue_request (Request::Type r) { - char c = Request::Run; +#ifndef PLATFORM_WINDOWS + char c = r; (void) ::write (request_pipe[1], &c, 1); +#else + m_request_state.set (r); + m_request_sem.post (); +#endif +} + +void +Butler::summon () +{ + queue_request (Request::Run); } void Butler::stop () { Glib::Threads::Mutex::Lock lm (request_lock); - char c = Request::Pause; - (void) ::write (request_pipe[1], &c, 1); + queue_request (Request::Pause); paused.wait(request_lock); } @@ -357,8 +412,7 @@ void Butler::wait_until_finished () { Glib::Threads::Mutex::Lock lm (request_lock); - char c = Request::Pause; - (void) ::write (request_pipe[1], &c, 1); + queue_request (Request::Pause); paused.wait(request_lock); } diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 974258a5c2..d9cefb44f2 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -17,7 +17,7 @@ */ -#include <dlfcn.h> +#include <glibmm/module.h> #include <glibmm/fileutils.h> @@ -29,8 +29,10 @@ #include "ardour/debug.h" #include "ardour/control_protocol_manager.h" + #include "ardour/control_protocol_search_path.h" + using namespace ARDOUR; using namespace std; using namespace PBD; @@ -211,7 +213,9 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) } cpi.protocol = 0; - dlclose (cpi.descriptor->module); + delete cpi.state; + cpi.state = 0; + delete (Glib::Module*)cpi.descriptor->module; ProtocolStatusChange (&cpi); @@ -296,7 +300,7 @@ ControlProtocolManager::control_protocol_discover (string path) string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name)); } - dlclose (descriptor->module); + delete (Glib::Module*)descriptor->module; } return 0; @@ -305,31 +309,31 @@ ControlProtocolManager::control_protocol_discover (string path) ControlProtocolDescriptor* ControlProtocolManager::get_descriptor (string path) { - void *module; + Glib::Module* module = new Glib::Module(path); ControlProtocolDescriptor *descriptor = 0; ControlProtocolDescriptor* (*dfunc)(void); - const char *errstr; + void* func = 0; - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg; + if (!(*module)) { + error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg; + delete module; return 0; } - - dfunc = (ControlProtocolDescriptor* (*)(void)) dlsym (module, "protocol_descriptor"); - - if ((errstr = dlerror()) != 0) { + if (!module->get_symbol("protocol_descriptor", func)) { error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg; - error << errstr << endmsg; - dlclose (module); + error << Glib::Module::get_last_error() << endmsg; + delete module; return 0; } + dfunc = (ControlProtocolDescriptor* (*)(void))func; descriptor = dfunc(); + if (descriptor) { - descriptor->module = module; + descriptor->module = (void*)module; } else { - dlclose (module); + delete module; } return descriptor; diff --git a/libs/ardour/control_protocol_search_path.cc b/libs/ardour/control_protocol_search_path.cc index 254cd03fe9..c5c5d0ba00 100644 --- a/libs/ardour/control_protocol_search_path.cc +++ b/libs/ardour/control_protocol_search_path.cc @@ -33,14 +33,14 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath control_protocol_search_path () { - SearchPath spath(user_config_directory ()); + Searchpath spath(user_config_directory ()); spath += ardour_dll_directory (); spath.add_subdirectory_to_paths (surfaces_dir_name); - spath += SearchPath(Glib::getenv(surfaces_env_variable_name)); + spath += Searchpath(Glib::getenv(surfaces_env_variable_name)); return spath; } diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc index fb122dd83c..dc762299e9 100644 --- a/libs/ardour/debug.cc +++ b/libs/ardour/debug.cc @@ -31,6 +31,7 @@ uint64_t PBD::DEBUG::MidiDiskstreamIO = PBD::new_debug_bit ("mididiskstreamio"); uint64_t PBD::DEBUG::SnapBBT = PBD::new_debug_bit ("snapbbt"); uint64_t PBD::DEBUG::Configuration = PBD::new_debug_bit ("configuration"); uint64_t PBD::DEBUG::Latency = PBD::new_debug_bit ("latency"); +uint64_t PBD::DEBUG::Peaks = PBD::new_debug_bit ("peaks"); uint64_t PBD::DEBUG::Processors = PBD::new_debug_bit ("processors"); uint64_t PBD::DEBUG::ProcessThreads = PBD::new_debug_bit ("processthreads"); uint64_t PBD::DEBUG::Graph = PBD::new_debug_bit ("graph"); diff --git a/libs/ardour/default_click.cc b/libs/ardour/default_click.cc index fd23f0166d..7e8eca8fd2 100644 --- a/libs/ardour/default_click.cc +++ b/libs/ardour/default_click.cc @@ -21,6 +21,10 @@ #include "ardour/session.h" #include "ardour/types.h" +#ifdef COMPILER_MSVC +#pragma warning(disable:4305) +#endif + using namespace ARDOUR; const Sample Session::default_click_emphasis[] = { diff --git a/libs/ardour/directory_names.cc b/libs/ardour/directory_names.cc index af7f7f550c..f01c024435 100644 --- a/libs/ardour/directory_names.cc +++ b/libs/ardour/directory_names.cc @@ -36,6 +36,7 @@ const char* const export_formats_dir_name = X_("export"); const char* const templates_dir_name = X_("templates"); const char* const route_templates_dir_name = X_("route_templates"); const char* const surfaces_dir_name = X_("surfaces"); +const char* const ladspa_dir_name = X_("ladspa"); const char* const panner_dir_name = X_("panners"); const char* const backend_dir_name = X_("backends"); diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index a359f228e8..e046d5a830 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -29,7 +29,6 @@ #include <cstdlib> #include <ctime> #include <sys/stat.h> -#include <sys/mman.h> #include <glibmm/threads.h> @@ -571,7 +570,7 @@ Diskstream::move_processor_automation (boost::weak_ptr<Processor> p, list< Evora set<Evoral::Parameter> const a = processor->what_can_be_automated (); - for (set<Evoral::Parameter>::iterator i = a.begin (); i != a.end (); ++i) { + for (set<Evoral::Parameter>::const_iterator i = a.begin (); i != a.end (); ++i) { boost::shared_ptr<AutomationList> al = processor->automation_control(*i)->alist(); XMLNode & before = al->get_state (); bool const things_moved = al->move_ranges (movements); @@ -601,7 +600,7 @@ Diskstream::check_record_status (framepos_t transport_frame, bool can_record) */ rolling = _session.transport_speed() != 0.0f; - possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record; + possibly_recording = (rolling << 2) | ((int)record_enabled() << 1) | (int)can_record; change = possibly_recording ^ last_possibly_recording; if (possibly_recording == last_possibly_recording) { diff --git a/libs/ardour/export_format_base.cc b/libs/ardour/export_format_base.cc index ed8bb9d5f8..1eda449915 100644 --- a/libs/ardour/export_format_base.cc +++ b/libs/ardour/export_format_base.cc @@ -185,7 +185,7 @@ ExportFormatBase::nearest_sample_rate (framecnt_t sample_rate) SampleRate best_match = SR_None; #define DO_SR_COMPARISON(rate) \ - diff = std::fabs((rate) - sample_rate); \ + diff = std::fabs((double)((rate) - sample_rate)); \ if(diff < smallest_diff) { \ smallest_diff = diff; \ best_match = (rate); \ diff --git a/libs/ardour/export_formats_search_path.cc b/libs/ardour/export_formats_search_path.cc index cf18b14a18..ffa096d33a 100644 --- a/libs/ardour/export_formats_search_path.cc +++ b/libs/ardour/export_formats_search_path.cc @@ -32,14 +32,14 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath export_formats_search_path () { - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths (export_formats_dir_name); bool export_formats_path_defined = false; - SearchPath spath_env (Glib::getenv(export_env_variable_name, export_formats_path_defined)); + Searchpath spath_env (Glib::getenv(export_env_variable_name, export_formats_path_defined)); if (export_formats_path_defined) { spath += spath_env; diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index 301914b0ae..2c0c44033d 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -20,6 +20,8 @@ #include "ardour/export_graph_builder.h" +#include <vector> + #include <glibmm/miscutils.h> #include "audiographer/process_context.h" @@ -317,8 +319,8 @@ ExportGraphBuilder::Normalizer::Normalizer (ExportGraphBuilder & parent, FileSpe { std::string tmpfile_path = parent.session.session_directory().export_path(); tmpfile_path = Glib::build_filename(tmpfile_path, "XXXXXX"); - char tmpfile_path_buf[tmpfile_path.size() + 1]; - std::copy(tmpfile_path.begin(), tmpfile_path.end(), tmpfile_path_buf); + std::vector<char> tmpfile_path_buf(tmpfile_path.size() + 1); + std::copy(tmpfile_path.begin(), tmpfile_path.end(), tmpfile_path_buf.begin()); tmpfile_path_buf[tmpfile_path.size()] = '\0'; config = new_config; @@ -334,7 +336,7 @@ ExportGraphBuilder::Normalizer::Normalizer (ExportGraphBuilder & parent, FileSpe normalizer->add_output (threader); int format = ExportFormatBase::F_RAW | ExportFormatBase::SF_Float; - tmp_file.reset (new TmpFile<float> (tmpfile_path_buf, format, channels, config.format->sample_rate())); + tmp_file.reset (new TmpFile<float> (&tmpfile_path_buf[0], format, channels, config.format->sample_rate())); tmp_file->FileWritten.connect_same_thread (post_processing_connection, boost::bind (&Normalizer::start_post_processing, this)); diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc index 93f43f33a6..20abc80de1 100644 --- a/libs/ardour/export_handler.cc +++ b/libs/ardour/export_handler.cc @@ -20,6 +20,7 @@ #include "ardour/export_handler.h" +#include <glib/gstdio.h> #include <glibmm.h> #include <glibmm/convert.h> @@ -422,10 +423,10 @@ ExportHandler::export_cd_marker_file (ExportTimespanPtr timespan, ExportFormatSp } catch (std::exception& e) { error << string_compose (_("an error occured while writing a TOC/CUE file: %1"), e.what()) << endmsg; - ::unlink (filepath.c_str()); + ::g_unlink (filepath.c_str()); } catch (Glib::Exception& e) { error << string_compose (_("an error occured while writing a TOC/CUE file: %1"), e.what()) << endmsg; - ::unlink (filepath.c_str()); + ::g_unlink (filepath.c_str()); } } diff --git a/libs/ardour/export_profile_manager.cc b/libs/ardour/export_profile_manager.cc index 42e494c0cb..7ff4282c74 100644 --- a/libs/ardour/export_profile_manager.cc +++ b/libs/ardour/export_profile_manager.cc @@ -685,7 +685,7 @@ ExportProfileManager::FormatStatePtr ExportProfileManager::deserialize_format (XMLNode & root) { XMLProperty * prop; - UUID id; + PBD::UUID id; if ((prop = root.property ("id"))) { id = prop->value(); diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index 0921498186..e06b3d624e 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -51,7 +51,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Glib; -PBD::Signal3<int,std::string,std::string,std::vector<std::string> > FileSource::AmbiguousFileName; +PBD::Signal2<int,std::string,std::vector<std::string> > FileSource::AmbiguousFileName; FileSource::FileSource (Session& session, DataType type, const string& path, const string& origin, Source::Flag flag) : Source(session, type, path, flag) @@ -240,19 +240,15 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist isnew = false; if (!Glib::path_is_absolute (path)) { - vector<string> dirs; vector<string> hits; string fullpath; + std::vector<std::string> dirs = s.source_search_path (type); - string search_path = s.source_search_path (type); - - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - hits.clear (); for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) { @@ -296,7 +292,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist /* more than one match: ask the user */ - int which = FileSource::AmbiguousFileName (path, search_path, de_duped_hits).get_value_or (-1); + int which = FileSource::AmbiguousFileName (path, de_duped_hits).get_value_or (-1); if (which < 0) { goto out; @@ -310,8 +306,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist if (must_exist) { error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - path, search_path) << endmsg; + _("Filesource: cannot find required file (%1)"), path) << endmsg; goto out; } else { isnew = true; @@ -357,8 +352,6 @@ bool FileSource::find_2X (Session& s, DataType type, const string& path, bool must_exist, bool& isnew, uint16_t& chan, string& found_path) { - string search_path = s.source_search_path (type); - string pathstr = path; string::size_type pos; bool ret = false; @@ -369,18 +362,17 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex /* non-absolute pathname: find pathstr in search path */ - vector<string> dirs; + vector<string> dirs = s.source_search_path (type); + int cnt; string fullpath; string keeppath; - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - cnt = 0; for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) { @@ -437,16 +429,15 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex if (cnt > 1) { error << string_compose ( - _("FileSource: \"%1\" is ambigous when searching %2\n\t"), - pathstr, search_path) << endmsg; + _("FileSource: \"%1\" is ambigous when searching\n\t"), pathstr) << endmsg; goto out; } else if (cnt == 0) { if (must_exist) { error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - pathstr, search_path) << endmsg; + _("Filesource: cannot find required file (%1): while searching") + , pathstr) << endmsg; goto out; } else { isnew = true; @@ -496,13 +487,14 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex goto out; } +#ifndef PLATFORM_WINDOWS if (errno != ENOENT) { error << string_compose( _("Filesource: cannot check for existing file (%1): %2"), path, strerror (errno)) << endmsg; goto out; } - +#endif /* a new file */ isnew = true; ret = true; diff --git a/libs/ardour/filesystem_paths.cc b/libs/ardour/filesystem_paths.cc index 73bfaff137..54f7508b65 100644 --- a/libs/ardour/filesystem_paths.cc +++ b/libs/ardour/filesystem_paths.cc @@ -86,49 +86,71 @@ user_config_directory () std::string ardour_dll_directory () { +#ifdef PLATFORM_WINDOWS + std::string dll_dir_path(g_win32_get_package_installation_directory_of_module(NULL)); + dll_dir_path = Glib::build_filename (dll_dir_path, "lib"); + return Glib::build_filename (dll_dir_path, "ardour3"); +#else std::string s = Glib::getenv("ARDOUR_DLL_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_DLL_PATH not set in environment - exiting\n"); ::exit (1); } return s; +#endif +} + +#ifdef PLATFORM_WINDOWS +Searchpath +windows_search_path () +{ + std::string dll_dir_path(g_win32_get_package_installation_directory_of_module(NULL)); + dll_dir_path = Glib::build_filename (dll_dir_path, "share"); + return Glib::build_filename (dll_dir_path, "ardour3"); } +#endif -SearchPath +Searchpath ardour_config_search_path () { - static SearchPath search_path; + static Searchpath search_path; if (search_path.empty()) { search_path += user_config_directory(); - +#ifdef PLATFORM_WINDOWS + search_path += windows_search_path (); +#else std::string s = Glib::getenv("ARDOUR_CONFIG_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_CONFIG_PATH not set in environment - exiting\n"); ::exit (1); } - search_path += SearchPath (s); + search_path += Searchpath (s); +#endif } return search_path; } -SearchPath +Searchpath ardour_data_search_path () { - static SearchPath search_path; + static Searchpath search_path; if (search_path.empty()) { search_path += user_config_directory(); - +#ifdef PLATFORM_WINDOWS + search_path += windows_search_path (); +#else std::string s = Glib::getenv("ARDOUR_DATA_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_DATA_PATH not set in environment - exiting\n"); ::exit (1); } - search_path += SearchPath (s); + search_path += Searchpath (s); +#endif } return search_path; diff --git a/libs/ardour/find_session.cc b/libs/ardour/find_session.cc index 7a25b1298b..501927c42c 100644 --- a/libs/ardour/find_session.cc +++ b/libs/ardour/find_session.cc @@ -27,6 +27,7 @@ #include <glibmm/miscutils.h> #include "pbd/compose.h" +#include "pbd/pathexpand.h" #include "pbd/error.h" #include "ardour/filename_extensions.h" @@ -44,16 +45,10 @@ int find_session (string str, string& path, string& snapshot, bool& isnew) { struct stat statbuf; - char buf[PATH_MAX+1]; isnew = false; - if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) { - error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg; - return -1; - } - - str = buf; + str = canonical_path (str); /* check to see if it exists, and what it is */ diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 2cd886b03e..5874ac3b1b 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -20,12 +20,18 @@ #include "libardour-config.h" #endif +#ifdef interface +#undef interface +#endif + #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain #include <cstdlib> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> +#ifndef PLATFORM_WINDOWS #include <sys/resource.h> +#endif #include <unistd.h> #include <fcntl.h> #include <errno.h> @@ -43,7 +49,7 @@ #include "ardour/audio_unit.h" #endif -#ifdef __SSE__ +#if defined(__SSE__) || defined(USE_XMMINTRIN) #include <xmmintrin.h> #endif @@ -54,7 +60,9 @@ #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> +#ifdef HAVE_LRDF #include <lrdf.h> +#endif #include "pbd/cpus.h" #include "pbd/error.h" @@ -196,6 +204,7 @@ setup_hardware_optimization (bool try_optimization) static void lotsa_files_please () { +#ifndef PLATFORM_WINDOWS struct rlimit rl; if (getrlimit (RLIMIT_NOFILE, &rl) == 0) { @@ -216,6 +225,7 @@ lotsa_files_please () } else { error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg; } +#endif } bool @@ -262,7 +272,9 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir // allow ardour the absolute maximum number of open files lotsa_files_please (); +#ifdef HAVE_LRDF lrdf_init(); +#endif Library = new AudioLibrary; BootMessage (_("Loading configuration")); @@ -364,7 +376,9 @@ ARDOUR::cleanup () ARDOUR::AudioEngine::destroy (); delete Library; +#ifdef HAVE_LRDF lrdf_cleanup (); +#endif delete &ControlProtocolManager::instance(); #ifdef WINDOWS_VST_SUPPORT fst_exit (); @@ -382,7 +396,7 @@ void ARDOUR::find_bindings_files (map<string,string>& files) { vector<std::string> found; - SearchPath spath = ardour_config_search_path(); + Searchpath spath = ardour_config_search_path(); if (getenv ("ARDOUR_SAE")) { Glib::PatternSpec pattern("*SAE-*.bindings"); @@ -581,10 +595,21 @@ clock_gettime (int /*clk_id*/, struct timespec *t) microseconds_t ARDOUR::get_microseconds () { +#ifdef PLATFORM_WINDOWS + microseconds_t ret = 0; + LARGE_INTEGER freq, time; + + if (QueryPerformanceFrequency(&freq)) + if (QueryPerformanceCounter(&time)) + ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart); + + return ret; +#else struct timespec ts; if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) { /* EEEK! */ return 0; } return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000); +#endif } diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc index d183bcd7d2..f8a1d51e10 100644 --- a/libs/ardour/graph.cc +++ b/libs/ardour/graph.cc @@ -22,6 +22,7 @@ #include "pbd/compose.h" #include "pbd/debug_rt_alloc.h" +#include "pbd/pthread_utils.h" #include "ardour/debug.h" #include "ardour/graph.h" @@ -358,7 +359,7 @@ Graph::run_one() /* update the number of threads that will still be sleeping */ _execution_tokens -= wakeup; - DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_self(), wakeup)); + DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_name(), wakeup)); for (int i = 0; i < wakeup; i++) { _execution_sem.signal (); @@ -367,12 +368,12 @@ Graph::run_one() while (to_run == 0) { _execution_tokens += 1; pthread_mutex_unlock (&_trigger_mutex); - DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_self())); + DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_name())); _execution_sem.wait (); if (_quit_threads) { return true; } - DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_self())); + DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_name())); pthread_mutex_lock (&_trigger_mutex); if (_trigger_queue.size()) { to_run = _trigger_queue.back(); @@ -384,7 +385,7 @@ Graph::run_one() to_run->process(); to_run->finish (_current_chain); - DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 has finished run_one()\n", pthread_self())); + DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 has finished run_one()\n", pthread_name())); return false; } @@ -552,7 +553,7 @@ Graph::process_one_route (Route* route) assert (route); - DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_self(), route->name())); + DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_name(), route->name())); if (_process_silent) { retval = route->silent_roll (_process_nframes, _process_start_frame, _process_end_frame, need_butler); diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 047b46f553..b66f354224 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -34,6 +34,7 @@ #include <sndfile.h> #include <samplerate.h> +#include <glib/gstdio.h> #include <glibmm.h> #include <boost/scoped_array.hpp> @@ -117,7 +118,7 @@ open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQu } static std::string -get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint channel, uint channels) +get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint32_t channel, uint32_t channels) { char buf[PATH_MAX+1]; bool goodfile = false; @@ -172,14 +173,14 @@ get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_repl } static vector<string> -get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels) +get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint32_t channels) { vector<string> new_paths; const string basename = basename_nosuffix (import_file_path); SessionDirectory sdir(session_dir); - for (uint n = 0; n < channels; ++n) { + for (uint32_t n = 0; n < channels; ++n) { const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO; @@ -196,7 +197,7 @@ get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const st static bool map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/, - uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session) + uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session) { for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) @@ -215,7 +216,7 @@ map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/, static bool create_mono_sources_for_writing (const vector<string>& new_paths, - Session& sess, uint samplerate, + Session& sess, uint32_t samplerate, vector<boost::shared_ptr<Source> >& newfiles, framepos_t timeline_position) { @@ -253,10 +254,10 @@ create_mono_sources_for_writing (const vector<string>& new_paths, static string compose_status_message (const string& path, - uint file_samplerate, - uint session_samplerate, - uint /* current_file */, - uint /* total_files */) + uint32_t file_samplerate, + uint32_t session_samplerate, + uint32_t /* current_file */, + uint32_t /* total_files */) { if (file_samplerate != session_samplerate) { return string_compose (_("Resampling %1 from %2kHz to %3kHz"), @@ -274,12 +275,12 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status, { const framecnt_t nframes = ResampledImportableSource::blocksize; boost::shared_ptr<AudioFileSource> afs; - uint channels = source->channels(); + uint32_t channels = source->channels(); boost::scoped_array<float> data(new float[nframes * channels]); vector<boost::shared_array<Sample> > channel_data; - for (uint n = 0; n < channels; ++n) { + for (uint32_t n = 0; n < channels; ++n) { channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes])); } @@ -300,7 +301,7 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status, */ float peak = 0; - uint read_count = 0; + uint32_t read_count = 0; while (!status.cancel) { framecnt_t const nread = source->read (data.get(), nframes); @@ -324,15 +325,23 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status, progress_base = 0.5; } - uint read_count = 0; + uint32_t read_count = 0; while (!status.cancel) { framecnt_t nread, nfread; - uint x; - uint chn; + uint32_t x; + 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; } @@ -464,7 +473,7 @@ remove_file_source (boost::shared_ptr<Source> source) boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source); if (fs) { - ::unlink (fs->path().c_str()); + ::g_unlink (fs->path().c_str()); } } @@ -479,7 +488,7 @@ Session::import_files (ImportStatus& status) Sources all_new_sources; boost::shared_ptr<AudioFileSource> afs; boost::shared_ptr<SMFSource> smfs; - uint channels = 0; + uint32_t channels = 0; status.sources.clear (); diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 6f5b5a63da..ebd295411e 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -19,6 +19,7 @@ #include <fstream> #include <algorithm> #include <cmath> +#include <vector> #include <unistd.h> #include <locale.h> @@ -395,7 +396,9 @@ IO::disconnect (void* src) int IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif boost::shared_ptr<Port> port; @@ -466,7 +469,9 @@ IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) int IO::ensure_ports (ChanCount count, bool clear, void* src) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif bool changed = false; @@ -501,7 +506,9 @@ IO::ensure_ports (ChanCount count, bool clear, void* src) int IO::ensure_io (ChanCount count, bool clear, void* src) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif return ensure_ports (count, clear, src); } @@ -1373,20 +1380,20 @@ IO::build_legal_port_name (DataType type) limit = name_size - AudioEngine::instance()->my_name().length() - (suffix.length() + 5); - char buf1[name_size+1]; - char buf2[name_size+1]; + std::vector<char> buf1(name_size+1); + std::vector<char> buf2(name_size+1); /* colons are illegal in port names, so fix that */ string nom = _name.val(); replace_all (nom, ":", ";"); - snprintf (buf1, name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str()); + snprintf (&buf1[0], name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str()); - int port_number = find_port_hole (buf1); - snprintf (buf2, name_size+1, "%s %d", buf1, port_number); + int port_number = find_port_hole (&buf1[0]); + snprintf (&buf2[0], name_size+1, "%s %d", &buf1[0], port_number); - return string (buf2); + return string (&buf2[0]); } int32_t @@ -1404,14 +1411,13 @@ IO::find_port_hole (const char* base) */ for (n = 1; n < 9999; ++n) { - size_t size = AudioEngine::instance()->port_name_size() + 1; - char buf[size]; + std::vector<char> buf (AudioEngine::instance()->port_name_size()); PortSet::iterator i = _ports.begin(); - snprintf (buf, size, _("%s %u"), base, n); + snprintf (&buf[0], jack_port_name_size(), _("%s %u"), base, n); for ( ; i != _ports.end(); ++i) { - if (i->name() == buf) { + if (string(i->name()) == string(&buf[0])) { break; } } diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index bc3a83799b..8b089929b5 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -17,6 +17,10 @@ */ +#ifdef WAF_BUILD +#include "libardour-config.h" +#endif + #include <inttypes.h> #include <vector> @@ -25,11 +29,15 @@ #include <cstdlib> #include <cstdio> // so libraptor doesn't complain #include <cmath> +#ifndef COMPILER_MSVC #include <dirent.h> +#endif #include <sys/stat.h> #include <cerrno> +#ifdef HAVE_LRDF #include <lrdf.h> +#endif #include "pbd/compose.h" #include "pbd/error.h" @@ -50,16 +58,16 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_t index, framecnt_t rate) +LadspaPlugin::LadspaPlugin (string module_path, AudioEngine& e, Session& session, uint32_t index, framecnt_t rate) : Plugin (e, session) { - init (mod, index, rate); + init (module_path, index, rate); } LadspaPlugin::LadspaPlugin (const LadspaPlugin &other) : Plugin (other) { - init (other._module, other._index, other._sample_rate); + init (other._module_path, other._index, other._sample_rate); for (uint32_t i = 0; i < parameter_count(); ++i) { _control_data[i] = other._shadow_data[i]; @@ -68,25 +76,32 @@ LadspaPlugin::LadspaPlugin (const LadspaPlugin &other) } void -LadspaPlugin::init (void *mod, uint32_t index, framecnt_t rate) +LadspaPlugin::init (string module_path, uint32_t index, framecnt_t rate) { + void* func; LADSPA_Descriptor_Function dfunc; uint32_t i, port_cnt; - const char *errstr; - _module = mod; + _module_path = module_path; + _module = new Glib::Module(_module_path); _control_data = 0; _shadow_data = 0; _latency_control_port = 0; _was_activated = false; - dfunc = (LADSPA_Descriptor_Function) dlsym (_module, "ladspa_descriptor"); + if (!(*_module)) { + error << _("LADSPA: Unable to open module: ") << Glib::Module::get_last_error() << endmsg; + delete _module; + throw failed_constructor(); + } - if ((errstr = dlerror()) != NULL) { + if (!_module->get_symbol("ladspa_descriptor", func)) { error << _("LADSPA: module has no descriptor function.") << endmsg; throw failed_constructor(); } + dfunc = (LADSPA_Descriptor_Function)func; + if ((_descriptor = dfunc (index)) == 0) { error << _("LADSPA: plugin has gone away since discovery!") << endmsg; throw failed_constructor(); @@ -142,9 +157,8 @@ LadspaPlugin::~LadspaPlugin () deactivate (); cleanup (); - /* XXX who should close a plugin? */ - - // dlclose (module); + // glib has internal reference counting on modules so this is ok + delete _module; delete [] _control_data; delete [] _shadow_data; @@ -629,10 +643,11 @@ LadspaPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const boost::shared_ptr<Plugin::ScalePoints> LadspaPlugin::get_scale_points(uint32_t port_index) const { + boost::shared_ptr<Plugin::ScalePoints> ret; +#ifdef HAVE_LRDF const uint32_t id = atol(unique_id().c_str()); lrdf_defaults* points = lrdf_get_scale_values(id, port_index); - boost::shared_ptr<Plugin::ScalePoints> ret; if (!points) { return ret; } @@ -645,6 +660,7 @@ LadspaPlugin::get_scale_points(uint32_t port_index) const } lrdf_free_setting_values(points); +#endif return ret; } @@ -710,17 +726,7 @@ PluginPtr LadspaPluginInfo::load (Session& session) { try { - PluginPtr plugin; - void *module; - - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg; - error << dlerror() << endmsg; - return PluginPtr ((Plugin*) 0); - } else { - plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate())); - } - + PluginPtr plugin (new LadspaPlugin (path, session.engine(), session, index, session.frame_rate())); plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this))); return plugin; } @@ -739,6 +745,7 @@ LadspaPluginInfo::LadspaPluginInfo() void LadspaPlugin::find_presets () { +#ifdef HAVE_LRDF uint32_t id; std::string unique (unique_id()); @@ -759,12 +766,14 @@ LadspaPlugin::find_presets () } lrdf_free_uris(set_uris); } +#endif } bool LadspaPlugin::load_preset (PresetRecord r) { +#ifdef HAVE_LRDF lrdf_defaults* defs = lrdf_get_setting_values (r.uri.c_str()); if (defs) { @@ -777,6 +786,7 @@ LadspaPlugin::load_preset (PresetRecord r) } Plugin::load_preset (r); +#endif return true; } @@ -784,6 +794,7 @@ LadspaPlugin::load_preset (PresetRecord r) static void lrdf_remove_preset (const char* /*source*/, const char *setting_uri) { +#ifdef HAVE_LRDF lrdf_statement p; lrdf_statement *q; lrdf_statement *i; @@ -817,11 +828,13 @@ lrdf_remove_preset (const char* /*source*/, const char *setting_uri) p.predicate = NULL; p.object = NULL; lrdf_remove_matches (&p); +#endif } void LadspaPlugin::do_remove_preset (string name) { +#ifdef HAVE_LRDF string const envvar = preset_envvar (); if (envvar.empty()) { warning << _("Could not locate HOME. Preset not removed.") << endmsg; @@ -837,6 +850,7 @@ LadspaPlugin::do_remove_preset (string name) lrdf_remove_preset (source.c_str(), p->uri.c_str ()); write_preset_file (envvar); +#endif } string @@ -859,6 +873,7 @@ LadspaPlugin::preset_source (string envvar) const bool LadspaPlugin::write_preset_file (string envvar) { +#ifdef HAVE_LRDF string path = string_compose("%1/.ladspa", envvar); if (g_mkdir_with_parents (path.c_str(), 0775)) { warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg; @@ -879,11 +894,15 @@ LadspaPlugin::write_preset_file (string envvar) } return true; +#else + return false; +#endif } string LadspaPlugin::do_save_preset (string name) { +#ifdef HAVE_LRDF /* make a vector of pids that are input parameters */ vector<int> input_parameter_pids; for (uint32_t i = 0; i < parameter_count(); ++i) { @@ -902,8 +921,8 @@ LadspaPlugin::do_save_preset (string name) lrdf_defaults defaults; defaults.count = input_parameter_pids.size (); - lrdf_portvalue portvalues[input_parameter_pids.size()]; - defaults.items = portvalues; + std::vector<lrdf_portvalue> portvalues(input_parameter_pids.size()); + defaults.items = &portvalues[0]; for (vector<int>::size_type i = 0; i < input_parameter_pids.size(); ++i) { portvalues[i].pid = input_parameter_pids[i]; @@ -927,6 +946,9 @@ LadspaPlugin::do_save_preset (string name) } return uri; +#else + return string(); +#endif } LADSPA_PortDescriptor diff --git a/libs/ardour/ladspa_search_path.cc b/libs/ardour/ladspa_search_path.cc new file mode 100644 index 0000000000..49a2645f5d --- /dev/null +++ b/libs/ardour/ladspa_search_path.cc @@ -0,0 +1,61 @@ +/* + Copyright (C) 2011 Tim Mayberry + + 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. + +*/ + +#include <glibmm/miscutils.h> + +#include "pbd/pathexpand.h" + +#include "ardour/ladspa_search_path.h" +#include "ardour/directory_names.h" +#include "ardour/filesystem_paths.h" + +namespace { + const char * const ladspa_env_variable_name = "LADSPA_PATH"; +} // anonymous + +using namespace PBD; + +namespace ARDOUR { + +Searchpath +ladspa_search_path () +{ + Searchpath spath_env (Glib::getenv(ladspa_env_variable_name)); + + Searchpath spath (user_config_directory ()); + + spath += ardour_dll_directory (); + spath.add_subdirectory_to_paths (ladspa_dir_name); + +#ifndef PLATFORM_WINDOWS + spath.push_back ("/usr/local/lib64/ladspa"); + spath.push_back ("/usr/local/lib/ladspa"); + spath.push_back ("/usr/lib64/ladspa"); + spath.push_back ("/usr/lib/ladspa"); +#endif + +#ifdef __APPLE__ + spath.push_back (path_expand ("~/Library/Audio/Plug-Ins/LADSPA")); + spath.push_back ("/Library/Audio/Plug-Ins/LADSPA"); +#endif + + return spath_env + spath; +} + +} // namespace ARDOUR diff --git a/libs/ardour/ltc_slave.cc b/libs/ardour/ltc_slave.cc index b4c4a1446b..ced0226d00 100644 --- a/libs/ardour/ltc_slave.cc +++ b/libs/ardour/ltc_slave.cc @@ -19,11 +19,11 @@ */ #include <iostream> #include <errno.h> -#include <poll.h> #include <sys/types.h> #include <unistd.h> #include "pbd/error.h" +#include "pbd/pthread_utils.h" #include "ardour/debug.h" #include "ardour/slave.h" @@ -150,7 +150,7 @@ LTC_Slave::reset() } void -LTC_Slave::parse_ltc(const pframes_t nframes, const Sample* const in, const framecnt_t posinfo) +LTC_Slave::parse_ltc(const ARDOUR::pframes_t nframes, const Sample* const in, const ARDOUR::framecnt_t posinfo) { pframes_t i; unsigned char sound[8192]; @@ -432,7 +432,7 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos) frameoffset_t skip = now - (monotonic_cnt + nframes); monotonic_cnt = now; - DEBUG_TRACE (DEBUG::LTC, string_compose ("speed_and_position - TID:%1 | latency: %2 | skip %3\n", ::pthread_self(), ltc_slave_latency.max, skip)); + DEBUG_TRACE (DEBUG::LTC, string_compose ("speed_and_position - TID:%1 | latency: %2 | skip %3\n", pthread_name(), ltc_slave_latency.max, skip)); if (last_timestamp == 0) { engine_dll_initstate = 0; @@ -591,7 +591,7 @@ LTC_Slave::approximate_current_delta() const snprintf(delta, sizeof(delta), "%s", _("flywheel")); } else { snprintf(delta, sizeof(delta), "\u0394<span foreground=\"green\" face=\"monospace\" >%s%s%" PRIi64 "</span>sm", - LEADINGZERO(abs(current_delta)), PLUSMINUS(-current_delta), abs(current_delta)); + LEADINGZERO(llabs(current_delta)), PLUSMINUS(-current_delta), llabs(current_delta)); } return std::string(delta); } diff --git a/libs/ardour/lv2_bundled_search_path.cc b/libs/ardour/lv2_bundled_search_path.cc index d8cd1c1075..2454ea2ae1 100644 --- a/libs/ardour/lv2_bundled_search_path.cc +++ b/libs/ardour/lv2_bundled_search_path.cc @@ -29,10 +29,10 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath lv2_bundled_search_path () { - SearchPath spath( ardour_dll_directory () ); + Searchpath spath( ardour_dll_directory () ); spath.add_subdirectory_to_paths ("LV2"); return spath; diff --git a/libs/ardour/lv2_evbuf.c b/libs/ardour/lv2_evbuf.c index 8942d19a9b..fba7fd521d 100644 --- a/libs/ardour/lv2_evbuf.c +++ b/libs/ardour/lv2_evbuf.c @@ -219,7 +219,7 @@ lv2_evbuf_get(LV2_Evbuf_Iterator iter, *subframes = 0; *type = aev->body.type; *size = aev->body.size; - *data = LV2_ATOM_BODY(&aev->body); + *data = (uint8_t*)LV2_ATOM_BODY(&aev->body); break; } diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index dc7805c273..e6b3c2d56e 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -25,6 +25,7 @@ #include <cstdlib> #include <cstring> +#include <glib/gstdio.h> #include <giomm/file.h> #include <glib/gprintf.h> #include <glibmm.h> @@ -1111,7 +1112,7 @@ LV2Plugin::do_remove_preset(string name) name + ".ttl" ) ); - unlink(preset_file.c_str()); + ::g_unlink(preset_file.c_str()); } bool @@ -1139,16 +1140,16 @@ LV2Plugin::write_to(RingBuffer<uint8_t>* dest, uint32_t size, const uint8_t* body) { - const uint32_t buf_size = sizeof(UIMessage) + size; - uint8_t buf[buf_size]; + const uint32_t buf_size = sizeof(UIMessage) + size; + vector<uint8_t> buf(buf_size); - UIMessage* msg = (UIMessage*)buf; + UIMessage* msg = (UIMessage*)&buf[0]; msg->index = index; msg->protocol = protocol; msg->size = size; memcpy(msg + 1, body, size); - return (dest->write(buf, buf_size) == buf_size); + return (dest->write(&buf[0], buf_size) == buf_size); } bool @@ -1227,13 +1228,13 @@ LV2Plugin::emit_to_ui(void* controller, UIMessageSink sink) error << "Error reading from Plugin=>UI RingBuffer" << endmsg; break; } - uint8_t body[msg.size]; - if (_to_ui->read(body, msg.size) != msg.size) { + vector<uint8_t> body(msg.size); + if (_to_ui->read(&body[0], msg.size) != msg.size) { error << "Error reading from Plugin=>UI RingBuffer" << endmsg; break; } - sink(controller, msg.index, msg.size, msg.protocol, body); + sink(controller, msg.index, msg.size, msg.protocol, &body[0]); read_space -= sizeof(msg) + msg.size; } @@ -1716,15 +1717,15 @@ LV2Plugin::connect_and_run(BufferSet& bufs, error << "Error reading from UI=>Plugin RingBuffer" << endmsg; break; } - uint8_t body[msg.size]; - if (_from_ui->read(body, msg.size) != msg.size) { + vector<uint8_t> body(msg.size); + if (_from_ui->read(&body[0], msg.size) != msg.size) { error << "Error reading from UI=>Plugin RingBuffer" << endmsg; break; } if (msg.protocol == urids.atom_eventTransfer) { LV2_Evbuf* buf = _ev_buffers[msg.index]; LV2_Evbuf_Iterator i = lv2_evbuf_end(buf); - const LV2_Atom* const atom = (const LV2_Atom*)body; + const LV2_Atom* const atom = (const LV2_Atom*)&body[0]; if (!lv2_evbuf_write(&i, nframes, 0, atom->type, atom->size, (const uint8_t*)(atom + 1))) { error << "Failed to write data to LV2 event buffer\n"; @@ -2034,7 +2035,7 @@ LV2World::load_bundled_plugins() vector<string *> *plugin_objects = scanner (ARDOUR::lv2_bundled_search_path().to_string(), lv2_filter, 0, true, true); if (plugin_objects) { for ( vector<string *>::iterator x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { -#ifdef WINDOWS +#ifdef PLATFORM_WINDOWS string uri = "file:///" + **x + "/"; #else string uri = "file://" + **x + "/"; diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc index ec736fef69..80690bd744 100644 --- a/libs/ardour/meter.cc +++ b/libs/ardour/meter.cc @@ -18,6 +18,7 @@ #include <algorithm> #include <cmath> +#include <limits> #include "pbd/compose.h" @@ -153,7 +154,7 @@ void PeakMeter::reset_max () { for (size_t i = 0; i < _max_peak_power.size(); ++i) { - _max_peak_power[i] = -INFINITY; + _max_peak_power[i] = -std::numeric_limits<float>::infinity(); _max_peak_signal[i] = 0; } @@ -163,7 +164,7 @@ PeakMeter::reset_max () if (n < n_midi) { _visible_peak_power[n] = 0; } else { - _visible_peak_power[n] = -INFINITY; + _visible_peak_power[n] = -std::numeric_limits<float>::infinity(); } } } @@ -302,7 +303,7 @@ PeakMeter::meter () _peak_signal[n] = 0; /* ... to here */ if (n < n_midi) { - _max_peak_power[n] = -INFINITY; // std::max (new_peak, _max_peak_power[n]); // XXX + _max_peak_power[n] = -std::numeric_limits<float>::infinity(); // std::max (new_peak, _max_peak_power[n]); // XXX _max_peak_signal[n] = 0; if (midi_meter_falloff == 0.0f || new_peak > _visible_peak_power[n]) { ; @@ -336,7 +337,7 @@ PeakMeter::meter () } else { // do falloff new_peak = _visible_peak_power[n] - (audio_meter_falloff); - _visible_peak_power[n] = std::max (new_peak, -INFINITY); + _visible_peak_power[n] = std::max (new_peak, -std::numeric_limits<float>::infinity()); } } } diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc index 762d94469c..8c95272fde 100644 --- a/libs/ardour/midi_clock_slave.cc +++ b/libs/ardour/midi_clock_slave.cc @@ -20,7 +20,6 @@ #include <cmath> #include <errno.h> -#include <poll.h> #include <sys/types.h> #include <unistd.h> #include "pbd/error.h" @@ -261,7 +260,7 @@ MIDIClock_Slave::stop (Parser& /*parser*/, framepos_t /*timestamp*/) } void -MIDIClock_Slave::position (Parser& /*parser*/, byte* message, size_t size) +MIDIClock_Slave::position (Parser& /*parser*/, MIDI::byte* message, size_t size) { // we are note supposed to get position messages while we are running // so lets be robust and ignore those @@ -270,8 +269,8 @@ MIDIClock_Slave::position (Parser& /*parser*/, byte* message, size_t size) } assert(size == 3); - byte lsb = message[1]; - byte msb = message[2]; + MIDI::byte lsb = message[1]; + MIDI::byte msb = message[2]; assert((lsb <= 0x7f) && (msb <= 0x7f)); uint16_t position_in_sixteenth_notes = (uint16_t(msb) << 7) | uint16_t(lsb); diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 4771f7128c..a1a640cd1c 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -26,11 +26,10 @@ #include <fcntl.h> #include <cstdlib> #include <ctime> -#include <strings.h> // for ffs(3) #include <sys/stat.h> -#include <sys/mman.h> #include "pbd/error.h" +#include "pbd/ffs.h" #include "pbd/basename.h" #include <glibmm/threads.h> #include "pbd/xml++.h" @@ -439,7 +438,7 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t break; case ForceChannel: if (ev.is_channel_event()) { - ev.set_channel (ffs(mask) - 1); + ev.set_channel (PBD::ffs(mask) - 1); } _capture_buf->write(transport_frame + loop_offset + ev.time(), ev.type(), ev.size(), ev.buffer()); diff --git a/libs/ardour/midi_patch_manager.cc b/libs/ardour/midi_patch_manager.cc index 4bced4e46d..f2d964bb77 100644 --- a/libs/ardour/midi_patch_manager.cc +++ b/libs/ardour/midi_patch_manager.cc @@ -28,6 +28,7 @@ #include "ardour/session.h" #include "ardour/session_directory.h" #include "ardour/midi_patch_manager.h" + #include "ardour/midi_patch_search_path.h" #include "i18n.h" @@ -102,7 +103,7 @@ MidiPatchManager::refresh() _master_devices_by_model.clear(); _all_models.clear(); - SearchPath search_path = midi_patch_search_path (); + Searchpath search_path = midi_patch_search_path (); Glib::PatternSpec pattern (string("*.midnam")); vector<std::string> result; diff --git a/libs/ardour/midi_patch_search_path.cc b/libs/ardour/midi_patch_search_path.cc index ccad1de466..c099c379e9 100644 --- a/libs/ardour/midi_patch_search_path.cc +++ b/libs/ardour/midi_patch_search_path.cc @@ -31,14 +31,14 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath midi_patch_search_path () { - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(midi_patch_dir_name); bool midi_patch_path_defined = false; - SearchPath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined)); + Searchpath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined)); if (midi_patch_path_defined) { spath += spath_env; diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index 124d3f7c9b..1887b74302 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -20,7 +20,6 @@ #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> -#include <poll.h> #include <float.h> #include <cerrno> #include <ctime> diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 7dff7ac639..6a998de90e 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -17,8 +17,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <strings.h> // for ffs(3) - +#include "pbd/ffs.h" #include "pbd/enumwriter.h" #include "pbd/convert.h" #include "evoral/midi_util.h" @@ -321,7 +320,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame if (!lm.locked()) { boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream(); framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes); - if (can_internal_playback_seek(std::llabs(playback_distance))) { + if (can_internal_playback_seek(llabs(playback_distance))) { /* TODO should declick, and/or note-off */ internal_playback_seek(playback_distance); } @@ -513,7 +512,7 @@ MidiTrack::filter_channels (BufferSet& bufs, ChannelMode mode, uint32_t mask) } break; case ForceChannel: - ev.set_channel (ffs (mask) - 1); + ev.set_channel (PBD::ffs (mask) - 1); ++e; break; case AllChannels: @@ -633,9 +632,9 @@ void MidiTrack::MidiControl::set_value(double val) { bool valid = false; - if (std::isinf(val)) { + if (isinf(val)) { cerr << "MIDIControl value is infinity" << endl; - } else if (std::isnan(val)) { + } else if (isnan(val)) { cerr << "MIDIControl value is NaN" << endl; } else if (val < _list->parameter().min()) { cerr << "MIDIControl value is < " << _list->parameter().min() << endl; diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc index b80370ec6a..06940c1e34 100644 --- a/libs/ardour/midi_ui.cc +++ b/libs/ardour/midi_ui.cc @@ -77,7 +77,9 @@ MidiControlUI::midi_input_handler (IOCondition ioc, AsyncMIDIPort* port) if (ioc & IO_IN) { +#ifndef PLATFORM_WINDOWS CrossThreadChannel::drain (port->selectable()); +#endif DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name())); framepos_t now = _session.engine().sample_time(); diff --git a/libs/ardour/mix.cc b/libs/ardour/mix.cc index 3a873a8e50..220cd0660c 100644 --- a/libs/ardour/mix.cc +++ b/libs/ardour/mix.cc @@ -24,6 +24,8 @@ #include "ardour/runtime_functions.h" #include <stdint.h> +using std::min; +using std::max; using namespace ARDOUR; #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) @@ -93,22 +95,22 @@ default_compute_peak (const ARDOUR::Sample * buf, pframes_t nsamples, float curr } void -default_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *min, float *max) +default_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *minf, float *maxf) { pframes_t i; float a, b; - a = *max; - b = *min; + a = *maxf; + b = *minf; for (i = 0; i < nframes; i++) { - a = fmax (buf[i], a); - b = fmin (buf[i], b); + a = max (buf[i], a); + b = min (buf[i], b); } - *max = a; - *min = b; + *maxf = a; + *minf = b; } void 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/mtc_slave.cc b/libs/ardour/mtc_slave.cc index e9071af619..0dee2a071b 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -19,11 +19,11 @@ */ #include <iostream> #include <errno.h> -#include <poll.h> #include <sys/types.h> #include <unistd.h> #include "pbd/error.h" +#include "pbd/pthread_utils.h" #include "ardour/audioengine.h" #include "ardour/debug.h" @@ -32,6 +32,8 @@ #include "ardour/session.h" #include "ardour/slave.h" +#include <glibmm/timer.h> + #include "i18n.h" using namespace std; @@ -236,7 +238,7 @@ MTC_Slave::read_current (SafeTime *st) const do { if (tries == 10) { error << _("MTC Slave: atomic read of current time failed, sleeping!") << endmsg; - usleep (20); + Glib::usleep (20); tries = 0; } *st = current; @@ -299,7 +301,7 @@ MTC_Slave::update_mtc_qtr (Parser& /*p*/, int which_qtr, framepos_t now) * when a full TC has been received * OR on locate */ void -MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now) +MTC_Slave::update_mtc_time (const MIDI::byte *msg, bool was_full, framepos_t now) { busy_guard1++; @@ -307,8 +309,11 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now) to use a timestamp indicating when this MTC time was received. example: when we received a locate command via MMC. */ - +#ifdef COMPILER_MSVC + DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self().p)); +#else DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self())); +#endif TimecodeFormat tc_format; bool reset_tc = true; @@ -488,7 +493,7 @@ MTC_Slave::update_mtc_status (MIDI::MTC_Status status) /* XXX !!! thread safety ... called from MIDI I/O context * on locate (via ::update_mtc_time()) */ - DEBUG_TRACE (DEBUG::MTC, string_compose("MTC_Slave::update_mtc_status - TID:%1\n", ::pthread_self())); + DEBUG_TRACE (DEBUG::MTC, string_compose("MTC_Slave::update_mtc_status - TID:%1\n", pthread_name())); return; // why was this fn needed anyway ? it just messes up things -> use reset. busy_guard1++; diff --git a/libs/ardour/panner_manager.cc b/libs/ardour/panner_manager.cc index 24fa10e225..3c9623f3e6 100644 --- a/libs/ardour/panner_manager.cc +++ b/libs/ardour/panner_manager.cc @@ -29,6 +29,7 @@ #include "ardour/debug.h" #include "ardour/panner_manager.h" + #include "ardour/panner_search_path.h" #include "i18n.h" @@ -65,7 +66,7 @@ static bool panner_filter (const string& str, void */*arg*/) #ifdef __APPLE__ return str[0] != '.' && (str.length() > 6 && str.find (".dylib") == (str.length() - 6)); #else - return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); + return str[0] != '.' && (str.length() > 3 && (str.find (".so") == (str.length() - 3) || str.find (".dll") == (str.length() - 4))); #endif } @@ -83,6 +84,7 @@ PannerManager::discover_panners () for (vector<std::string *>::iterator i = panner_modules->begin(); i != panner_modules->end(); ++i) { panner_discover (**i); } + vector_delete (panner_modules); } @@ -113,31 +115,33 @@ PannerManager::panner_discover (string path) PannerInfo* PannerManager::get_descriptor (string path) { - void *module; + Glib::Module* module = new Glib::Module(path); PannerInfo* info = 0; PanPluginDescriptor *descriptor = 0; PanPluginDescriptor* (*dfunc)(void); - const char *errstr; + void* func = 0; - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("PannerManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg; + if (!module) { + error << string_compose(_("PannerManager: cannot load module \"%1\" (%2)"), path, + Glib::Module::get_last_error()) << endmsg; + delete module; return 0; } - dfunc = (PanPluginDescriptor* (*)(void)) dlsym (module, "panner_descriptor"); - - if ((errstr = dlerror()) != 0) { + if (!module->get_symbol("panner_descriptor", func)) { error << string_compose(_("PannerManager: module \"%1\" has no descriptor function."), path) << endmsg; - error << errstr << endmsg; - dlclose (module); + error << Glib::Module::get_last_error() << endmsg; + delete module; return 0; } + dfunc = (PanPluginDescriptor* (*)(void))func; descriptor = dfunc(); + if (descriptor) { info = new PannerInfo (*descriptor, module); } else { - dlclose (module); + delete module; } return info; diff --git a/libs/ardour/panner_search_path.cc b/libs/ardour/panner_search_path.cc index 49349238e4..2889063ca4 100644 --- a/libs/ardour/panner_search_path.cc +++ b/libs/ardour/panner_search_path.cc @@ -31,13 +31,18 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath panner_search_path () { - SearchPath spath(user_config_directory ()); + Searchpath spath(user_config_directory ()); spath += ardour_dll_directory (); spath.add_subdirectory_to_paths(panner_dir_name); +<<<<<<< HEAD spath += SearchPath(Glib::getenv(panner_env_variable_name)); +======= + + spath += Searchpath(Glib::getenv(panner_env_variable_name)); +>>>>>>> windows+cc return spath; } diff --git a/libs/ardour/pcm_utils.cc b/libs/ardour/pcm_utils.cc index de3497d977..ae3bd4a4e0 100644 --- a/libs/ardour/pcm_utils.cc +++ b/libs/ardour/pcm_utils.cc @@ -17,8 +17,10 @@ */ +#ifdef COMPILER_MSVC +#include <ardourext/float_cast.h> +#endif #include "ardour/pcm_utils.h" - #include <cmath> using namespace std; diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index bb79801c9f..47462a3575 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -1997,11 +1997,11 @@ Playlist::find_next_region (framepos_t frame, RegionPoint point, int dir) freeze (); /* add the added regions */ - for (RegionListProperty::ChangeContainer::iterator i = change.added.begin(); i != change.added.end(); ++i) { + for (RegionListProperty::ChangeContainer::const_iterator i = change.added.begin(); i != change.added.end(); ++i) { add_region_internal ((*i), (*i)->position()); } /* remove the removed regions */ - for (RegionListProperty::ChangeContainer::iterator i = change.removed.begin(); i != change.removed.end(); ++i) { + for (RegionListProperty::ChangeContainer::const_iterator i = change.removed.begin(); i != change.removed.end(); ++i) { remove_region (*i); } @@ -2488,7 +2488,7 @@ Playlist::uses_source (boost::shared_ptr<const Source> src) const { RegionReadLock rlock (const_cast<Playlist*> (this)); - for (set<boost::shared_ptr<Region> >::iterator r = all_regions.begin(); r != all_regions.end(); ++r) { + for (set<boost::shared_ptr<Region> >::const_iterator r = all_regions.begin(); r != all_regions.end(); ++r) { if ((*r)->uses_source (src)) { return true; } @@ -2533,7 +2533,7 @@ Playlist::region_by_id (const ID& id) const { /* searches all regions ever added to this playlist */ - for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { + for (set<boost::shared_ptr<Region> >::const_iterator i = all_regions.begin(); i != all_regions.end(); ++i) { if ((*i)->id() == id) { return *i; } diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index 9b2170c349..11d859ed8c 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -27,12 +27,16 @@ #include <cstdlib> #include <cstdio> // so libraptor doesn't complain #include <cmath> +#ifndef COMPILER_MSVC #include <dirent.h> +#endif #include <sys/stat.h> #include <cerrno> #include <utility> +#ifdef HAVE_LRDF #include <lrdf.h> +#endif #include "pbd/compose.h" #include "pbd/error.h" diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index b5be296b1a..e93566068b 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -25,11 +25,13 @@ #include <sys/types.h> #include <cstdio> -#include <lrdf.h> -#include <dlfcn.h> #include <cstdlib> #include <fstream> +#ifdef HAVE_LRDF +#include <lrdf.h> +#endif + #ifdef WINDOWS_VST_SUPPORT #include "fst.h" #include "pbd/basename.h" @@ -43,9 +45,11 @@ #endif //LXVST_SUPPORT #include <glibmm/miscutils.h> +#include <glibmm/pattern.h> #include "pbd/pathscanner.h" #include "pbd/whitespace.h" +#include "pbd/file_utils.h" #include "ardour/debug.h" #include "ardour/filesystem_paths.h" @@ -55,6 +59,8 @@ #include "ardour/plugin_manager.h" #include "ardour/rc_configuration.h" +#include "ardour/ladspa_search_path.h" + #ifdef LV2_SUPPORT #include "ardour/lv2_plugin.h" #endif @@ -77,6 +83,8 @@ #include "i18n.h" +#include "ardour/debug.h" + using namespace ARDOUR; using namespace PBD; using namespace std; @@ -126,10 +134,6 @@ PluginManager::PluginManager () } #endif /* Native LinuxVST support*/ - if ((s = getenv ("LADSPA_PATH"))) { - ladspa_path = s; - } - if ((s = getenv ("VST_PATH"))) { windows_vst_path = s; } else if ((s = getenv ("VST_PLUGINS"))) { @@ -198,91 +202,38 @@ PluginManager::refresh () void PluginManager::ladspa_refresh () { - if (_ladspa_plugin_info) + if (_ladspa_plugin_info) { _ladspa_plugin_info->clear (); - else + } else { _ladspa_plugin_info = new ARDOUR::PluginInfoList (); - - static const char *standard_paths[] = { - "/usr/local/lib64/ladspa", - "/usr/local/lib/ladspa", - "/usr/lib64/ladspa", - "/usr/lib/ladspa", - "/Library/Audio/Plug-Ins/LADSPA", - "" - }; + } /* allow LADSPA_PATH to augment, not override standard locations */ /* Only add standard locations to ladspa_path if it doesn't * already contain them. Check for trailing G_DIR_SEPARATOR too. */ + + vector<string> ladspa_modules; - int i; - for (i = 0; standard_paths[i][0]; i++) { - size_t found = ladspa_path.find(standard_paths[i]); - if (found != ladspa_path.npos) { - switch (ladspa_path[found + strlen(standard_paths[i])]) { - case ':' : - case '\0': - continue; - case G_DIR_SEPARATOR : - if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' || - ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') { - continue; - } - } - } - if (!ladspa_path.empty()) - ladspa_path += ":"; - - ladspa_path += standard_paths[i]; - - } - - DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_path)); - - ladspa_discover_from_path (ladspa_path); -} - - -int -PluginManager::add_ladspa_directory (string path) -{ - if (ladspa_discover_from_path (path) == 0) { - ladspa_path += ':'; - ladspa_path += path; - return 0; - } - return -1; -} - -static bool ladspa_filter (const string& str, void */*arg*/) -{ - /* Not a dotfile, has a prefix before a period, suffix is "so" */ + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string())); - return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); -} - -int -PluginManager::ladspa_discover_from_path (string /*path*/) -{ - PathScanner scanner; - vector<string *> *plugin_objects; - vector<string *>::iterator x; - int ret = 0; + Glib::PatternSpec so_extension_pattern("*.so"); + Glib::PatternSpec dylib_extension_pattern("*.dylib"); + Glib::PatternSpec dll_extension_pattern("*.dll"); - plugin_objects = scanner (ladspa_path, ladspa_filter, 0, false, true); + find_matching_files_in_search_path (ladspa_search_path (), + so_extension_pattern, ladspa_modules); - if (plugin_objects) { - for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { - ladspa_discover (**x); - } + find_matching_files_in_search_path (ladspa_search_path (), + dylib_extension_pattern, ladspa_modules); + + find_matching_files_in_search_path (ladspa_search_path (), + dll_extension_pattern, ladspa_modules); - vector_delete (plugin_objects); + for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) { + ladspa_discover (*i); } - - return ret; } static bool rdf_filter (const string &str, void* /*arg*/) @@ -315,7 +266,7 @@ PluginManager::add_lxvst_presets() void PluginManager::add_presets(string domain) { - +#ifdef HAVE_LRDF PathScanner scanner; vector<string *> *presets; vector<string *>::iterator x; @@ -338,11 +289,13 @@ PluginManager::add_presets(string domain) vector_delete (presets); } +#endif } void PluginManager::add_lrdf_data (const string &path) { +#ifdef HAVE_LRDF PathScanner scanner; vector<string *>* rdf_files; vector<string *>::iterator x; @@ -360,30 +313,36 @@ PluginManager::add_lrdf_data (const string &path) vector_delete (rdf_files); } +#endif } int PluginManager::ladspa_discover (string path) { - void *module; + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path)); + + Glib::Module module(path); const LADSPA_Descriptor *descriptor; LADSPA_Descriptor_Function dfunc; - const char *errstr; + void* func = 0; - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg; + if (!module) { + error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), + path, Glib::Module::get_last_error()) << endmsg; return -1; } - dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor"); - if ((errstr = dlerror()) != 0) { + if (!module.get_symbol("ladspa_descriptor", func)) { error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg; - error << errstr << endmsg; - dlclose (module); + error << Glib::Module::get_last_error() << endmsg; return -1; } + dfunc = (LADSPA_Descriptor_Function)func; + + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path)); + for (uint32_t i = 0; ; ++i) { if ((descriptor = dfunc (i)) == 0) { break; @@ -437,6 +396,8 @@ PluginManager::ladspa_discover (string path) if(!found){ _ladspa_plugin_info->push_back (info); } + + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs)); } // GDB WILL NOT LIKE YOU IF YOU DO THIS @@ -448,6 +409,7 @@ PluginManager::ladspa_discover (string path) string PluginManager::get_ladspa_category (uint32_t plugin_id) { +#ifdef HAVE_LRDF char buf[256]; lrdf_statement pattern; @@ -505,6 +467,9 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) } else { return label; } +#else + return ("Unknown"); +#endif } #ifdef LV2_SUPPORT diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index cf961d6828..bc5d26fb80 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -21,7 +21,9 @@ #include "libardour-config.h" #endif +#ifndef PLATFORM_WINDOWS #include <jack/weakjack.h> // so that we can test for new functions at runtime +#endif #include "pbd/compose.h" #include "pbd/error.h" diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc index c352e22e55..fa09ea05ac 100644 --- a/libs/ardour/port_insert.cc +++ b/libs/ardour/port_insert.cc @@ -249,7 +249,9 @@ PortInsert::signal_latency() const bool PortInsert::configure_io (ChanCount in, ChanCount out) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif /* for an insert, processor input corresponds to IO output, and vice versa */ diff --git a/libs/ardour/port_set.cc b/libs/ardour/port_set.cc index 6096e356f5..c7f5e2e674 100644 --- a/libs/ardour/port_set.cc +++ b/libs/ardour/port_set.cc @@ -56,7 +56,7 @@ static bool sort_ports_by_name (boost::shared_ptr<Port> a, boost::shared_ptr<Por // if some of the names don't have a number as posfix, compare as strings - if (last_digit_position_a == aname.size() or last_digit_position_b == bname.size()) { + if (last_digit_position_a == aname.size() || last_digit_position_b == bname.size()) { return aname < bname; } diff --git a/libs/ardour/rc_configuration.cc b/libs/ardour/rc_configuration.cc index f4612699d4..7fe030fb7e 100644 --- a/libs/ardour/rc_configuration.cc +++ b/libs/ardour/rc_configuration.cc @@ -72,7 +72,7 @@ int RCConfiguration::load_state () { std::string rcfile; - struct stat statbuf; + GStatBuf statbuf; /* load system configuration first */ diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 3e81524750..44f8c34ddd 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -564,7 +564,7 @@ RegionFactory::new_region_name (string old) uint32_t number; string::size_type len = old.length() + 64; string remainder; - char buf[len]; + std::vector<char> buf(len); if ((last_period = old.find_last_of ('.')) == string::npos) { @@ -603,8 +603,8 @@ RegionFactory::new_region_name (string old) number++; - snprintf (buf, len, "%s%" PRIu32 "%s", old.substr (0, last_period + 1).c_str(), number, remainder.c_str()); - sbuf = buf; + snprintf (&buf[0], len, "%s%" PRIu32 "%s", old.substr (0, last_period + 1).c_str(), number, remainder.c_str()); + sbuf = &buf[0]; if (region_name_map.find (sbuf) == region_name_map.end ()) { break; @@ -612,7 +612,7 @@ RegionFactory::new_region_name (string old) } if (number != (UINT_MAX-1)) { - return buf; + return &buf[0]; } error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg; diff --git a/libs/ardour/resampled_source.cc b/libs/ardour/resampled_source.cc index 6184e1a3d6..0a81319108 100644 --- a/libs/ardour/resampled_source.cc +++ b/libs/ardour/resampled_source.cc @@ -26,7 +26,11 @@ using namespace ARDOUR; using namespace PBD; +#ifdef PLATFORM_WINDOWS +const uint32_t ResampledImportableSource::blocksize = 524288U; +#else const uint32_t ResampledImportableSource::blocksize = 16384U; +#endif ResampledImportableSource::ResampledImportableSource (boost::shared_ptr<ImportableSource> src, framecnt_t rate, SrcQuality srcq) : source (src) diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 6f23e920d4..4b9285c1c8 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1639,7 +1639,9 @@ Route::reset_instrument_info () int Route::configure_processors (ProcessorStreams* err) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif if (!_in_configure_processors) { Glib::Threads::RWLock::WriterLock lm (_processor_lock); @@ -1710,7 +1712,9 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) int Route::configure_processors_unlocked (ProcessorStreams* err) { +#ifndef PLATFORM_WINDOWS assert (!AudioEngine::instance()->process_lock().trylock()); +#endif if (_in_configure_processors) { return 0; @@ -2850,7 +2854,7 @@ Route::feeds (boost::shared_ptr<Route> other, bool* via_sends_only) { const FedBy& fed_by (other->fed_by()); - for (FedBy::iterator f = fed_by.begin(); f != fed_by.end(); ++f) { + for (FedBy::const_iterator f = fed_by.begin(); f != fed_by.end(); ++f) { boost::shared_ptr<Route> sr = f->r.lock(); if (sr && (sr.get() == this)) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 115fcd750a..b880883e09 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -44,8 +44,8 @@ #include "pbd/stacktrace.h" #include "pbd/file_utils.h" #include "pbd/convert.h" -#include "pbd/strsplit.h" #include "pbd/unwind.h" +#include "pbd/search_path.h" #include "ardour/amp.h" #include "ardour/analyser.h" @@ -4581,18 +4581,18 @@ Session::end_time_changed (framepos_t old) } } -string +std::vector<std::string> Session::source_search_path (DataType type) const { - vector<string> s; + Searchpath sp; if (session_dirs.size() == 1) { switch (type) { case DataType::AUDIO: - s.push_back (_session_dir->sound_path()); + sp.push_back (_session_dir->sound_path()); break; case DataType::MIDI: - s.push_back (_session_dir->midi_path()); + sp.push_back (_session_dir->midi_path()); break; } } else { @@ -4600,10 +4600,10 @@ Session::source_search_path (DataType type) const SessionDirectory sdir (i->path); switch (type) { case DataType::AUDIO: - s.push_back (sdir.sound_path()); + sp.push_back (sdir.sound_path()); break; case DataType::MIDI: - s.push_back (sdir.midi_path()); + sp.push_back (sdir.midi_path()); break; } } @@ -4612,49 +4612,30 @@ Session::source_search_path (DataType type) const if (type == DataType::AUDIO) { const string sound_path_2X = _session_dir->sound_path_2X(); if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { - if (find (s.begin(), s.end(), sound_path_2X) == s.end()) { - s.push_back (sound_path_2X); + if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) { + sp.push_back (sound_path_2X); } } } - /* now check the explicit (possibly user-specified) search path - */ - - vector<string> dirs; + // now check the explicit (possibly user-specified) search path switch (type) { case DataType::AUDIO: - split (config.get_audio_search_path (), dirs, ':'); + sp += Searchpath(config.get_audio_search_path ()); break; case DataType::MIDI: - split (config.get_midi_search_path (), dirs, ':'); + sp += Searchpath(config.get_midi_search_path ()); break; } - for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) { - if (find (s.begin(), s.end(), *i) == s.end()) { - s.push_back (*i); - } - } - - string search_path; - - for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) { - if (!search_path.empty()) { - search_path += ':'; - } - search_path += *si; - } - - return search_path; + return sp; } void Session::ensure_search_path_includes (const string& path, DataType type) { - string search_path; - vector<string> dirs; + Searchpath sp; if (path == ".") { return; @@ -4662,16 +4643,14 @@ Session::ensure_search_path_includes (const string& path, DataType type) switch (type) { case DataType::AUDIO: - search_path = config.get_audio_search_path (); + sp += Searchpath(config.get_audio_search_path ()); break; case DataType::MIDI: - search_path = config.get_midi_search_path (); + sp += Searchpath (config.get_midi_search_path ()); break; } - split (search_path, dirs, ':'); - - for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) { + for (vector<std::string>::iterator i = sp.begin(); i != sp.end(); ++i) { /* No need to add this new directory if it has the same inode as an existing one; checking inode rather than name prevents duplicated directories when we are using symlinks. @@ -4683,18 +4662,14 @@ Session::ensure_search_path_includes (const string& path, DataType type) } } - if (!search_path.empty()) { - search_path += ':'; - } - - search_path += path; + sp += path; switch (type) { case DataType::AUDIO: - config.set_audio_search_path (search_path); + config.set_audio_search_path (sp.to_string()); break; case DataType::MIDI: - config.set_midi_search_path (search_path); + config.set_midi_search_path (sp.to_string()); break; } } diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index 1d235b051a..3e7c2226cc 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -17,16 +17,6 @@ */ -#include <algorithm> -#include <string> -#include <cmath> -#include <cerrno> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> - -#include <glibmm/threads.h> - #include "pbd/error.h" #include "pbd/pthread_utils.h" #include "pbd/stacktrace.h" diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index 6c828ac6f0..19034da247 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -23,6 +23,7 @@ #include "pbd/error.h" #include "pbd/enumwriter.h" #include "pbd/stacktrace.h" +#include "pbd/pthread_utils.h" #include "ardour/debug.h" #include "ardour/session_event.h" @@ -56,7 +57,7 @@ SessionEvent::operator new (size_t) { CrossThreadPool* p = pool->per_thread_pool (); SessionEvent* ev = static_cast<SessionEvent*> (p->alloc ()); - DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 Allocating SessionEvent from %2 ev @ %3\n", pthread_self(), p->name(), ev)); + DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 Allocating SessionEvent from %2 ev @ %3\n", pthread_name(), p->name(), ev)); #ifndef NDEBUG if (DEBUG::SessionEvents & PBD::debug_bits) { stacktrace (cerr, 40); @@ -74,7 +75,7 @@ SessionEvent::operator delete (void *ptr, size_t /*size*/) DEBUG_TRACE (DEBUG::SessionEvents, string_compose ( "%1 Deleting SessionEvent @ %2 ev thread pool = %3 ev pool = %4\n", - pthread_self(), ev, p->name(), ev->own_pool->name() + pthread_name(), ev, p->name(), ev->own_pool->name() )); #ifndef NDEBUG diff --git a/libs/ardour/session_ltc.cc b/libs/ardour/session_ltc.cc index b2fbaf602c..2ce25b5a48 100644 --- a/libs/ardour/session_ltc.cc +++ b/libs/ardour/session_ltc.cc @@ -31,7 +31,6 @@ using namespace std; using namespace ARDOUR; -using namespace MIDI; using namespace PBD; using namespace Timecode; diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 6d3083df77..ea6dfe81cf 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -22,8 +22,6 @@ #include <cerrno> #include <cassert> #include <unistd.h> -#include <fcntl.h> -#include <poll.h> #include <boost/shared_ptr.hpp> @@ -34,6 +32,7 @@ #include "pbd/error.h" #include "pbd/pthread_utils.h" +#include "pbd/timersub.h" #include "timecode/time.h" @@ -349,7 +348,7 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) * @param t time to send. */ int -Session::send_full_time_code (framepos_t const t, pframes_t nframes) +Session::send_full_time_code (framepos_t const t, MIDI::pframes_t nframes) { /* This function could easily send at a given frame offset, but would * that be useful? Does ardour do sub-block accurate locating? [DR] */ @@ -440,7 +439,7 @@ Session::send_full_time_code (framepos_t const t, pframes_t nframes) * earlier already this cycle by send_full_time_code) */ int -Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, pframes_t nframes) +Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, ARDOUR::pframes_t nframes) { if (_engine.freewheeling() || !_send_qf_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) { // cerr << "(MTC) Not sending MTC\n"; @@ -512,7 +511,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f assert (msg_time < end_frame); /* convert from session frames back to JACK frames using the transport speed */ - pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed; + ARDOUR::pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed; assert (out_stamp < nframes); MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer(nframes)); diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc index b2c4640880..b586ab196e 100644 --- a/libs/ardour/session_playlists.cc +++ b/libs/ardour/session_playlists.cc @@ -221,11 +221,11 @@ SessionPlaylists::get (vector<boost::shared_ptr<Playlist> >& s) const { Glib::Threads::Mutex::Lock lm (lock); - for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) { + for (List::const_iterator i = playlists.begin(); i != playlists.end(); ++i) { s.push_back (*i); } - for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { + for (List::const_iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { s.push_back (*i); } } @@ -448,11 +448,11 @@ SessionPlaylists::region_use_count (boost::shared_ptr<Region> region) const Glib::Threads::Mutex::Lock lm (lock); uint32_t cnt = 0; - for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) { + for (List::const_iterator i = playlists.begin(); i != playlists.end(); ++i) { cnt += (*i)->region_use_count (region); } - for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { + for (List::const_iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { cnt += (*i)->region_use_count (region); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index f3ad9d66dd..bbd3432205 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -33,15 +33,14 @@ #include <unistd.h> #include <sys/stat.h> #include <climits> -#include <fcntl.h> -#include <poll.h> #include <signal.h> -#include <sys/mman.h> #include <sys/time.h> #ifdef HAVE_SYS_VFS_H #include <sys/vfs.h> -#else +#endif + +#ifdef __APPLE__ #include <sys/param.h> #include <sys/mount.h> #endif @@ -69,11 +68,13 @@ #include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/file_utils.h" +#include "pbd/pathexpand.h" #include "pbd/pathscanner.h" #include "pbd/pthread_utils.h" #include "pbd/stacktrace.h" #include "pbd/convert.h" #include "pbd/clear_dir.h" +#include "pbd/localtime_r.h" #include "ardour/amp.h" #include "ardour/audio_diskstream.h" @@ -355,7 +356,7 @@ Session::post_engine_init () string Session::raid_path () const { - SearchPath raid_search_path; + Searchpath raid_search_path; for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) { raid_search_path += (*i).path; @@ -376,11 +377,11 @@ Session::setup_raid_path (string path) session_dirs.clear (); - SearchPath search_path(path); - SearchPath sound_search_path; - SearchPath midi_search_path; + Searchpath search_path(path); + Searchpath sound_search_path; + Searchpath midi_search_path; - for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { + for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) { sp.path = *i; sp.blocks = 0; // not needed session_dirs.push_back (sp); @@ -726,9 +727,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } else { - if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2"), - tmp_path, xml_path) << endmsg; + if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) { + error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"), + tmp_path, xml_path, g_strerror(errno)) << endmsg; if (g_remove (tmp_path.c_str()) != 0) { error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), tmp_path, g_strerror (errno)) << endmsg; @@ -2041,6 +2042,54 @@ Session::refresh_disk_space () _total_free_4k_blocks_uncertain = true; } } +#elif defined (COMPILER_MSVC) + vector<string> scanned_volumes; + vector<string>::iterator j; + vector<space_and_path>::iterator i; + DWORD nSectorsPerCluster, nBytesPerSector, + nFreeClusters, nTotalClusters; + char disk_drive[4]; + bool volume_found; + + _total_free_4k_blocks = 0; + + for (i = session_dirs.begin(); i != session_dirs.end(); i++) { + strncpy (disk_drive, (*i).path.c_str(), 3); + disk_drive[3] = 0; + strupr(disk_drive); + + volume_found = false; + if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters))) + { + int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster; + int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters; + i->blocks = (uint32_t)(nFreeBytes / 4096); + + for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) { + if (0 == j->compare(disk_drive)) { + volume_found = true; + break; + } + } + + if (!volume_found) { + scanned_volumes.push_back(disk_drive); + _total_free_4k_blocks += i->blocks; + } + } + } + + if (0 == _total_free_4k_blocks) { + strncpy (disk_drive, path().c_str(), 3); + disk_drive[3] = 0; + + if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters))) + { + int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster; + int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters; + _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096); + } + } #endif } @@ -2227,7 +2276,7 @@ Session::auto_save() } static bool -state_file_filter (const string &str, void */*arg*/) +state_file_filter (const string &str, void* /*arg*/) { return (str.length() > strlen(statefile_suffix) && str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix))); @@ -2404,7 +2453,7 @@ Session::commit_reversible_command (Command *cmd) } static bool -accept_all_audio_files (const string& path, void */*arg*/) +accept_all_audio_files (const string& path, void* /*arg*/) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) { return false; @@ -2418,7 +2467,7 @@ accept_all_audio_files (const string& path, void */*arg*/) } static bool -accept_all_midi_files (const string& path, void */*arg*/) +accept_all_midi_files (const string& path, void* /*arg*/) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) { return false; @@ -2430,7 +2479,7 @@ accept_all_midi_files (const string& path, void */*arg*/) } static bool -accept_all_state_files (const string& path, void */*arg*/) +accept_all_state_files (const string& path, void* /*arg*/) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) { return false; @@ -2586,6 +2635,8 @@ Session::cleanup_sources (CleanupReport& rep) bool used; string spath; int ret = -1; + string tmppath1; + string tmppath2; _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup); @@ -2710,9 +2761,6 @@ Session::cleanup_sources (CleanupReport& rep) i = tmp; } - char tmppath1[PATH_MAX+1]; - char tmppath2[PATH_MAX+1]; - if (candidates) { for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) { @@ -2721,19 +2769,10 @@ Session::cleanup_sources (CleanupReport& rep) for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { - if (realpath(spath.c_str(), tmppath1) == 0) { - error << string_compose (_("Cannot expand path %1 (%2)"), - spath, strerror (errno)) << endmsg; - continue; - } - - if (realpath((*i).c_str(), tmppath2) == 0) { - error << string_compose (_("Cannot expand path %1 (%2)"), - (*i), strerror (errno)) << endmsg; - continue; - } + tmppath1 = canonical_path (spath); + tmppath2 = canonical_path ((*i)); - if (strcmp(tmppath1, tmppath2) == 0) { + if (tmppath1 == tmppath2) { used = true; break; } @@ -2837,7 +2876,7 @@ Session::cleanup_sources (CleanupReport& rep) string peakpath = peak_path (base); if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { - if (::unlink (peakpath.c_str()) != 0) { + if (::g_unlink (peakpath.c_str()) != 0) { error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path, strerror (errno)) << endmsg; diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index 644fb19ffb..06a6b80e99 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -17,7 +17,9 @@ */ +#ifndef COMPILER_MSVC #include <stdbool.h> +#endif #include <cstdio> #include "ardour/session.h" @@ -59,11 +61,19 @@ intptr_t Session::vst_callback ( if (effect && effect->user) { plug = (VSTPlugin *) (effect->user); session = &plug->session(); +#ifdef COMPILER_MSVC + SHOW_CALLBACK ("am callback 0x%x, opcode = %d, plugin = \"%s\" ", (int) pthread_self().p, opcode, plug->name()); +#else SHOW_CALLBACK ("am callback 0x%x, opcode = %d, plugin = \"%s\" ", (int) pthread_self(), opcode, plug->name()); +#endif } else { plug = 0; session = 0; +#ifdef COMPILER_MSVC + SHOW_CALLBACK ("am callback 0x%x, opcode = %d", (int) pthread_self().p, opcode); +#else SHOW_CALLBACK ("am callback 0x%x, opcode = %d", (int) pthread_self(), opcode); +#endif } switch(opcode){ diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 830fd75fdf..d915bba845 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -30,6 +30,7 @@ #include "pbd/stl_delete.h" #include "pbd/strsplit.h" +#include <glib/gstdio.h> #include <glibmm/miscutils.h> #include "evoral/Control.hpp" @@ -96,7 +97,7 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist) SMFSource::~SMFSource () { if (removable()) { - unlink (_path.c_str()); + ::g_unlink (_path.c_str()); } } diff --git a/libs/ardour/sndfile_helpers.cc b/libs/ardour/sndfile_helpers.cc index 459890e829..2e618e043b 100644 --- a/libs/ardour/sndfile_helpers.cc +++ b/libs/ardour/sndfile_helpers.cc @@ -17,7 +17,9 @@ */ +#ifndef COMPILER_MSVC #include <strings.h> +#endif #include <map> #include <sndfile.h> diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc index c9f6c4014f..ceb88eddc9 100644 --- a/libs/ardour/sndfileimportable.cc +++ b/libs/ardour/sndfileimportable.cc @@ -51,7 +51,7 @@ SndFileImportableSource::read (Sample* buffer, framecnt_t nframes) return per_channel * sf_info.channels; } -uint +uint32_t SndFileImportableSource::channels () const { return sf_info.channels; diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index cf75cffba3..1c3144f164 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -26,10 +26,11 @@ #include <climits> #include <cstdarg> -#include <pwd.h> -#include <sys/utsname.h> #include <sys/stat.h> +#ifdef PLATFORM_WINDOWS +#include <glibmm/convert.h> +#endif #include <glibmm/miscutils.h> #include "ardour/sndfilesource.h" @@ -184,22 +185,30 @@ SndFileSource::init_sndfile () int SndFileSource::open () { - _descriptor = new SndFileDescriptor (_path, writable(), &_info); + string path_to_open; + +#ifdef PLATFORM_WINDOWS + path_to_open = Glib::locale_from_utf8(_path); +#else + path_to_open = _path; +#endif + + _descriptor = new SndFileDescriptor (path_to_open.c_str(), writable(), &_info); _descriptor->Closed.connect_same_thread (file_manager_connection, boost::bind (&SndFileSource::file_closed, this)); SNDFILE* sf = _descriptor->allocate (); if (sf == 0) { - char errbuf[256]; + char errbuf[1024]; sf_error_str (0, errbuf, sizeof (errbuf) - 1); #ifndef HAVE_COREAUDIO /* if we have CoreAudio, we will be falling back to that if libsndfile fails, so we don't want to see this message. */ - cerr << "failed to open " << _path << " with name " << _name << endl; + cerr << "failed to open " << path_to_open << " with name " << _name << endl; error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"), - _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg; + path_to_open, (writable() ? "read+write" : "reading"), errbuf) << endmsg; #endif return -1; } @@ -253,7 +262,7 @@ SndFileSource::open () if (!_broadcast_info->write_to_file (sf)) { error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"), - _path, _broadcast_info->get_error()) + path_to_open, _broadcast_info->get_error()) << endmsg; _flags = Flag (_flags & ~Broadcast); delete _broadcast_info; @@ -541,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*/) { @@ -768,12 +801,12 @@ SndFileSource::crossfade (Sample* data, framecnt_t cnt, int fade_in) } else if (xfade < xfade_frames) { - gain_t in[xfade]; - gain_t out[xfade]; + std::vector<gain_t> in(xfade); + std::vector<gain_t> out(xfade); /* short xfade, compute custom curve */ - compute_equal_power_fades (xfade, in, out); + compute_equal_power_fades (xfade, &in[0], &out[0]); for (framecnt_t n = 0; n < xfade; ++n) { xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]); diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index 618dddc70b..03039fea5b 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -19,8 +19,6 @@ #include <sys/stat.h> #include <unistd.h> -#include <fcntl.h> -#include <poll.h> #include <float.h> #include <cerrno> #include <ctime> diff --git a/libs/ardour/sse_functions_xmm.cc b/libs/ardour/sse_functions_xmm.cc index 48212ea8e1..f8a53cc6f8 100644 --- a/libs/ardour/sse_functions_xmm.cc +++ b/libs/ardour/sse_functions_xmm.cc @@ -45,8 +45,11 @@ x86_sse_find_peaks(const ARDOUR::Sample* buf, ARDOUR::pframes_t nframes, float * // use 64 byte prefetch for quadruple quads while (nframes >= 16) { +#ifdef COMPILER_MSVC + _mm_prefetch(((char*)buf+64), 0); // A total guess! Assumed to be eqivalent to +#else // the line below but waiting to be tested !! __builtin_prefetch(buf+64,0,0); - +#endif work = _mm_load_ps(buf); current_min = _mm_min_ps(current_min, work); current_max = _mm_max_ps(current_max, work); diff --git a/libs/ardour/template_utils.cc b/libs/ardour/template_utils.cc index 05007b0ade..b912fdc446 100644 --- a/libs/ardour/template_utils.cc +++ b/libs/ardour/template_utils.cc @@ -37,18 +37,18 @@ using namespace PBD; namespace ARDOUR { -SearchPath +Searchpath template_search_path () { - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(templates_dir_name); return spath; } -SearchPath +Searchpath route_template_search_path () { - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(route_templates_dir_name); return spath; } @@ -66,7 +66,7 @@ user_route_template_directory () } static bool -template_filter (const string &str, void */*arg*/) +template_filter (const string &str, void* /*arg*/) { if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) { return false; @@ -76,7 +76,7 @@ template_filter (const string &str, void */*arg*/) } static bool -route_template_filter (const string &str, void */*arg*/) +route_template_filter (const string &str, void* /*arg*/) { if (str.find (template_suffix) == str.length() - strlen (template_suffix)) { return true; @@ -97,7 +97,7 @@ find_session_templates (vector<TemplateInfo>& template_names) { vector<string *> *templates; PathScanner scanner; - SearchPath spath (template_search_path()); + Searchpath spath (template_search_path()); templates = scanner (spath.to_string(), template_filter, 0, true, true); @@ -133,7 +133,7 @@ find_route_templates (vector<TemplateInfo>& template_names) { vector<string *> *templates; PathScanner scanner; - SearchPath spath (route_template_search_path()); + Searchpath spath (route_template_search_path()); templates = scanner (spath.to_string(), route_template_filter, 0, false, true); diff --git a/libs/ardour/test/jack_utils_test.cc b/libs/ardour/test/jack_utils_test.cc new file mode 100644 index 0000000000..7645df6ff3 --- /dev/null +++ b/libs/ardour/test/jack_utils_test.cc @@ -0,0 +1,290 @@ + +#include <stdexcept> + +#ifdef PLATFORM_WINDOWS +#include <windows.h> // only for Sleep +#endif + +#include <glibmm/miscutils.h> + +#include "ardour/jack_utils.h" + +#include "jack_utils_test.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (JackUtilsTest); + +using namespace std; +using namespace ARDOUR; + +void +JackUtilsTest::test_driver_names () +{ + vector<string> driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + cout << "Number of possible JACK Audio drivers found on this system: " << driver_names.size () << endl; + + for (vector<string>::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + cout << "JACK Audio driver found: " << *i << endl; + } + + string default_audio_driver; + get_jack_default_audio_driver_name (default_audio_driver); + + cout << "The default audio driver on this system is: " << default_audio_driver << endl; + + driver_names.clear(); + + get_jack_midi_system_names (default_audio_driver, driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << "Number of possible JACK MIDI drivers found on this system for default audio driver: " << driver_names.size () << endl; + + for (vector<string>::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + cout << "JACK MIDI driver found: " << *i << endl; + } + + string default_midi_driver; + get_jack_default_midi_system_name (default_audio_driver, default_midi_driver); + + cout << "The default midi driver on this system is: " << default_midi_driver << endl; +} + +string +devices_string (const vector<string>& devices) +{ + std::string str; + for (vector<string>::const_iterator i = devices.begin(); i != devices.end();) { + str += *i; + if (++i != devices.end()) str += ", "; + } + return str; +} + +void +JackUtilsTest::test_device_names () +{ + vector<string> driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + + for (vector<string>::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + string devices = devices_string (get_jack_device_names_for_audio_driver (*i)); + cout << "JACK Audio driver found: " << *i << " with devices: " << devices << endl; + } +} + +void +JackUtilsTest::test_samplerates () +{ + vector<string> samplerates; + + get_jack_sample_rate_strings (samplerates); + cout << endl; + cout << "Number of possible Samplerates supported by JACK: " << samplerates.size () << endl; + + for (vector<string>::const_iterator i = samplerates.begin(); i != samplerates.end(); ++i) { + cout << "Samplerate: " << *i << endl; + } +} + +void +JackUtilsTest::test_period_sizes () +{ + vector<string> period_sizes; + + get_jack_period_size_strings (period_sizes); + cout << endl; + cout << "Number of possible Period sizes supported by JACK: " << period_sizes.size () << endl; + + for (vector<string>::const_iterator i = period_sizes.begin(); i != period_sizes.end(); ++i) { + cout << "Period size: " << *i << endl; + } +} + +void +JackUtilsTest::test_dither_modes () +{ + vector<string> driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + + for (vector<string>::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + vector<string> dither_modes; + + get_jack_dither_mode_strings (*i, dither_modes); + cout << "Number of possible Dither Modes supported by JACK driver " << *i << + ": " << dither_modes.size () << endl; + for (vector<string>::const_iterator j = dither_modes.begin(); j != dither_modes.end(); ++j) { + cout << "Dither Mode: " << *j << endl; + } + cout << endl; + } + +} + +void +JackUtilsTest::test_connect_server () +{ + cout << endl; + if (jack_server_running ()) { + cout << "Jack server running " << endl; + } else { + cout << "Jack server not running " << endl; + } +} + +void +JackUtilsTest::test_set_jack_path_env () +{ + cout << endl; + + bool path_env_set = false; + + string path_env = Glib::getenv ("PATH", path_env_set); + + if (path_env_set) { + cout << "PATH env set to: " << path_env << endl; + } else { + cout << "PATH env not set" << endl; + } + vector<string> server_dirs; + get_jack_server_dir_paths (server_dirs); + set_path_env_for_jack_autostart (server_dirs); + + path_env_set = false; + + path_env = Glib::getenv ("PATH", path_env_set); + + CPPUNIT_ASSERT (path_env_set); + + cout << "After set_jack_path_env PATH env set to: " << path_env << endl; +} + +void +JackUtilsTest::test_server_paths () +{ + cout << endl; + + vector<std::string> server_dirs; + + CPPUNIT_ASSERT (get_jack_server_dir_paths (server_dirs)); + + cout << "Number of Directories that may contain JACK servers: " << server_dirs.size () << endl; + + for (vector<std::string>::const_iterator i = server_dirs.begin(); i != server_dirs.end(); ++i) { + cout << "JACK server directory path: " << *i << endl; + } + + vector<string> server_names; + + CPPUNIT_ASSERT (get_jack_server_application_names (server_names)); + + cout << "Number of possible JACK server names on this system: " << server_names.size () << endl; + + for (vector<string>::const_iterator i = server_names.begin(); i != server_names.end(); ++i) { + cout << "JACK server name: " << *i << endl; + } + + vector<std::string> server_paths; + + CPPUNIT_ASSERT (get_jack_server_paths (server_dirs, server_names, server_paths)); + + cout << "Number of JACK servers on this system: " << server_paths.size () << endl; + + for (vector<std::string>::const_iterator i = server_paths.begin(); i != server_paths.end(); ++i) { + cout << "JACK server path: " << *i << endl; + } + + vector<std::string> server_paths2; + + CPPUNIT_ASSERT (get_jack_server_paths (server_paths2)); + + CPPUNIT_ASSERT (server_paths.size () == server_paths2.size ()); + + std::string default_server_path; + + CPPUNIT_ASSERT (get_jack_default_server_path (default_server_path)); + + cout << "The default JACK server on this system: " << default_server_path << endl; +} + +bool +get_default_jack_command_line (std::string& command_line) +{ + cout << endl; + + JackCommandLineOptions options; + + CPPUNIT_ASSERT (get_jack_default_server_path (options.server_path)); + + get_jack_default_audio_driver_name (options.driver); + + + // should fail, haven't set any device yet + CPPUNIT_ASSERT (!get_jack_command_line_string (options, command_line)); + + vector<string> devices = get_jack_device_names_for_audio_driver (options.driver); + + if (!devices.empty()) { + options.input_device = devices.front (); + options.output_device = devices.front (); + } else { + cout << "No audio devices available using default JACK driver using Dummy driver" << endl; + options.driver = dummy_driver_name; + devices = get_jack_device_names_for_audio_driver (options.driver); + CPPUNIT_ASSERT (!devices.empty ()); + options.input_device = devices.front (); + options.output_device = devices.front (); + } + + options.input_device = devices.front (); + options.output_device = devices.front (); + + string midi_driver; + + get_jack_default_midi_system_name (options.driver, options.midi_driver); + // + // this at least should create a valid jack command line + return get_jack_command_line_string (options, command_line); + +} + +void +JackUtilsTest::test_config () +{ + std::string config_path(get_jack_server_user_config_file_path()); + + cout << "Jack server config file path: " << config_path << endl; + + std::string command_line; + + CPPUNIT_ASSERT (get_default_jack_command_line (command_line)); + + CPPUNIT_ASSERT (write_jack_config_file (config_path, command_line)); +} + + +void +JackUtilsTest::test_command_line () +{ + string command_line; + + // this at least should create a valid jack command line + CPPUNIT_ASSERT (get_default_jack_command_line (command_line)); + + cout << "Default JACK command line: " << command_line << endl; +} diff --git a/libs/ardour/test/jack_utils_test.h b/libs/ardour/test/jack_utils_test.h new file mode 100644 index 0000000000..08fad2fc36 --- /dev/null +++ b/libs/ardour/test/jack_utils_test.h @@ -0,0 +1,31 @@ + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +class JackUtilsTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (JackUtilsTest); + CPPUNIT_TEST (test_driver_names); + CPPUNIT_TEST (test_device_names); + CPPUNIT_TEST (test_samplerates); + CPPUNIT_TEST (test_period_sizes); + CPPUNIT_TEST (test_dither_modes); + CPPUNIT_TEST (test_connect_server); + CPPUNIT_TEST (test_set_jack_path_env); + CPPUNIT_TEST (test_server_paths); + CPPUNIT_TEST (test_config); + CPPUNIT_TEST (test_command_line); + CPPUNIT_TEST_SUITE_END (); + +public: + void test_driver_names (); + void test_device_names (); + void test_samplerates (); + void test_period_sizes (); + void test_dither_modes (); + void test_connect_server (); + void test_set_jack_path_env (); + void test_server_paths (); + void test_config (); + void test_command_line (); +}; diff --git a/libs/ardour/test/midi_clock_slave_test.cc b/libs/ardour/test/midi_clock_slave_test.cc index dcb159cb2c..4349df22eb 100644 --- a/libs/ardour/test/midi_clock_slave_test.cc +++ b/libs/ardour/test/midi_clock_slave_test.cc @@ -27,7 +27,7 @@ MIDIClock_SlaveTest::testStepResponse () for (framecnt_t i = 1; i<= 100 * period_size; i++) { // simulate jitter - framecnt_t input_delta = framecnt_t (one_ppqn_in_frames + 0.1 * (double(random()) / double (RAND_MAX)) * one_ppqn_in_frames); + framecnt_t input_delta = framecnt_t (one_ppqn_in_frames + 0.1 * (double(g_random_int()) / double (RAND_MAX)) * one_ppqn_in_frames); if (i % input_delta == 0) { update_midi_clock (*parser, start_time + i); diff --git a/libs/ardour/test/plugins_test.cc b/libs/ardour/test/plugins_test.cc new file mode 100644 index 0000000000..0e4bddcda6 --- /dev/null +++ b/libs/ardour/test/plugins_test.cc @@ -0,0 +1,54 @@ +#include <iostream> + +#include "ardour/plugin_manager.h" +#include "ardour/ladspa_search_path.h" + +#include "plugins_test.h" +#include "test_common.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (PluginsTest); + +using namespace std; +using namespace ARDOUR; +using namespace PBD; + +void +print_plugin_info (PluginInfoPtr pp) +{ + cout << "LADSPA Plugin, name " << pp->name + << ", category " << pp->category + << ", creator " << pp->creator + << ", path " << pp->path + << ", n_inputs " << pp->n_inputs.n_audio () + << ", n_outputs " << pp->n_outputs.n_audio () + << endl; + +} + +void +PluginsTest::test () +{ + PluginManager& pm = PluginManager::instance (); + + pm.refresh (); + + Searchpath ladspa_paths(ladspa_search_path ()); + + cout << "Number of Ladspa paths found: " << ladspa_paths.size () << endl; + + for (vector<std::string>::iterator i = ladspa_paths.begin (); i != ladspa_paths.end(); ++i) + { + cout << "LADSPA search path includes: " << *i << endl; + } + + PluginInfoList& ladspa_list = pm.ladspa_plugin_info (); + + cout << "Number of Ladspa plugins found: " << ladspa_list.size () << endl; + + for (PluginInfoList::iterator i = ladspa_list.begin (); i != ladspa_list.end(); ++i) + { + print_plugin_info (*i); + } + + +} diff --git a/libs/ardour/test/plugins_test.h b/libs/ardour/test/plugins_test.h new file mode 100644 index 0000000000..1503b2bde2 --- /dev/null +++ b/libs/ardour/test/plugins_test.h @@ -0,0 +1,12 @@ +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +class PluginsTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (PluginsTest); + CPPUNIT_TEST (test); + CPPUNIT_TEST_SUITE_END (); + +public: + void test (); +}; diff --git a/libs/ardour/test/resampled_source_test.cc b/libs/ardour/test/resampled_source_test.cc index 5aaf71b7aa..c8ef0f4a95 100644 --- a/libs/ardour/test/resampled_source_test.cc +++ b/libs/ardour/test/resampled_source_test.cc @@ -1,4 +1,4 @@ -// this is included first to avoid SearchPath definition on windows +// this is included first to avoid Searchpath definition on windows #include "test_common.h" #include "pbd/file_utils.h" diff --git a/libs/ardour/test/test_common.cc b/libs/ardour/test/test_common.cc index 61f92972d1..71eba65bbb 100644 --- a/libs/ardour/test/test_common.cc +++ b/libs/ardour/test/test_common.cc @@ -25,10 +25,10 @@ using namespace std; -PBD::SearchPath +PBD::Searchpath test_search_path () { -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS std::string wsp(g_win32_get_package_installation_directory_of_module(NULL)); return Glib::build_filename (wsp, "ardour_testdata"); #else diff --git a/libs/ardour/test/test_common.h b/libs/ardour/test/test_common.h index 91fd066ac2..bfda543508 100644 --- a/libs/ardour/test/test_common.h +++ b/libs/ardour/test/test_common.h @@ -21,7 +21,7 @@ #include "pbd/search_path.h" -PBD::SearchPath test_search_path (); +PBD::Searchpath test_search_path (); std::string new_test_output_dir (std::string prefix = ""); diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index aa06912913..d1d2372977 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -36,7 +36,9 @@ #include <sys/stat.h> #include <sys/time.h> #include <fcntl.h> +#ifndef COMPILER_MSVC #include <dirent.h> +#endif #include <errno.h> #include <regex.h> diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index cb40d6eac8..168bd0506e 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -528,8 +528,9 @@ VSTPlugin::connect_and_run (BufferSet& bufs, { Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset); - float *ins[_plugin->numInputs]; - float *outs[_plugin->numOutputs]; + // VC++ doesn't support this C99 extension. Use alloca instead of dynamic array (rather than std::vector which allocs on the heap) + float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*)); + float** outs = (float**)alloca(_plugin->numInputs*sizeof(float*)); int32_t i; const uint32_t nbufs = bufs.count().n_audio(); @@ -552,7 +553,7 @@ VSTPlugin::connect_and_run (BufferSet& bufs, } /* we already know it can support processReplacing */ - _plugin->processReplacing (_plugin, ins, outs, nframes); + _plugin->processReplacing (_plugin, &ins[0], &outs[0], nframes); return 0; } diff --git a/libs/ardour/worker.cc b/libs/ardour/worker.cc index b13398c69d..d5238adb60 100644 --- a/libs/ardour/worker.cc +++ b/libs/ardour/worker.cc @@ -23,6 +23,8 @@ #include "ardour/worker.h" #include "pbd/error.h" +#include <glibmm/timer.h> + namespace ARDOUR { Worker::Worker(Workee* workee, uint32_t ring_size) @@ -128,7 +130,7 @@ Worker::run() continue; } while (!verify_message_completeness(_requests)) { - ::usleep(2000); + Glib::usleep(2000); if (_exit) { return; } diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 18c2188f6a..21f745e20b 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -2,6 +2,7 @@ from waflib.extras import autowaf as autowaf from waflib import Options import os +import sys import re import subprocess import sys @@ -106,6 +107,7 @@ libardour_sources = [ 'io_processor.cc', 'kmeterdsp.cc', 'ladspa_plugin.cc', + 'ladspa_search_path.cc', 'location.cc', 'location_importer.cc', 'ltc_slave.cc', @@ -247,8 +249,11 @@ def configure(conf): autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', exact_version='0.3.2') autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') - autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', - atleast_version='0.4.0') + if Options.options.dist_target != 'mingw': + autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', + atleast_version='0.4.0') + autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', + atleast_version='0.3.2') autowaf.check_pkg(conf, 'samplerate', uselib_store='SAMPLERATE', atleast_version='0.1.0') autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', @@ -451,6 +456,7 @@ def build(bld): create_ardour_test_program(bld, obj.includes, 'framepos_minus_beats', 'test_framepos_minus_beats', ['test/framepos_minus_beats_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_equivalent_regions', 'test_playlist_equivalent_regions', ['test/playlist_equivalent_regions_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_layering', 'test_playlist_layering', ['test/playlist_layering_test.cc']) + create_ardour_test_program(bld, obj.includes, 'plugins_test', 'test_plugins', ['test/plugins_test.cc']) create_ardour_test_program(bld, obj.includes, 'region_naming', 'test_region_naming', ['test/region_naming_test.cc']) create_ardour_test_program(bld, obj.includes, 'control_surface', 'test_control_surfaces', ['test/control_surfaces_test.cc']) create_ardour_test_program(bld, obj.includes, 'mtdm_test', 'test_mtdm', ['test/mtdm_test.cc']) @@ -468,6 +474,7 @@ def build(bld): test/framepos_minus_beats_test.cc test/playlist_equivalent_regions_test.cc test/playlist_layering_test.cc + test/plugins_test.cc test/region_naming_test.cc test/control_surfaces_test.cc test/mtdm_test.cc diff --git a/libs/audiographer/audiographer/broadcast_info.h b/libs/audiographer/audiographer/broadcast_info.h index cdc0aaac3a..dd776d17af 100644 --- a/libs/audiographer/audiographer/broadcast_info.h +++ b/libs/audiographer/audiographer/broadcast_info.h @@ -21,6 +21,8 @@ #ifndef AUDIOGRAPHER_BROADCAST_INFO_H #define AUDIOGRAPHER_BROADCAST_INFO_H +#include <stdint.h> + #include <string> #include <ctime> diff --git a/libs/audiographer/audiographer/debug_utils.h b/libs/audiographer/audiographer/debug_utils.h index b11f065b42..a8c63e85b6 100644 --- a/libs/audiographer/audiographer/debug_utils.h +++ b/libs/audiographer/audiographer/debug_utils.h @@ -8,6 +8,7 @@ #ifdef __GNUC__ #include <cxxabi.h> +#include <cstdlib> #endif #include "audiographer/visibility.h" diff --git a/libs/audiographer/audiographer/sndfile/tmp_file.h b/libs/audiographer/audiographer/sndfile/tmp_file.h index 8655fd7191..facb872abf 100644 --- a/libs/audiographer/audiographer/sndfile/tmp_file.h +++ b/libs/audiographer/audiographer/sndfile/tmp_file.h @@ -4,6 +4,9 @@ #include <cstdio> #include <string> +#include <glib.h> +#include <glib/gstdio.h> + #include "sndfile_writer.h" #include "sndfile_reader.h" @@ -18,7 +21,7 @@ class TmpFile : public SndfileWriter<T>, public SndfileReader<T> /// \a filename_template must match the requirements for mkstemp, i.e. end in "XXXXXX" TmpFile (char * filename_template, int format, ChannelCount channels, framecnt_t samplerate) - : SndfileHandle (mkstemp(filename_template), true, SndfileBase::ReadWrite, format, channels, samplerate) + : SndfileHandle (g_mkstemp(filename_template), true, SndfileBase::ReadWrite, format, channels, samplerate) , filename (filename_template) {} diff --git a/libs/audiographer/private/gdither/gdither.cc b/libs/audiographer/private/gdither/gdither.cc index fe9ecc655a..75e16d7863 100644 --- a/libs/audiographer/private/gdither/gdither.cc +++ b/libs/audiographer/private/gdither/gdither.cc @@ -226,7 +226,7 @@ inline static void gdither_innner_loop(const GDitherType dt, switch (bit_depth) { case GDither8bit: - o8[i] = (u_int8_t) (clamped * post_scale); + o8[i] = (uint8_t) (clamped * post_scale); break; case GDither16bit: o16[i] = (int16_t) (clamped * post_scale); @@ -292,7 +292,7 @@ inline static void gdither_innner_loop_fp(const GDitherType dt, break; } - clamped = rintf(tmp); + clamped = (double)lrintf(tmp); if (clamped > clamp_u) { clamped = clamp_u; } else if (clamped < clamp_l) { diff --git a/libs/audiographer/src/general/broadcast_info.cc b/libs/audiographer/src/general/broadcast_info.cc index 43e5008e52..df69ac9c79 100644 --- a/libs/audiographer/src/general/broadcast_info.cc +++ b/libs/audiographer/src/general/broadcast_info.cc @@ -34,7 +34,7 @@ namespace AudioGrapher static void snprintf_bounded_null_filled (char* target, size_t target_size, char const * fmt, ...) { - char buf[target_size+1]; + char *buf = (char*)alloca(target_size+1); va_list ap; va_start (ap, fmt); diff --git a/libs/audiographer/tests/sndfile/tmp_file_test.cc b/libs/audiographer/tests/sndfile/tmp_file_test.cc index 94647cc1a6..9ce8af7a5c 100644 --- a/libs/audiographer/tests/sndfile/tmp_file_test.cc +++ b/libs/audiographer/tests/sndfile/tmp_file_test.cc @@ -23,7 +23,7 @@ class TmpFileTest : public CppUnit::TestFixture void testProcess() { - uint channels = 2; + uint32_t channels = 2; file.reset (new TmpFile<float>(SF_FORMAT_WAV | SF_FORMAT_FLOAT, channels, 44100)); AllocatingProcessContext<float> c (random_data, frames, channels); c.set_flag (ProcessContext<float>::EndOfInput); diff --git a/libs/backends/jack/jack_utils.cc b/libs/backends/jack/jack_utils.cc index e009b05cd7..331c164353 100644 --- a/libs/backends/jack/jack_utils.cc +++ b/libs/backends/jack/jack_utils.cc @@ -558,7 +558,7 @@ ARDOUR::set_path_env_for_jack_autostart (const vector<std::string>& dirs) #ifdef __APPLE__ // push it back into the environment so that auto-started JACK can find it. // XXX why can't we just expect OS X users to have PATH set correctly? we can't ... - setenv ("PATH", SearchPath(dirs).to_string().c_str(), 1); + setenv ("PATH", Searchpath(dirs).to_string().c_str(), 1); #else /* silence a compiler unused variable warning */ (void) dirs; @@ -581,7 +581,7 @@ ARDOUR::get_jack_server_dir_paths (vector<std::string>& server_dir_paths) server_dir_paths.push_back (Glib::path_get_dirname (execpath)); #endif - SearchPath sp(string(g_getenv("PATH"))); + Searchpath sp(string(g_getenv("PATH"))); #ifdef WIN32 gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL); diff --git a/libs/backends/jack/wscript b/libs/backends/jack/wscript index 111ecf3218..4e54af0be5 100644 --- a/libs/backends/jack/wscript +++ b/libs/backends/jack/wscript @@ -1,5 +1,6 @@ #!/usr/bin/env python from waflib.extras import autowaf as autowaf +from waflib import Options import os import sys import re @@ -19,7 +20,14 @@ def options(opt): autowaf.set_options(opt) def configure(conf): - autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.121.0') + # + # PortAudio is currently used to get a list of audio device names. + # We should find a better way to do this that doesn't involve this + # kind of dependency. + # + if Options.options.dist_target == 'mingw': + autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', + atleast_version='19') autowaf.configure(conf) def build(bld): @@ -35,7 +43,10 @@ def build(bld): obj.includes = ['.'] obj.name = 'jack_audiobackend' obj.target = 'jack_audiobackend' - obj.uselib = [ 'JACK' ] + if Options.options.dist_target == 'mingw': + obj.uselib = [ 'JACK', 'PORTAUDIO' ] + else: + obj.uselib = [ 'JACK' ] obj.use = 'libardour libpbd' obj.vnum = JACKBACKEND_VERSION obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3', 'backends') diff --git a/libs/clearlooks-newer/animation.c b/libs/clearlooks-newer/animation.c index 2c6a6fdc42..8339ed7c19 100644 --- a/libs/clearlooks-newer/animation.c +++ b/libs/clearlooks-newer/animation.c @@ -159,11 +159,12 @@ add_animation (const GtkWidget *widget, gdouble stop_time) static gboolean update_animation_info (gpointer key, gpointer value, gpointer user_data) { - (void) user_data; - - AnimationInfo *animation_info = value; + AnimationInfo *animation_info; GtkWidget *widget = key; + animation_info = value; + (void) user_data; + g_assert ((widget != NULL) && (animation_info != NULL)); /* remove the widget from the hash table if it is not drawable */ @@ -217,9 +218,10 @@ animation_timeout_handler (gpointer data) static void on_checkbox_toggle (GtkWidget *widget, gpointer data) { + AnimationInfo *animation_info; (void) data; - AnimationInfo *animation_info = lookup_animation_info (widget); + animation_info = lookup_animation_info (widget); if (animation_info != NULL) { diff --git a/libs/clearlooks-newer/clearlooks_draw.c b/libs/clearlooks-newer/clearlooks_draw.c index e44610b4ee..1f98485ce5 100644 --- a/libs/clearlooks-newer/clearlooks_draw.c +++ b/libs/clearlooks-newer/clearlooks_draw.c @@ -945,12 +945,12 @@ clearlooks_draw_menubar0 (cairo_t *cr, const MenuBarParameters *menubar, int x, int y, int width, int height) { - (void) params; - (void) menubar; - /* const CairoColor *light = &colors->shade[0]; */ const CairoColor *dark = &colors->shade[3]; + (void) params; + (void) menubar; + cairo_set_line_width (cr, 1); cairo_translate (cr, x, y+0.5); @@ -972,12 +972,12 @@ clearlooks_draw_menubar2 (cairo_t *cr, const MenuBarParameters *menubar, int x, int y, int width, int height) { - (void) params; - (void) menubar; - CairoColor lower; cairo_pattern_t *pattern; + (void) params; + (void) menubar; + ge_shade_color (&colors->bg[0], 0.96, &lower); cairo_translate (cr, x, y); @@ -1316,10 +1316,10 @@ clearlooks_draw_separator (cairo_t *cr, const SeparatorParameters *separator, int x, int y, int width, int height) { - (void) widget; - + CairoColor hilight; CairoColor color = colors->shade[3]; - CairoColor hilight; + + (void) widget; ge_shade_color (&color, 1.4, &hilight); cairo_save (cr); @@ -1432,11 +1432,12 @@ clearlooks_draw_toolbar (cairo_t *cr, const ToolbarParameters *toolbar, int x, int y, int width, int height) { - (void) widget; - - const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; - const CairoColor *dark = &colors->shade[3]; CairoColor light; + const CairoColor *dark; + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + + (void) widget; + dark = &colors->shade[3]; ge_shade_color (fill, 1.1, &light); cairo_set_line_width (cr, 1.0); @@ -1575,13 +1576,13 @@ clearlooks_draw_scrollbar_trough (cairo_t *cr, const ScrollBarParameters *scrollbar, int x, int y, int width, int height) { - (void) widget; - - const CairoColor *bg = &colors->shade[2]; - const CairoColor *border = &colors->shade[5]; + const CairoColor *bg; CairoColor bg_shade; - cairo_pattern_t *pattern; + cairo_pattern_t *pattern; + const CairoColor *border = &colors->shade[5]; + (void) widget; + bg = &colors->shade[2]; ge_shade_color (bg, 0.95, &bg_shade); cairo_set_line_width (cr, 1); @@ -1809,11 +1810,11 @@ clearlooks_draw_statusbar (cairo_t *cr, const WidgetParameters *widget, int x, int y, int width, int height) { + CairoColor hilight; + const CairoColor *dark = &colors->shade[3]; + (void) widget; (void) height; - - const CairoColor *dark = &colors->shade[3]; - CairoColor hilight; ge_shade_color (dark, 1.4, &hilight); @@ -1837,9 +1838,9 @@ clearlooks_draw_menu_frame (cairo_t *cr, const WidgetParameters *widget, int x, int y, int width, int height) { + const CairoColor *border = &colors->shade[5]; (void) widget; - const CairoColor *border = &colors->shade[5]; cairo_translate (cr, x, y); cairo_set_line_width (cr, 1); /* @@ -1924,15 +1925,15 @@ clearlooks_draw_resize_grip (cairo_t *cr, const ResizeGripParameters *grip, int x, int y, int width, int height) { - (void) widget; - - const CairoColor *dark = &colors->shade[4]; CairoColor hilight; int lx, ly; int x_down; int y_down; int dots; - + const CairoColor *dark = &colors->shade[4]; + + (void) widget; + ge_shade_color (dark, 1.5, &hilight); /* The number of dots fitting into the area. Just hardcoded to 4 right now. */ @@ -1996,17 +1997,18 @@ clearlooks_draw_radiobutton (cairo_t *cr, const CheckboxParameters *checkbox, int x, int y, int width, int height) { - (void) width; - (void) height; - const CairoColor *border; const CairoColor *dot; CairoColor shadow; CairoColor highlight; cairo_pattern_t *pt; gboolean inconsistent; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + (void) width; + (void) height; + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; diff --git a/libs/clearlooks-newer/clearlooks_draw_glossy.c b/libs/clearlooks-newer/clearlooks_draw_glossy.c index a0e250ee64..a8dd9ef7a3 100644 --- a/libs/clearlooks-newer/clearlooks_draw_glossy.c +++ b/libs/clearlooks-newer/clearlooks_draw_glossy.c @@ -1088,13 +1088,16 @@ clearlooks_glossy_draw_toolbar (cairo_t *cr, const ToolbarParameters *toolbar, int x, int y, int width, int height) { + CairoColor light; + const CairoColor *dark; + + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + dark = &colors->shade[3]; + (void) widget; (void) width; (void) height; - - const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; - const CairoColor *dark = &colors->shade[3]; - CairoColor light; + ge_shade_color (fill, 1.1, &light); cairo_set_line_width (cr, 1.0); @@ -1232,9 +1235,6 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, const CheckboxParameters *checkbox, int x, int y, int width, int height) { - (void) width; - (void) height; - const CairoColor *border; const CairoColor *dot; CairoColor shadow; @@ -1243,6 +1243,9 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + (void) width; + (void) height; + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; diff --git a/libs/clearlooks-newer/clearlooks_draw_gummy.c b/libs/clearlooks-newer/clearlooks_draw_gummy.c index 0d736b5acc..ca208c2ebc 100644 --- a/libs/clearlooks-newer/clearlooks_draw_gummy.c +++ b/libs/clearlooks-newer/clearlooks_draw_gummy.c @@ -790,10 +790,10 @@ clearlooks_gummy_draw_separator (cairo_t *cr, const SeparatorParameters *separator, int x, int y, int width, int height) { - (void) widget; - - CairoColor color = colors->shade[3]; CairoColor hilight; + CairoColor color = colors->shade[3]; + + (void) widget; ge_shade_color (&color, 1.3, &hilight); cairo_save (cr); @@ -1162,11 +1162,14 @@ clearlooks_gummy_draw_toolbar (cairo_t *cr, const ToolbarParameters *toolbar, int x, int y, int width, int height) { - (void) widget; - - const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; - const CairoColor *dark = &colors->shade[3]; CairoColor light; + const CairoColor *dark; + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + + (void) widget; + + dark = &colors->shade[3]; + ge_shade_color (fill, toolbar->style == 1 ? 1.1 : 1.05, &light); cairo_set_line_width (cr, 1.0); @@ -1302,12 +1305,12 @@ clearlooks_gummy_draw_statusbar (cairo_t *cr, const WidgetParameters *widget, int x, int y, int width, int height) { + CairoColor hilight; + const CairoColor *dark = &colors->shade[3]; + (void) widget; (void) height; - const CairoColor *dark = &colors->shade[3]; - CairoColor hilight; - ge_shade_color (dark, 1.3, &hilight); cairo_set_line_width (cr, 1); @@ -1331,9 +1334,6 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, const CheckboxParameters *checkbox, int x, int y, int width, int height) { - (void) width; - (void) height; - const CairoColor *border; const CairoColor *dot; CairoColor shadow; @@ -1342,6 +1342,9 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + (void) width; + (void) height; + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; diff --git a/libs/clearlooks-newer/clearlooks_rc_style.c b/libs/clearlooks-newer/clearlooks_rc_style.c index 9f8fbd4945..8d6e0aa898 100644 --- a/libs/clearlooks-newer/clearlooks_rc_style.c +++ b/libs/clearlooks-newer/clearlooks_rc_style.c @@ -173,9 +173,9 @@ clearlooks_gtk2_rc_parse_boolean (GtkSettings *settings, GScanner *scanner, gboolean *retval) { - (void) settings; - guint token; + + (void) settings; token = g_scanner_get_next_token(scanner); token = g_scanner_get_next_token(scanner); @@ -198,10 +198,10 @@ clearlooks_gtk2_rc_parse_color(GtkSettings *settings, GScanner *scanner, GdkColor *color) { - (void) settings; - guint token; + (void) settings; + /* Skip 'blah_color' */ token = g_scanner_get_next_token(scanner); @@ -217,10 +217,10 @@ clearlooks_gtk2_rc_parse_double (GtkSettings *settings, GScanner *scanner, gdouble *val) { - (void) settings; - guint token; + (void) settings; + /* Skip 'blah' */ token = g_scanner_get_next_token(scanner); @@ -242,10 +242,10 @@ clearlooks_gtk2_rc_parse_int (GtkSettings *settings, GScanner *scanner, guint8 *progressbarstyle) { - (void) settings; - guint token; + (void) settings; + /* Skip 'sunkenmenubar' */ token = g_scanner_get_next_token(scanner); @@ -267,10 +267,10 @@ clearlooks_gtk2_rc_parse_style (GtkSettings *settings, GScanner *scanner, ClearlooksStyles *style) { - (void) settings; - guint token; + (void) settings; + g_assert (CL_NUM_STYLES == CL_STYLE_GUMMY + 1); /* so that people don't forget ;-) */ /* Skip 'style' */ @@ -308,10 +308,10 @@ clearlooks_gtk2_rc_parse_dummy (GtkSettings *settings, GScanner *scanner, const gchar *name) { - (void) settings; - guint token; + (void) settings; + /* Skip option */ token = g_scanner_get_next_token (scanner); diff --git a/libs/clearlooks-newer/clearlooks_style.c b/libs/clearlooks-newer/clearlooks_style.c index f1b46a5426..d1ac8d5d39 100644 --- a/libs/clearlooks-newer/clearlooks_style.c +++ b/libs/clearlooks-newer/clearlooks_style.c @@ -956,14 +956,14 @@ clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation) static void clearlooks_style_draw_option (DRAW_ARGS) { - (void) detail; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); const ClearlooksColors *colors; WidgetParameters params; CheckboxParameters checkbox; cairo_t *cr; + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + (void) detail; + CHECK_ARGS SANITIZE_SIZE @@ -1019,14 +1019,17 @@ clearlooks_style_draw_vline (GtkStyle *style, gint y2, gint x) { + const ClearlooksColors *colors; + SeparatorParameters separator; + cairo_t *cr; + + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + (void) state_type; (void) widget; (void) detail; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - const ClearlooksColors *colors; - SeparatorParameters separator = { FALSE }; - cairo_t *cr; + + separator.horizontal = FALSE; CHECK_ARGS @@ -1053,13 +1056,13 @@ clearlooks_style_draw_hline (GtkStyle *style, gint x2, gint y) { - (void) state_type; - (void) widget; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); const ClearlooksColors *colors; cairo_t *cr; SeparatorParameters separator; + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + (void) state_type; + (void) widget; CHECK_ARGS @@ -1136,13 +1139,14 @@ clearlooks_style_draw_resize_grip (GtkStyle *style, gint width, gint height) { - (void) detail; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - ClearlooksColors *colors = &clearlooks_style->colors; + ClearlooksColors *colors; cairo_t *cr; WidgetParameters params; ResizeGripParameters grip; + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + (void) detail; + colors = &clearlooks_style->colors; CHECK_ARGS SANITIZE_SIZE @@ -1164,14 +1168,15 @@ clearlooks_style_draw_resize_grip (GtkStyle *style, static void clearlooks_style_draw_tab (DRAW_ARGS) { - (void) shadow_type; - (void) detail; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - ClearlooksColors *colors = &clearlooks_style->colors; + ClearlooksColors *colors; WidgetParameters params; ArrowParameters arrow; cairo_t *cr; + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + (void) shadow_type; + (void) detail; + colors = &clearlooks_style->colors; CHECK_ARGS SANITIZE_SIZE @@ -1202,15 +1207,18 @@ clearlooks_style_draw_arrow (GtkStyle *style, gint width, gint height) { + ClearlooksColors *colors; + WidgetParameters params; + ArrowParameters arrow; + cairo_t *cr; + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + (void) shadow; (void) detail; (void) fill; - - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - ClearlooksColors *colors = &clearlooks_style->colors; - WidgetParameters params; - ArrowParameters arrow; - cairo_t *cr = ge_gdk_drawable_to_cairo (window, area); + + cr = ge_gdk_drawable_to_cairo (window, area); + colors = &clearlooks_style->colors; CHECK_ARGS SANITIZE_SIZE @@ -1475,10 +1483,9 @@ clearlooks_style_draw_layout (GtkStyle * style, GtkWidget * widget, const gchar * detail, gint x, gint y, PangoLayout * layout) { - (void) detail; - GdkGC *gc; + (void) detail; g_return_if_fail (GTK_IS_STYLE (style)); g_return_if_fail (window != NULL); @@ -1525,17 +1532,20 @@ clearlooks_style_draw_render_icon (GtkStyle *style, GtkWidget *widget, const char *detail) { - (void) direction; - (void) detail; - - int width = 1; - int height = 1; + int width; + int height; GdkPixbuf *scaled; GdkPixbuf *stated; GdkPixbuf *base_pixbuf; GdkScreen *screen; GtkSettings *settings; - + + width = 1; + height = 1; + + (void) direction; + (void) detail; + /* Oddly, style can be NULL in this function, because * GtkIconSet can be used without a style and if so * it uses this function. diff --git a/libs/evoral/evoral/Sequence.hpp b/libs/evoral/evoral/Sequence.hpp index de8f97a297..e762d64ad1 100644 --- a/libs/evoral/evoral/Sequence.hpp +++ b/libs/evoral/evoral/Sequence.hpp @@ -181,7 +181,7 @@ public: OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; } void set_overlap_pitch_resolution(OverlapPitchResolution opr); - void set_notes (const Sequence<Time>::Notes& n); + void set_notes (const typename Sequence<Time>::Notes& n); typedef boost::shared_ptr< Event<Time> > SysExPtr; typedef boost::shared_ptr<const Event<Time> > constSysExPtr; @@ -271,10 +271,16 @@ public: const const_iterator& end() const { return _end_iter; } + // CONST iterator implementations (x3) typename Notes::const_iterator note_lower_bound (Time t) const; typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const; typename SysExes::const_iterator sysex_lower_bound (Time t) const; + // NON-CONST iterator implementations (x3) + typename Notes::iterator note_lower_bound (Time t); + typename PatchChanges::iterator patch_change_lower_bound (Time t); + typename SysExes::iterator sysex_lower_bound (Time t); + bool control_to_midi_event(boost::shared_ptr< Event<Time> >& ev, const ControlIterator& iter) const; diff --git a/libs/evoral/evoral/midi_util.h b/libs/evoral/evoral/midi_util.h index 6c394b14b8..5c72fb86c9 100644 --- a/libs/evoral/evoral/midi_util.h +++ b/libs/evoral/evoral/midi_util.h @@ -22,7 +22,6 @@ #include <iostream> #include <stdint.h> -#include <stdbool.h> #include <string> #include <sys/types.h> #include <assert.h> diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index a095daa135..2453574e5c 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -812,7 +812,7 @@ ControlList::modify (iterator iter, double when, double val) (*iter)->when = when; (*iter)->value = val; - if (std::isnan (val)) { + if (isnan (val)) { abort (); } diff --git a/libs/evoral/src/Curve.cpp b/libs/evoral/src/Curve.cpp index 6f3532fdcb..44fc48f728 100644 --- a/libs/evoral/src/Curve.cpp +++ b/libs/evoral/src/Curve.cpp @@ -22,6 +22,7 @@ #include <climits> #include <cfloat> #include <cmath> +#include <vector> #include <glibmm/threads.h> @@ -56,8 +57,8 @@ Curve::solve () (www.korf.co.uk/spline.pdf) for more details. */ - double x[npoints]; - double y[npoints]; + vector<double> x(npoints); + vector<double> y(npoints); uint32_t i; ControlList::EventList::const_iterator xx; diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index 204ef58f33..7084a90491 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -1201,11 +1201,13 @@ Sequence<Time>::overlaps_unlocked (const NotePtr& note, const NotePtr& without) template<typename Time> void -Sequence<Time>::set_notes (const Sequence<Time>::Notes& n) +Sequence<Time>::set_notes (const typename Sequence<Time>::Notes& n) { _notes = n; } +// CONST iterator implementations (x3) + /** Return the earliest note with time >= t */ template<typename Time> typename Sequence<Time>::Notes::const_iterator @@ -1239,6 +1241,41 @@ Sequence<Time>::sysex_lower_bound (Time t) const return i; } +// NON-CONST iterator implementations (x3) + +/** Return the earliest note with time >= t */ +template<typename Time> +typename Sequence<Time>::Notes::iterator +Sequence<Time>::note_lower_bound (Time t) +{ + NotePtr search_note(new Note<Time>(0, t, 0, 0, 0)); + typename Sequence<Time>::Notes::iterator i = _notes.lower_bound(search_note); + assert(i == _notes.end() || (*i)->time() >= t); + return i; +} + +/** Return the earliest patch change with time >= t */ +template<typename Time> +typename Sequence<Time>::PatchChanges::iterator +Sequence<Time>::patch_change_lower_bound (Time t) +{ + PatchChangePtr search (new PatchChange<Time> (t, 0, 0, 0)); + typename Sequence<Time>::PatchChanges::iterator i = _patch_changes.lower_bound (search); + assert (i == _patch_changes.end() || musical_time_greater_or_equal_to ((*i)->time(), t)); + return i; +} + +/** Return the earliest sysex with time >= t */ +template<typename Time> +typename Sequence<Time>::SysExes::iterator +Sequence<Time>::sysex_lower_bound (Time t) +{ + SysExPtr search (new Event<Time> (0, t)); + typename Sequence<Time>::SysExes::iterator i = _sysexes.lower_bound (search); + assert (i == _sysexes.end() || (*i)->time() >= t); + return i; +} + template<typename Time> void Sequence<Time>::get_notes (Notes& n, NoteOperator op, uint8_t val, int chan_mask) const @@ -1393,4 +1430,3 @@ Sequence<Time>::dump (ostream& str) const template class Sequence<Evoral::MusicalTime>; } // namespace Evoral - diff --git a/libs/evoral/src/libsmf/smf.c b/libs/evoral/src/libsmf/smf.c index c062f99659..3fde1d831e 100644 --- a/libs/evoral/src/libsmf/smf.c +++ b/libs/evoral/src/libsmf/smf.c @@ -39,7 +39,11 @@ #include <assert.h> #include <math.h> #include <errno.h> +#ifdef PLATFORM_WINDOWS +#include <winsock2.h> +#else #include <arpa/inet.h> +#endif #include "smf.h" #include "smf_private.h" @@ -52,7 +56,7 @@ smf_new(void) { int cantfail; - smf_t *smf = malloc(sizeof(smf_t)); + smf_t *smf = (smf_t*)malloc(sizeof(smf_t)); if (smf == NULL) { g_critical("Cannot allocate smf_t structure: %s", strerror(errno)); return (NULL); @@ -85,7 +89,7 @@ smf_delete(smf_t *smf) { /* Remove all the tracks, from last to first. */ while (smf->tracks_array->len > 0) - smf_track_delete(g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1)); + smf_track_delete((smf_track_t*)g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1)); smf_fini_tempo(smf); @@ -105,7 +109,7 @@ smf_delete(smf_t *smf) smf_track_t * smf_track_new(void) { - smf_track_t *track = malloc(sizeof(smf_track_t)); + smf_track_t *track = (smf_track_t*)malloc(sizeof(smf_track_t)); if (track == NULL) { g_critical("Cannot allocate smf_track_t structure: %s", strerror(errno)); return (NULL); @@ -131,7 +135,7 @@ smf_track_delete(smf_track_t *track) /* Remove all the events, from last to first. */ while (track->events_array->len > 0) - smf_event_delete(g_ptr_array_index(track->events_array, track->events_array->len - 1)); + smf_event_delete((smf_event_t*)g_ptr_array_index(track->events_array, track->events_array->len - 1)); if (track->smf) smf_track_remove_from_smf(track); @@ -220,7 +224,7 @@ smf_track_remove_from_smf(smf_track_t *track) smf_event_t * smf_event_new(void) { - smf_event_t *event = malloc(sizeof(smf_event_t)); + smf_event_t *event = (smf_event_t*)malloc(sizeof(smf_event_t)); if (event == NULL) { g_critical("Cannot allocate smf_event_t structure: %s", strerror(errno)); return (NULL); @@ -253,7 +257,7 @@ smf_event_new_from_pointer(const void *midi_data, size_t len) return (NULL); event->midi_buffer_length = len; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno)); smf_event_delete(event); @@ -343,7 +347,7 @@ smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte) } event->midi_buffer_length = len; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno)); smf_event_delete(event); @@ -780,7 +784,7 @@ smf_track_get_event_by_number(const smf_track_t *track, size_t event_number) if (event_number > track->number_of_events) return (NULL); - event = g_ptr_array_index(track->events_array, event_number - 1); + event = (smf_event_t*)g_ptr_array_index(track->events_array, event_number - 1); assert(event); diff --git a/libs/evoral/src/libsmf/smf_decode.c b/libs/evoral/src/libsmf/smf_decode.c index bfba08e9f9..8037fd80d2 100644 --- a/libs/evoral/src/libsmf/smf_decode.c +++ b/libs/evoral/src/libsmf/smf_decode.c @@ -37,7 +37,11 @@ #include <assert.h> #include <math.h> #include <errno.h> +#ifdef PLATFORM_WINDOWS +#include <winsock2.h> +#else #include <arpa/inet.h> +#endif #include <stdint.h> #include "smf.h" #include "smf_private.h" @@ -114,7 +118,7 @@ smf_event_decode_textual(const smf_event_t *event, const char *name) int off = 0; char *buf, *extracted; - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_textual: malloc failed."); return (NULL); @@ -177,7 +181,7 @@ smf_event_decode_metadata(const smf_event_t *event) break; } - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_metadata: malloc failed."); return (NULL); @@ -235,7 +239,7 @@ smf_event_decode_metadata(const smf_event_t *event) off += snprintf(buf + off, BUFFER_SIZE - off, "Time Signature: %d/%d, %d clocks per click, %d notated 32nd notes per quarter note", - event->midi_buffer[3], (int)pow(2, event->midi_buffer[4]), event->midi_buffer[5], + event->midi_buffer[3], (int)pow((double)2, event->midi_buffer[4]), event->midi_buffer[5], event->midi_buffer[6]); break; @@ -302,7 +306,7 @@ smf_event_decode_system_realtime(const smf_event_t *event) return (NULL); } - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_system_realtime: malloc failed."); return (NULL); @@ -354,7 +358,7 @@ smf_event_decode_sysex(const smf_event_t *event) return (NULL); } - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_sysex: malloc failed."); return (NULL); @@ -455,7 +459,7 @@ smf_event_decode_system_common(const smf_event_t *event) if (smf_event_is_sysex(event)) return (smf_event_decode_sysex(event)); - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_system_realtime: malloc failed."); return (NULL); @@ -526,7 +530,7 @@ smf_event_decode(const smf_event_t *event) return (NULL); } - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode: malloc failed."); return (NULL); @@ -596,7 +600,7 @@ smf_decode(const smf_t *smf) int off = 0; char *buf; - buf = malloc(BUFFER_SIZE); + buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode: malloc failed."); return (NULL); diff --git a/libs/evoral/src/libsmf/smf_load.c b/libs/evoral/src/libsmf/smf_load.c index 98d5ea8cff..d8168d0e6a 100644 --- a/libs/evoral/src/libsmf/smf_load.c +++ b/libs/evoral/src/libsmf/smf_load.c @@ -40,7 +40,11 @@ #include <math.h> #include <errno.h> #include <ctype.h> +#ifdef PLATFORM_WINDOWS +#include <winsock2.h> +#else #include <arpa/inet.h> +#endif #include "smf.h" #include "smf_private.h" @@ -119,7 +123,7 @@ parse_mthd_header(smf_t *smf) return (-1); } - tmp_mthd = smf->file_buffer; + tmp_mthd = (struct chunk_header_struct*)smf->file_buffer; if (!chunk_signature_matches(tmp_mthd, "MThd")) { g_critical("SMF error: MThd signature not found, is that a MIDI file?"); @@ -409,7 +413,7 @@ extract_sysex_event(const unsigned char *buf, const size_t buffer_length, smf_ev } event->midi_buffer_length = message_length; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate memory in extract_sysex_event(): %s", strerror(errno)); return (-4); @@ -452,7 +456,7 @@ extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_ } event->midi_buffer_length = message_length; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate memory in extract_escaped_event(): %s", strerror(errno)); return (-4); @@ -522,7 +526,7 @@ extract_midi_event(const unsigned char *buf, const size_t buffer_length, smf_eve } event->midi_buffer_length = message_length; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate memory in extract_midi_event(): %s", strerror(errno)); return (-4); @@ -611,7 +615,7 @@ make_string(const unsigned char *buf, const size_t buffer_length, uint32_t len) len = buffer_length; } - str = malloc(len + 1); + str = (char*)malloc(len + 1); if (str == NULL) { g_critical("Cannot allocate memory in make_string()."); return (NULL); @@ -662,14 +666,14 @@ smf_event_extract_text(const smf_event_t *event) return (NULL); } - smf_extract_vlq((void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length); + smf_extract_vlq((const unsigned char*)(void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length); if (string_length <= 0) { g_critical("smf_event_extract_text: truncated MIDI message."); return (NULL); } - return (make_string((void *)(&event->midi_buffer[2] + length_length), event->midi_buffer_length - 2 - length_length, string_length)); + return (make_string((const unsigned char*)(void *)(&event->midi_buffer[2] + length_length), event->midi_buffer_length - 2 - length_length, string_length)); } /** diff --git a/libs/evoral/src/libsmf/smf_save.c b/libs/evoral/src/libsmf/smf_save.c index 1941ed4f7b..120c3a95eb 100644 --- a/libs/evoral/src/libsmf/smf_save.c +++ b/libs/evoral/src/libsmf/smf_save.c @@ -39,7 +39,11 @@ #include <assert.h> #include <math.h> #include <errno.h> +#ifdef PLATFORM_WINDOWS +#include <winsock2.h> +#else #include <arpa/inet.h> +#endif #include "smf.h" #include "smf_private.h" @@ -54,7 +58,7 @@ static void * smf_extend(smf_t *smf, const int length) { int i, previous_file_buffer_length = smf->file_buffer_length; - char *previous_file_buffer = smf->file_buffer; + char *previous_file_buffer = (char*)smf->file_buffer; /* XXX: Not terribly efficient. */ smf->file_buffer_length += length; @@ -201,7 +205,7 @@ smf_event_new_textual(int type, const char *text) /* "2 +" is for leading 0xFF 0xtype. */ event->midi_buffer_length = 2 + text_length + MAX_VLQ_LENGTH; - event->midi_buffer = malloc(event->midi_buffer_length); + event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length); if (event->midi_buffer == NULL) { g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno)); smf_event_delete(event); @@ -545,7 +549,7 @@ assert_smf_event_is_identical(const smf_event_t *a, const smf_event_t *b) { assert(a->event_number == b->event_number); assert(a->delta_time_pulses == b->delta_time_pulses); - assert(abs(a->time_pulses - b->time_pulses) <= 2); + assert(abs((long)(a->time_pulses - b->time_pulses)) <= 2); assert(fabs(a->time_seconds - b->time_seconds) <= 0.01); assert(a->track_number == b->track_number); assert(a->midi_buffer_length == b->midi_buffer_length); diff --git a/libs/evoral/src/libsmf/smf_tempo.c b/libs/evoral/src/libsmf/smf_tempo.c index 1d89639218..f3e3f7fc1b 100644 --- a/libs/evoral/src/libsmf/smf_tempo.c +++ b/libs/evoral/src/libsmf/smf_tempo.c @@ -59,7 +59,7 @@ new_tempo(smf_t *smf, size_t pulses) return (previous_tempo); } - tempo = malloc(sizeof(smf_tempo_t)); + tempo = (smf_tempo_t*)malloc(sizeof(smf_tempo_t)); if (tempo == NULL) { g_critical("Cannot allocate smf_tempo_t."); return (NULL); @@ -152,7 +152,7 @@ maybe_add_to_tempo_map(smf_event_t *event) } numerator = event->midi_buffer[3]; - denominator = (int)pow(2, event->midi_buffer[4]); + denominator = (int)pow((double)2, event->midi_buffer[4]); clocks_per_click = event->midi_buffer[5]; notes_per_note = event->midi_buffer[6]; @@ -259,7 +259,7 @@ smf_get_tempo_by_number(const smf_t *smf, size_t number) if (number >= smf->tempo_array->len) return (NULL); - return (g_ptr_array_index(smf->tempo_array, number)); + return ((smf_tempo_t*)g_ptr_array_index(smf->tempo_array, number)); } /** @@ -341,7 +341,7 @@ smf_fini_tempo(smf_t *smf) smf_tempo_t *tempo; while (smf->tempo_array->len > 0) { - tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1); + tempo = (smf_tempo_t*)g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1); assert(tempo); memset(tempo, 0, sizeof(smf_tempo_t)); diff --git a/libs/evoral/test/SMFTest.cpp b/libs/evoral/test/SMFTest.cpp index d4b2a28aff..fe9efa479f 100644 --- a/libs/evoral/test/SMFTest.cpp +++ b/libs/evoral/test/SMFTest.cpp @@ -1,5 +1,9 @@ #include "SMFTest.hpp" +#ifdef WIN32 +#include <io.h> // for R_OK +#endif + using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION( SMFTest ); diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc index 84a738f278..200308a254 100644 --- a/libs/gtkmm2ext/actions.cc +++ b/libs/gtkmm2ext/actions.cc @@ -27,6 +27,7 @@ #include <gtk/gtkuimanager.h> #include <gtk/gtkactiongroup.h> +#include <gtkmm.h> #include <gtkmm/accelmap.h> #include <gtkmm/uimanager.h> @@ -265,15 +266,15 @@ ActionManager::get_action (const char* path) path++; } - char copy[len+1]; - strcpy (copy, path); - char* slash = strchr (copy, '/'); + vector<char> copy(len+1); + strcpy (©[0], path); + char* slash = strchr (©[0], '/'); if (!slash) { return RefPtr<Action> (); } *slash = '\0'; - return get_action (copy, ++slash); + return get_action (©[0], ++slash); } diff --git a/libs/gtkmm2ext/binding_proxy.cc b/libs/gtkmm2ext/binding_proxy.cc index f12c64cf68..c56ab85982 100644 --- a/libs/gtkmm2ext/binding_proxy.cc +++ b/libs/gtkmm2ext/binding_proxy.cc @@ -107,7 +107,7 @@ BindingProxy::learning_finished () bool -BindingProxy::prompter_hiding (GdkEventAny */*ev*/) +BindingProxy::prompter_hiding (GdkEventAny* /*ev*/) { learning_connection.disconnect (); if (controllable) { diff --git a/libs/gtkmm2ext/bindings.cc b/libs/gtkmm2ext/bindings.cc index e049cd8d57..f96bd586d9 100644 --- a/libs/gtkmm2ext/bindings.cc +++ b/libs/gtkmm2ext/bindings.cc @@ -19,6 +19,8 @@ #include <iostream> +#include <glib/gstdio.h> + #include "pbd/xml++.h" #include "pbd/convert.h" @@ -389,7 +391,7 @@ Bindings::save (const string& path) save (*root); if (!tree.write (path)) { - ::unlink (path.c_str()); + ::g_unlink (path.c_str()); return false; } diff --git a/libs/gtkmm2ext/cairocell.cc b/libs/gtkmm2ext/cairocell.cc index f20f537e1b..c449cae592 100644 --- a/libs/gtkmm2ext/cairocell.cc +++ b/libs/gtkmm2ext/cairocell.cc @@ -25,6 +25,7 @@ #include "gtkmm2ext/utils.h" using std::string; +using std::vector; using std::map; using std::max; using std::cerr; @@ -132,7 +133,7 @@ void CairoTextCell::set_size (Cairo::RefPtr<Cairo::Context>& context) { const uint32_t lim = (uint32_t) ceil (_width_chars); - char buf[lim+1]; + vector<char> buf(lim+1); uint32_t n; double max_width = 0.0; double max_height = 0.0; @@ -149,7 +150,7 @@ CairoTextCell::set_size (Cairo::RefPtr<Cairo::Context>& context) buf[n] = '0' + digit; } - context->get_text_extents (buf, ext); + context->get_text_extents (&buf[0], ext); max_width = max (ext.width + ext.x_bearing, max_width); max_height = max (ext.height, max_height); diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc index d826def7ff..5a77557222 100644 --- a/libs/gtkmm2ext/fastmeter.cc +++ b/libs/gtkmm2ext/fastmeter.cc @@ -25,14 +25,16 @@ #include <stdlib.h> +#include <glibmm.h> +#include <gdkmm.h> #include <gdkmm/rectangle.h> #include <gtkmm2ext/fastmeter.h> #include <gtkmm2ext/utils.h> #define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; } #define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; } + using namespace Gtk; -using namespace Gdk; using namespace Glib; using namespace Gtkmm2ext; using namespace std; @@ -97,7 +99,7 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len, _stp[2] = stp2; _stp[3] = stp3; - set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); + set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); pixrect.x = 1; pixrect.y = 1; diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index fc94657f6d..33841cd0be 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -95,7 +95,7 @@ UI::UI (string namestr, int *argc, char ***argv) /* attach our request source to the default main context */ - request_channel.ios()->attach (MainContext::get_default()); + attach_request_source (); errors = new TextViewer (800,600); errors->text().set_editable (false); @@ -692,7 +692,7 @@ UI::flush_pending () } bool -UI::just_hide_it (GdkEventAny */*ev*/, Window *win) +UI::just_hide_it (GdkEventAny* /*ev*/, Window *win) { win->hide (); return true; @@ -742,7 +742,7 @@ UI::color_selection_done (bool status) } bool -UI::color_selection_deleted (GdkEventAny */*ev*/) +UI::color_selection_deleted (GdkEventAny* /*ev*/) { Main::quit (); return true; diff --git a/libs/gtkmm2ext/gtkapplication_win32.c b/libs/gtkmm2ext/gtkapplication_win32.c new file mode 100644 index 0000000000..78d538b334 --- /dev/null +++ b/libs/gtkmm2ext/gtkapplication_win32.c @@ -0,0 +1,49 @@ +/* GTK+ Integration with platform-specific application-wide features + * such as the OS X menubar and application delegate concepts (for X11) + * + * Copyright (C) 2007 Pioneer Research Center USA, Inc. + * Copyright (C) 2007 Imendio AB + * Copyright (C) 2009 Paul Davis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gtkmm2ext/gtkapplication.h> + +int +gtk_application_init (void) +{ + return 0; +} + +void gtk_application_cleanup (void) +{ +} + +void +gtk_application_set_menu_bar (GtkMenuShell* menushell) +{ +} + +void +gtk_application_add_app_menu_item (GtkApplicationMenuGroup* group, GtkMenuItem* item) +{ +} + +void +gtk_application_ready (void) +{ +} diff --git a/libs/gtkmm2ext/gtkmm2ext/auto_spin.h b/libs/gtkmm2ext/gtkmm2ext/auto_spin.h index 28fae316f6..8a6c9ab3b0 100644 --- a/libs/gtkmm2ext/gtkmm2ext/auto_spin.h +++ b/libs/gtkmm2ext/gtkmm2ext/auto_spin.h @@ -20,6 +20,10 @@ #ifndef __gtkmm2ext_auto_spin_h__ #define __gtkmm2ext_auto_spin_h__ +#ifdef interface +#undef interface +#endif + #include <gtkmm.h> #include "gtkmm2ext/visibility.h" diff --git a/libs/gtkmm2ext/gtkmm2ext/click_box.h b/libs/gtkmm2ext/gtkmm2ext/click_box.h index 8270f25778..c2afa2dd12 100644 --- a/libs/gtkmm2ext/gtkmm2ext/click_box.h +++ b/libs/gtkmm2ext/gtkmm2ext/click_box.h @@ -20,6 +20,10 @@ #ifndef __gtkmm2ext_click_box_h__ #define __gtkmm2ext_click_box_h__ +#ifdef interface +#undef interface +#endif + #include <string> #include <gtkmm.h> diff --git a/libs/gtkmm2ext/gtkmm2ext/doi.h b/libs/gtkmm2ext/gtkmm2ext/doi.h index e24224701f..53c24847f3 100644 --- a/libs/gtkmm2ext/gtkmm2ext/doi.h +++ b/libs/gtkmm2ext/gtkmm2ext/doi.h @@ -20,6 +20,10 @@ #ifndef __ardour_gtk_doi_h__ #define __ardour_gtk_doi_h__ +#ifdef interface +#undef interface +#endif + #include <gtkmm.h> #include "gtkmm2ext/visibility.h" diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h index b726eb89ac..065cc4bc00 100644 --- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h +++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h @@ -27,6 +27,10 @@ #include <setjmp.h> #include <pthread.h> +#ifdef interface +#undef interface +#endif + #include <glibmm/thread.h> #include <gtkmm/widget.h> diff --git a/libs/gtkmm2ext/gtkmm2ext/popup.h b/libs/gtkmm2ext/gtkmm2ext/popup.h index 261e07b21c..75a62ae92c 100644 --- a/libs/gtkmm2ext/gtkmm2ext/popup.h +++ b/libs/gtkmm2ext/gtkmm2ext/popup.h @@ -20,6 +20,10 @@ #ifndef __qui_popup_h__ #define __qui_popup_h__ +#ifdef interface +#undef interface +#endif + #include <string> #include <gtkmm.h> diff --git a/libs/gtkmm2ext/gtkmm2ext/selector.h b/libs/gtkmm2ext/gtkmm2ext/selector.h index f9fb428529..e1a0c1a530 100644 --- a/libs/gtkmm2ext/gtkmm2ext/selector.h +++ b/libs/gtkmm2ext/gtkmm2ext/selector.h @@ -19,6 +19,10 @@ #ifndef __gtkselector_h__ #define __gtkselector_h__ +#ifdef interface +#undef interface +#endif + #include <string> #include <vector> diff --git a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h index 8a8cb04a71..b04c2cb005 100644 --- a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h +++ b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h @@ -19,6 +19,10 @@ #ifndef __gtkmm2ext_slider_controller_h__ #define __gtkmm2ext_slider_controller_h__ +#ifdef interface +#undef interface +#endif + #include <gtkmm.h> #include <gtkmm2ext/popup.h> #include <gtkmm2ext/pixfader.h> diff --git a/libs/gtkmm2ext/idle_adjustment.cc b/libs/gtkmm2ext/idle_adjustment.cc index 3e3a3da566..edf5517fff 100644 --- a/libs/gtkmm2ext/idle_adjustment.cc +++ b/libs/gtkmm2ext/idle_adjustment.cc @@ -20,8 +20,11 @@ #define _BSD_SOURCE #include <gtkmm2ext/idle_adjustment.h> #include <gtkmm/main.h> +#include <glibmm/main.h> #include <iostream> +#include "pbd/timersub.h" + using namespace Gtk; using namespace sigc; using namespace Gtkmm2ext; diff --git a/libs/gtkmm2ext/motionfeedback.cc b/libs/gtkmm2ext/motionfeedback.cc index ead2b26885..bef934eca5 100644 --- a/libs/gtkmm2ext/motionfeedback.cc +++ b/libs/gtkmm2ext/motionfeedback.cc @@ -25,6 +25,8 @@ #include <unistd.h> #include <stdio.h> /* for snprintf, grrr */ +#include <glib/gstdio.h> + #include <gdk/gdkkeysyms.h> #include <gtkmm.h> @@ -468,14 +470,18 @@ Glib::RefPtr<Gdk::Pixbuf> MotionFeedback::render_pixbuf (int size) { Glib::RefPtr<Gdk::Pixbuf> pixbuf; - char path[32]; + char *path; int fd; + GError *error = NULL; - snprintf (path, sizeof (path), "/tmp/mfimg%dXXXXXX", size); - - if ((fd = mkstemp (path)) < 0) { + fd = g_file_open_tmp ("mfimgXXXXXX", &path, &error); + close (fd); + + if(error) { + g_critical("failed to open a temporary file for writing: %s.", error->message); + g_error_free (error); return pixbuf; - } + } GdkColor col2 = {0,0,0,0}; GdkColor col3 = {0,0,0,0}; @@ -512,15 +518,17 @@ MotionFeedback::render_pixbuf (int size) pixbuf = Gdk::Pixbuf::create_from_file (path); } catch (const Gdk::PixbufError &e) { std::cerr << "Caught PixbufError: " << e.what() << std::endl; - unlink (path); + ::g_unlink (path); throw; } catch (...) { - unlink (path); + ::g_unlink (path); g_message("Caught ... "); throw; } - unlink (path); + ::g_unlink (path); + + g_free(path); return pixbuf; } diff --git a/libs/gtkmm2ext/popup.cc b/libs/gtkmm2ext/popup.cc index 6f4a8a5427..85a9d537c3 100644 --- a/libs/gtkmm2ext/popup.cc +++ b/libs/gtkmm2ext/popup.cc @@ -111,7 +111,7 @@ PopUp::touch () } gint -PopUp::button_click (GdkEventButton */*ev*/) +PopUp::button_click (GdkEventButton* /*ev*/) { remove (); return TRUE; diff --git a/libs/gtkmm2ext/prolooks_helpers.c b/libs/gtkmm2ext/prolooks_helpers.c index cdac2dbafe..9709db7c5a 100644 --- a/libs/gtkmm2ext/prolooks_helpers.c +++ b/libs/gtkmm2ext/prolooks_helpers.c @@ -6,6 +6,11 @@ License: LGPLv2+ */ +#ifdef COMPILER_MSVC +#include <algorithm> +using std::min; using std::max; +#endif + #include "gtkmm2ext/prolooks-helpers.h" static gpointer cairo_color_parent_class = NULL; @@ -188,7 +193,7 @@ static gchar* cairo_value_color_collect_value (GValue* value, guint n_collect_va (void) collect_flags; if (collect_values[0].v_pointer) { CairoColor* object; - object = collect_values[0].v_pointer; + object = (CairoColor*)collect_values[0].v_pointer; if (object->parent_instance.g_class == NULL) { return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { @@ -205,16 +210,16 @@ static gchar* cairo_value_color_collect_value (GValue* value, guint n_collect_va static gchar* cairo_value_color_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { CairoColor** object_p; (void) n_collect_values; - object_p = collect_values[0].v_pointer; + object_p = (CairoColor**)collect_values[0].v_pointer; if (!object_p) { return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value)); } if (!value->data[0].v_pointer) { *object_p = NULL; } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { - *object_p = value->data[0].v_pointer; + *object_p = (CairoColor*)value->data[0].v_pointer; } else { - *object_p = cairo_color_ref (value->data[0].v_pointer); + *object_p = (CairoColor*)cairo_color_ref (value->data[0].v_pointer); } return NULL; } @@ -223,7 +228,7 @@ static gchar* cairo_value_color_lcopy_value (const GValue* value, guint n_collec GParamSpec* cairo_param_spec_color (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { CairoParamSpecColor* spec; g_return_val_if_fail (g_type_is_a (object_type, CAIRO_TYPE_COLOR), NULL); - spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); + spec = (CairoParamSpecColor*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); G_PARAM_SPEC (spec)->value_type = object_type; return G_PARAM_SPEC (spec); } @@ -238,7 +243,7 @@ gpointer cairo_value_get_color (const GValue* value) { void cairo_value_set_color (GValue* value, gpointer v_object) { CairoColor* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CAIRO_TYPE_COLOR)); - old = value->data[0].v_pointer; + old = (CairoColor*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CAIRO_TYPE_COLOR)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -256,7 +261,7 @@ void cairo_value_set_color (GValue* value, gpointer v_object) { void cairo_value_take_color (GValue* value, gpointer v_object) { CairoColor* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CAIRO_TYPE_COLOR)); - old = value->data[0].v_pointer; + old = (CairoColor*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CAIRO_TYPE_COLOR)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -293,9 +298,9 @@ GType cairo_color_get_type (void) { if (g_once_init_enter (&cairo_color_type_id__volatile)) { static const GTypeValueTable g_define_type_value_table = { cairo_value_color_init, cairo_value_color_free_value, cairo_value_color_copy_value, cairo_value_color_peek_pointer, "p", cairo_value_color_collect_value, "p", cairo_value_color_lcopy_value }; static const GTypeInfo g_define_type_info = { sizeof (CairoColorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cairo_color_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CairoColor), 0, (GInstanceInitFunc) cairo_color_instance_init, &g_define_type_value_table }; - static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; + static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; GType cairo_color_type_id; - cairo_color_type_id = g_type_register_fundamental (g_type_fundamental_next (), "CairoColor", &g_define_type_info, &g_define_type_fundamental_info, 0); + cairo_color_type_id = g_type_register_fundamental (g_type_fundamental_next (), "CairoColor", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0); g_once_init_leave (&cairo_color_type_id__volatile, cairo_color_type_id); } return cairo_color_type_id__volatile; @@ -304,7 +309,7 @@ GType cairo_color_get_type (void) { gpointer cairo_color_ref (gpointer instance) { CairoColor* self; - self = instance; + self = (CairoColor*)instance; g_atomic_int_inc (&self->ref_count); return instance; } @@ -312,7 +317,7 @@ gpointer cairo_color_ref (gpointer instance) { void cairo_color_unref (gpointer instance) { CairoColor* self; - self = instance; + self = (CairoColor*)instance; if (g_atomic_int_dec_and_test (&self->ref_count)) { CAIRO_COLOR_GET_CLASS (self)->finalize (self); g_type_free_instance ((GTypeInstance *) self); @@ -774,7 +779,7 @@ static gchar* prolooks_value_hsl_collect_value (GValue* value, guint n_collect_v (void) collect_flags; if (collect_values[0].v_pointer) { ProlooksHSL* object; - object = collect_values[0].v_pointer; + object = (ProlooksHSL*)collect_values[0].v_pointer; if (object->parent_instance.g_class == NULL) { return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { @@ -791,16 +796,16 @@ static gchar* prolooks_value_hsl_collect_value (GValue* value, guint n_collect_v static gchar* prolooks_value_hsl_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ProlooksHSL** object_p; (void) n_collect_values; - object_p = collect_values[0].v_pointer; + object_p = (ProlooksHSL**)collect_values[0].v_pointer; if (!object_p) { return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value)); } if (!value->data[0].v_pointer) { *object_p = NULL; } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { - *object_p = value->data[0].v_pointer; + *object_p = (ProlooksHSL*)value->data[0].v_pointer; } else { - *object_p = prolooks_hsl_ref (value->data[0].v_pointer); + *object_p = (ProlooksHSL*)prolooks_hsl_ref (value->data[0].v_pointer); } return NULL; } @@ -809,7 +814,7 @@ static gchar* prolooks_value_hsl_lcopy_value (const GValue* value, guint n_colle GParamSpec* prolooks_param_spec_hsl (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { ProlooksParamSpecHSL* spec; g_return_val_if_fail (g_type_is_a (object_type, PROLOOKS_TYPE_HSL), NULL); - spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); + spec = (ProlooksParamSpecHSL*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); G_PARAM_SPEC (spec)->value_type = object_type; return G_PARAM_SPEC (spec); } @@ -824,7 +829,7 @@ gpointer prolooks_value_get_hsl (const GValue* value) { void prolooks_value_set_hsl (GValue* value, gpointer v_object) { ProlooksHSL* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSL)); - old = value->data[0].v_pointer; + old = (ProlooksHSL*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSL)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -842,7 +847,7 @@ void prolooks_value_set_hsl (GValue* value, gpointer v_object) { void prolooks_value_take_hsl (GValue* value, gpointer v_object) { ProlooksHSL* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSL)); - old = value->data[0].v_pointer; + old = (ProlooksHSL*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSL)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -879,9 +884,9 @@ GType prolooks_hsl_get_type (void) { if (g_once_init_enter (&prolooks_hsl_type_id__volatile)) { static const GTypeValueTable g_define_type_value_table = { prolooks_value_hsl_init, prolooks_value_hsl_free_value, prolooks_value_hsl_copy_value, prolooks_value_hsl_peek_pointer, "p", prolooks_value_hsl_collect_value, "p", prolooks_value_hsl_lcopy_value }; static const GTypeInfo g_define_type_info = { sizeof (ProlooksHSLClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) prolooks_hsl_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ProlooksHSL), 0, (GInstanceInitFunc) prolooks_hsl_instance_init, &g_define_type_value_table }; - static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; + static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; GType prolooks_hsl_type_id; - prolooks_hsl_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSL", &g_define_type_info, &g_define_type_fundamental_info, 0); + prolooks_hsl_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSL", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0); g_once_init_leave (&prolooks_hsl_type_id__volatile, prolooks_hsl_type_id); } return prolooks_hsl_type_id__volatile; @@ -890,15 +895,15 @@ GType prolooks_hsl_get_type (void) { gpointer prolooks_hsl_ref (gpointer instance) { ProlooksHSL* self; - self = instance; - g_atomic_int_inc (&self->ref_count); + self = (ProlooksHSL*)instance; + g_atomic_int_inc (&self->ref_count); return instance; } void prolooks_hsl_unref (gpointer instance) { ProlooksHSL* self; - self = instance; + self = (ProlooksHSL*)instance; if (g_atomic_int_dec_and_test (&self->ref_count)) { PROLOOKS_HSL_GET_CLASS (self)->finalize (self); g_type_free_instance ((GTypeInstance *) self); @@ -1183,7 +1188,7 @@ static gchar* prolooks_value_hsv_collect_value (GValue* value, guint n_collect_v (void) n_collect_values; if (collect_values[0].v_pointer) { ProlooksHSV* object; - object = collect_values[0].v_pointer; + object = (ProlooksHSV*)collect_values[0].v_pointer; if (object->parent_instance.g_class == NULL) { return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { @@ -1200,16 +1205,16 @@ static gchar* prolooks_value_hsv_collect_value (GValue* value, guint n_collect_v static gchar* prolooks_value_hsv_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ProlooksHSV** object_p; (void) n_collect_values; - object_p = collect_values[0].v_pointer; + object_p = (ProlooksHSV**)collect_values[0].v_pointer; if (!object_p) { return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value)); } if (!value->data[0].v_pointer) { *object_p = NULL; } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { - *object_p = value->data[0].v_pointer; + *object_p = (ProlooksHSV*)value->data[0].v_pointer; } else { - *object_p = prolooks_hsv_ref (value->data[0].v_pointer); + *object_p = (ProlooksHSV*)prolooks_hsv_ref (value->data[0].v_pointer); } return NULL; } @@ -1218,7 +1223,7 @@ static gchar* prolooks_value_hsv_lcopy_value (const GValue* value, guint n_colle GParamSpec* prolooks_param_spec_hsv (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { ProlooksParamSpecHSV* spec; g_return_val_if_fail (g_type_is_a (object_type, PROLOOKS_TYPE_HSV), NULL); - spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); + spec = (ProlooksParamSpecHSV*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); G_PARAM_SPEC (spec)->value_type = object_type; return G_PARAM_SPEC (spec); } @@ -1233,7 +1238,7 @@ gpointer prolooks_value_get_hsv (const GValue* value) { void prolooks_value_set_hsv (GValue* value, gpointer v_object) { ProlooksHSV* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSV)); - old = value->data[0].v_pointer; + old = (ProlooksHSV*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSV)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -1251,7 +1256,7 @@ void prolooks_value_set_hsv (GValue* value, gpointer v_object) { void prolooks_value_take_hsv (GValue* value, gpointer v_object) { ProlooksHSV* old; g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSV)); - old = value->data[0].v_pointer; + old = (ProlooksHSV*)value->data[0].v_pointer; if (v_object) { g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSV)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); @@ -1286,9 +1291,9 @@ GType prolooks_hsv_get_type (void) { if (g_once_init_enter (&prolooks_hsv_type_id__volatile)) { static const GTypeValueTable g_define_type_value_table = { prolooks_value_hsv_init, prolooks_value_hsv_free_value, prolooks_value_hsv_copy_value, prolooks_value_hsv_peek_pointer, "p", prolooks_value_hsv_collect_value, "p", prolooks_value_hsv_lcopy_value }; static const GTypeInfo g_define_type_info = { sizeof (ProlooksHSVClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) prolooks_hsv_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ProlooksHSV), 0, (GInstanceInitFunc) prolooks_hsv_instance_init, &g_define_type_value_table }; - static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; + static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; GType prolooks_hsv_type_id; - prolooks_hsv_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSV", &g_define_type_info, &g_define_type_fundamental_info, 0); + prolooks_hsv_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSV", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0); g_once_init_leave (&prolooks_hsv_type_id__volatile, prolooks_hsv_type_id); } return prolooks_hsv_type_id__volatile; @@ -1297,7 +1302,7 @@ GType prolooks_hsv_get_type (void) { gpointer prolooks_hsv_ref (gpointer instance) { ProlooksHSV* self; - self = instance; + self = (ProlooksHSV*)instance; g_atomic_int_inc (&self->ref_count); return instance; } @@ -1305,7 +1310,7 @@ gpointer prolooks_hsv_ref (gpointer instance) { void prolooks_hsv_unref (gpointer instance) { ProlooksHSV* self; - self = instance; + self = (ProlooksHSV*)instance; if (g_atomic_int_dec_and_test (&self->ref_count)) { PROLOOKS_HSV_GET_CLASS (self)->finalize (self); g_type_free_instance ((GTypeInstance *) self); diff --git a/libs/gtkmm2ext/selector.cc b/libs/gtkmm2ext/selector.cc index 85924e82ab..e4b95d1e03 100644 --- a/libs/gtkmm2ext/selector.cc +++ b/libs/gtkmm2ext/selector.cc @@ -22,6 +22,9 @@ #include <vector> #include <string> +#include <glibmm.h> +#include <gdkmm.h> + #include "pbd/pathscanner.h" #include "gtkmm2ext/keyboard.h" diff --git a/libs/midi++2/channel.cc b/libs/midi++2/channel.cc index 66ce5ed71c..ed8f4da5bc 100644 --- a/libs/midi++2/channel.cc +++ b/libs/midi++2/channel.cc @@ -25,7 +25,7 @@ using namespace MIDI; -Channel::Channel (byte channelnum, Port &p) +Channel::Channel (MIDI::byte channelnum, Port &p) : _port (p) { _channel_number = channelnum; @@ -182,13 +182,13 @@ Channel::process_controller (Parser & /*parser*/, EventTwoBytes *tb) } void -Channel::process_program_change (Parser & /*parser*/, byte val) +Channel::process_program_change (Parser & /*parser*/, MIDI::byte val) { _program_number = val; } void -Channel::process_chanpress (Parser & /*parser*/, byte val) +Channel::process_chanpress (Parser & /*parser*/, MIDI::byte val) { _chanpress = val; } @@ -215,7 +215,7 @@ Channel::process_reset (Parser & /*parser*/) * \return true if success */ bool -Channel::channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp) +Channel::channel_msg (MIDI::byte id, MIDI::byte val1, MIDI::byte val2, timestamp_t timestamp) { unsigned char msg[3]; int len = 0; diff --git a/libs/midi++2/ipmidi_port.cc b/libs/midi++2/ipmidi_port.cc index c4544c237b..567df99335 100644 --- a/libs/midi++2/ipmidi_port.cc +++ b/libs/midi++2/ipmidi_port.cc @@ -25,9 +25,17 @@ #include <errno.h> #include <stdlib.h> #include <string.h> +#ifdef COMPILER_MSVC +#undef O_NONBLOCK +#define O_NONBLOCK 0 +#endif +#if defined(PLATFORM_WINDOWS) +#include <winsock2.h> +#else #include <netdb.h> +#endif -#if defined(WIN32) +#if defined(PLATFORM_WINDOWS) static WSADATA g_wsaData; typedef int socklen_t; #else @@ -109,7 +117,7 @@ get_address (int sock, struct in_addr *inaddr, const string& ifname ) { // Get interface address from supplied name. -#if !defined(WIN32) +#if !defined(PLATFORM_WINDOWS) struct ifreq ifr; ::strncpy(ifr.ifr_name, ifname.c_str(), sizeof(ifr.ifr_name)); @@ -138,12 +146,13 @@ get_address (int sock, struct in_addr *inaddr, const string& ifname ) return false; -#endif // !WIN32 +#endif // !PLATFORM_WINDOWS' } bool IPMIDIPort::open_sockets (int base_port, const string& ifname) { +#if !defined(PLATFORM_WINDOWS) int protonum = 0; struct protoent *proto = ::getprotobyname("IP"); @@ -240,10 +249,13 @@ IPMIDIPort::open_sockets (int base_port, const string& ifname) } return true; +#else + return false; +#endif // !PLATFORM_WINDOWS' } int -IPMIDIPort::write (const byte* msg, size_t msglen, timestamp_t /* ignored */) { +IPMIDIPort::write (const MIDI::byte* msg, size_t msglen, timestamp_t /* ignored */) { if (sockout) { Glib::Threads::Mutex::Lock lm (write_lock); @@ -257,7 +269,7 @@ IPMIDIPort::write (const byte* msg, size_t msglen, timestamp_t /* ignored */) { } int -IPMIDIPort::read (byte* /*buf*/, size_t /*bufsize*/) +IPMIDIPort::read (MIDI::byte* /*buf*/, size_t /*bufsize*/) { /* nothing to do here - all handled by parse() */ return 0; diff --git a/libs/midi++2/midi++/ipmidi_port.h b/libs/midi++2/midi++/ipmidi_port.h index 4aa55828f1..a056612514 100644 --- a/libs/midi++2/midi++/ipmidi_port.h +++ b/libs/midi++2/midi++/ipmidi_port.h @@ -21,7 +21,7 @@ #include <string> #include <iostream> -#if defined(WIN32) +#if defined(PLATFORM_WINDOWS) #include <winsock.h> #elif defined(__FREE_BSD__) #include <netinet/in.h> diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index d151a43814..6e55134bb5 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -26,8 +26,12 @@ * now due to use of JackPortIsXXXX */ +#include <pthread.h> + #include "pbd/xml++.h" +#ifndef PLATFORM_WINDOWS #include "pbd/crossthread.h" +#endif #include "pbd/signals.h" #include "pbd/ringbuffer.h" diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc index bd8bbfc42d..9dd5bc33db 100644 --- a/libs/midi++2/midnam_patch.cc +++ b/libs/midi++2/midnam_patch.cc @@ -371,7 +371,7 @@ operator<< (std::ostream& os, const ChannelNameSet& cns) << "List size " << cns._patch_list.size() << endl << "Patch list name = [" << cns._patch_list_name << ']' << endl << "Available channels : "; - for (set<uint8_t>::iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) { + for (set<uint8_t>::const_iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) { os << (int) (*x) << ' '; } os << endl; diff --git a/libs/midi++2/mmc.cc b/libs/midi++2/mmc.cc index a3f8f01fe4..b92e686ce6 100644 --- a/libs/midi++2/mmc.cc +++ b/libs/midi++2/mmc.cc @@ -30,6 +30,10 @@ #include "midi++/port.h" #include "midi++/parser.h" +#ifndef __INT_MAX__ // 'ssize_t' won't be defined yet +typedef long ssize_t; +#endif + using namespace std; using namespace MIDI; using namespace PBD; @@ -226,19 +230,19 @@ MachineControl::set_ports (MIDI::Port* ip, MIDI::Port* op) } void -MachineControl::set_receive_device_id (byte id) +MachineControl::set_receive_device_id (MIDI::byte id) { _receive_device_id = id & 0x7f; } void -MachineControl::set_send_device_id (byte id) +MachineControl::set_send_device_id (MIDI::byte id) { _send_device_id = id & 0x7f; } bool -MachineControl::is_mmc (byte *sysex_buf, size_t len) +MachineControl::is_mmc (MIDI::byte *sysex_buf, size_t len) { if (len < 4 || len > 48) { return false; @@ -257,7 +261,7 @@ MachineControl::is_mmc (byte *sysex_buf, size_t len) } void -MachineControl::process_mmc_message (Parser &, byte *msg, size_t len) +MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) { size_t skiplen; byte *mmc_msg; @@ -464,7 +468,7 @@ MachineControl::process_mmc_message (Parser &, byte *msg, size_t len) } int -MachineControl::do_masked_write (byte *msg, size_t len) +MachineControl::do_masked_write (MIDI::byte *msg, size_t len) { /* return the number of bytes "consumed" */ @@ -490,7 +494,7 @@ MachineControl::do_masked_write (byte *msg, size_t len) } void -MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg) +MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte reg) { size_t n; ssize_t base_track; @@ -579,7 +583,7 @@ MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg) } int -MachineControl::do_locate (byte *msg, size_t /*msglen*/) +MachineControl::do_locate (MIDI::byte *msg, size_t /*msglen*/) { if (msg[2] == 0) { warning << "MIDI::MMC: locate [I/F] command not supported" @@ -594,7 +598,7 @@ MachineControl::do_locate (byte *msg, size_t /*msglen*/) } int -MachineControl::do_step (byte *msg, size_t /*msglen*/) +MachineControl::do_step (MIDI::byte *msg, size_t /*msglen*/) { int steps = msg[2] & 0x3f; @@ -607,7 +611,7 @@ MachineControl::do_step (byte *msg, size_t /*msglen*/) } int -MachineControl::do_shuttle (byte *msg, size_t /*msglen*/) +MachineControl::do_shuttle (MIDI::byte *msg, size_t /*msglen*/) { size_t forward; byte sh = msg[2]; diff --git a/libs/midi++2/mtc.cc b/libs/midi++2/mtc.cc index 0c2d8a41b3..1a477c3b8c 100644 --- a/libs/midi++2/mtc.cc +++ b/libs/midi++2/mtc.cc @@ -36,7 +36,7 @@ using namespace MIDI; #undef DEBUG_MTC bool -Parser::possible_mtc (byte *sysex_buf, size_t msglen) +Parser::possible_mtc (MIDI::byte *sysex_buf, size_t msglen) { byte fake_mtc_time[5]; @@ -91,7 +91,7 @@ Parser::reset_mtc_state () } void -Parser::process_mtc_quarter_frame (byte *msg) +Parser::process_mtc_quarter_frame (MIDI::byte *msg) { int which_quarter_frame = (msg[1] & 0xf0) >> 4; diff --git a/libs/midi++2/parser.cc b/libs/midi++2/parser.cc index 2f6b50899c..7d31c99781 100644 --- a/libs/midi++2/parser.cc +++ b/libs/midi++2/parser.cc @@ -136,7 +136,7 @@ Parser::~Parser () } void -Parser::trace_event (Parser &, byte *msg, size_t len) +Parser::trace_event (Parser &, MIDI::byte *msg, size_t len) { eventType type; ostream *o; @@ -658,7 +658,7 @@ Parser::system_msg (unsigned char inbyte) } void -Parser::signal (byte *msg, size_t len) +Parser::signal (MIDI::byte *msg, size_t len) { channel_t chan = msg[0]&0xF; int chan_i = chan; @@ -761,7 +761,7 @@ Parser::signal (byte *msg, size_t len) } bool -Parser::possible_mmc (byte *msg, size_t msglen) +Parser::possible_mmc (MIDI::byte *msg, size_t msglen) { if (!MachineControl::is_mmc (msg, msglen)) { return false; diff --git a/libs/panners/1in2out/panner_1in2out.cc b/libs/panners/1in2out/panner_1in2out.cc index 12e7896cfb..d92120c7aa 100644 --- a/libs/panners/1in2out/panner_1in2out.cc +++ b/libs/panners/1in2out/panner_1in2out.cc @@ -70,7 +70,7 @@ static PanPluginDescriptor _descriptor = { Panner1in2out::factory }; -extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } } +extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } Panner1in2out::Panner1in2out (boost::shared_ptr<Pannable> p) : Panner (p) diff --git a/libs/panners/1in2out/panner_1in2out.h b/libs/panners/1in2out/panner_1in2out.h index 97d23495c7..912072096b 100644 --- a/libs/panners/1in2out/panner_1in2out.h +++ b/libs/panners/1in2out/panner_1in2out.h @@ -33,6 +33,7 @@ #include "ardour/types.h" #include "ardour/panner.h" + namespace ARDOUR { class Panner1in2out : public Panner @@ -41,8 +42,8 @@ class Panner1in2out : public Panner Panner1in2out (boost::shared_ptr<Pannable>); ~Panner1in2out (); - void set_position (double); - bool clamp_position (double&); + void set_position (double); + bool clamp_position (double&); std::pair<double, double> position_range () const; double position() const; diff --git a/libs/panners/1in2out/wscript b/libs/panners/1in2out/wscript index 465b2da7a5..de6b21af25 100644 --- a/libs/panners/1in2out/wscript +++ b/libs/panners/1in2out/wscript @@ -22,7 +22,8 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = [ 'panner_1in2out.cc' ] obj.export_includes = ['.'] - obj.defines = [ 'PACKAGE="libardour_pan1in2out"' ] + obj.defines = [ 'PACKAGE="libardour_pan1in2out"' ] + obj.defines += [ 'ARDOURPANNER_DLL_EXPORTS' ] obj.includes = ['.'] obj.name = 'libardour_pan1in2out' obj.target = 'pan1in2out' diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index f801a36ff4..a10c4adc29 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -70,7 +70,7 @@ static PanPluginDescriptor _descriptor = { Panner2in2out::factory }; -extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } } +extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } Panner2in2out::Panner2in2out (boost::shared_ptr<Pannable> p) : Panner (p) diff --git a/libs/panners/2in2out/wscript b/libs/panners/2in2out/wscript index 4d144b1934..63f029f287 100644 --- a/libs/panners/2in2out/wscript +++ b/libs/panners/2in2out/wscript @@ -22,7 +22,8 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = [ 'panner_2in2out.cc' ] obj.export_includes = ['.'] - obj.defines = [ 'PACKAGE="libardour_pan2in2out"' ] + obj.defines = [ 'PACKAGE="libardour_pan2in2out"' ] + obj.defines += [ 'ARDOURPANNER_DLL_EXPORTS' ] obj.includes = ['.'] obj.name = 'libardour_pan2in2out' obj.target = 'pan2in2out' diff --git a/libs/panners/stereobalance/wscript b/libs/panners/stereobalance/wscript index 75eccca419..b66a2ffee6 100644 --- a/libs/panners/stereobalance/wscript +++ b/libs/panners/stereobalance/wscript @@ -22,7 +22,8 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = [ 'panner_balance.cc' ] obj.export_includes = ['.'] - obj.cxxflags = '-DPACKAGE="libardour_panbalance"' + obj.defines = ['PACKAGE="libardour_panbalance"'] + obj.defines += ['ARDOURPANNER_DLL_EXPORTS'] obj.includes = ['.'] obj.name = 'libardour_panbalance' obj.target = 'panbalance' diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index 2241ab96e3..f160ae3d24 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -25,6 +25,10 @@ #include <iostream> #include <string> +#ifdef COMPILER_MSVC +#include <malloc.h> +#endif + #include "pbd/cartesian.h" #include "pbd/compose.h" @@ -53,7 +57,7 @@ static PanPluginDescriptor _descriptor = { VBAPanner::factory }; -extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } } +extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } VBAPanner::Signal::Signal (Session&, VBAPanner&, uint32_t, uint32_t n_speakers) { @@ -65,7 +69,7 @@ VBAPanner::Signal::Signal (Session&, VBAPanner&, uint32_t, uint32_t n_speakers) } void -VBAPanner::Signal::Signal::resize_gains (uint32_t n) +VBAPanner::Signal::resize_gains (uint32_t n) { gains.assign (n, 0.0); } @@ -293,7 +297,7 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co assert (sz == obufs.count().n_audio()); - int8_t outputs[sz]; // on the stack, no malloc + int8_t *outputs = (int8_t*)alloca(sz); // on the stack, no malloc /* set initial state of each output "record" */ @@ -322,10 +326,10 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co /* at this point, we can test a speaker's status: - (outputs[o] & 1) <= in use before - (outputs[o] & 2) <= in use this time - (outputs[o] & 3) == 3 <= in use both times - outputs[o] == 0 <= not in use either time + (*outputs[o] & 1) <= in use before + (*outputs[o] & 2) <= in use this time + (*outputs[o] & 3) == 3 <= in use both times + *outputs[o] == 0 <= not in use either time */ diff --git a/libs/panners/vbap/vbap_speakers.cc b/libs/panners/vbap/vbap_speakers.cc index b84698bbd9..f2533222bd 100644 --- a/libs/panners/vbap/vbap_speakers.cc +++ b/libs/panners/vbap/vbap_speakers.cc @@ -31,6 +31,11 @@ of the software. */ +#ifdef COMPILER_MSVC +#pragma warning ( disable : 4244 ) +#endif + +#include <vector> #include <cmath> #include <algorithm> #include <stdlib.h> @@ -45,6 +50,13 @@ using namespace std; const double VBAPSpeakers::MIN_VOL_P_SIDE_LGTH = 0.01; +typedef std::vector<double> DoubleVector; +typedef std::vector<float> FloatVector; +typedef std::vector<bool> BoolVector; +typedef std::vector<int> IntVector; +typedef std::vector<IntVector> IntVector2D; +typedef std::vector<DoubleVector> DoubleVector2D; + VBAPSpeakers::VBAPSpeakers (boost::shared_ptr<Speakers> s) : _dimension (2) , _parent (s) @@ -104,17 +116,18 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) int i,j,k,l,table_size; int n_speakers = _speakers.size (); - int connections[n_speakers][n_speakers]; - float distance_table[((n_speakers * (n_speakers - 1)) / 2)]; - int distance_table_i[((n_speakers * (n_speakers - 1)) / 2)]; - int distance_table_j[((n_speakers * (n_speakers - 1)) / 2)]; - float distance; - struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr; - if (n_speakers == 0) { + if (n_speakers < 1) { return; } + FloatVector distance_table(((n_speakers * (n_speakers - 1)) / 2)); + IntVector distance_table_i(((n_speakers * (n_speakers - 1)) / 2)); + IntVector distance_table_j(((n_speakers * (n_speakers - 1)) / 2)); + IntVector2D connections(n_speakers, IntVector(n_speakers)); + float distance; + struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr; + for (i = 0; i < n_speakers; i++) { for (j = i+1; j < n_speakers; j++) { for(k=j+1;k<n_speakers;k++) { @@ -505,25 +518,25 @@ VBAPSpeakers::choose_speaker_pairs (){ matrices and stores the data to a global array */ const int n_speakers = _speakers.size(); - const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0/M_PI) * (M_PI - 0.175); - int sorted_speakers[n_speakers]; - bool exists[n_speakers]; - double inverse_matrix[n_speakers][4]; - int expected_pairs = 0; - int pair; - int speaker; - - if (n_speakers == 0) { + if (n_speakers < 1) { return; } + IntVector sorted_speakers(n_speakers); + BoolVector exists(n_speakers); + DoubleVector2D inverse_matrix(n_speakers, DoubleVector(4)); + const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0/M_PI) * (M_PI - 0.175); + int expected_pairs = 0; + int pair; + int speaker; + for (speaker = 0; speaker < n_speakers; ++speaker) { exists[speaker] = false; } /* sort loudspeakers according their aximuth angle */ - sort_2D_lss (sorted_speakers); + sort_2D_lss (&sorted_speakers[0]); /* adjacent loudspeakers are the loudspeaker pairs to be used.*/ for (speaker = 0; speaker < n_speakers-1; speaker++) { @@ -532,7 +545,7 @@ VBAPSpeakers::choose_speaker_pairs (){ _speakers[sorted_speakers[speaker]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { if (calc_2D_inv_tmatrix( _speakers[sorted_speakers[speaker]].angles().azi, _speakers[sorted_speakers[speaker+1]].angles().azi, - inverse_matrix[speaker]) != 0){ + &inverse_matrix[speaker][0]) != 0){ exists[speaker] = true; expected_pairs++; } @@ -543,7 +556,7 @@ VBAPSpeakers::choose_speaker_pairs (){ +_speakers[sorted_speakers[0]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { if (calc_2D_inv_tmatrix(_speakers[sorted_speakers[n_speakers-1]].angles().azi, _speakers[sorted_speakers[0]].angles().azi, - inverse_matrix[n_speakers-1]) != 0) { + &inverse_matrix[n_speakers-1][0]) != 0) { exists[n_speakers-1] = true; expected_pairs++; } diff --git a/libs/panners/vbap/wscript b/libs/panners/vbap/wscript index bc18def5e6..8fe9dc8e8a 100644 --- a/libs/panners/vbap/wscript +++ b/libs/panners/vbap/wscript @@ -22,7 +22,8 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = [ 'vbap_speakers.cc', 'vbap.cc' ] obj.export_includes = ['.'] - obj.defines = [ 'PACKAGE="libardour_panvbap"' ] + obj.defines = ['PACKAGE="libardour_panvbap"'] + obj.defines += ['ARDOURPANNER_DLL_EXPORTS'] obj.includes = ['.'] obj.name = 'libardour_panvbap' obj.target = 'panvbap' diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc index a7e148c839..3a4257ebdd 100644 --- a/libs/pbd/base_ui.cc +++ b/libs/pbd/base_ui.cc @@ -19,7 +19,11 @@ #include <cstring> #include <stdint.h> +#ifdef COMPILER_MSVC +#include <io.h> // Microsoft's nearest equivalent to <unistd.h> +#else #include <unistd.h> +#endif #include <fcntl.h> #include <cerrno> #include <cstring> @@ -33,6 +37,8 @@ #include "i18n.h" +#include "pbd/debug.h" + using namespace std; using namespace PBD; using namespace Glib; @@ -42,13 +48,18 @@ BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type(); BaseUI::RequestType BaseUI::Quit = BaseUI::new_request_type(); BaseUI::BaseUI (const string& str) - : request_channel (true) + : m_context(MainContext::get_default()) , run_loop_thread (0) , _name (str) +#ifndef PLATFORM_WINDOWS + , request_channel (true) +#endif { base_ui_instance = this; +#ifndef PLATFORM_WINDOWS request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler)); +#endif /* derived class must set _ok */ } @@ -73,7 +84,7 @@ BaseUI::new_request_type () void BaseUI::main_thread () { - DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", name(), pthread_self())); + DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", name(), pthread_name())); set_event_loop_for_thread (this); thread_init (); _main_loop->get_context()->signal_idle().connect (sigc::mem_fun (*this, &BaseUI::signal_running)); @@ -95,11 +106,9 @@ BaseUI::run () /* to be called by UI's that need/want their own distinct, self-created event loop thread. */ - _main_loop = MainLoop::create (MainContext::create()); - request_channel.ios()->attach (_main_loop->get_context()); - - /* glibmm hack - drop the refptr to the IOSource now before it can hurt */ - request_channel.drop_ios (); + m_context = MainContext::create(); + _main_loop = MainLoop::create (m_context); + attach_request_source (); Glib::Threads::Mutex::Lock lm (_run_lock); run_loop_thread = Glib::Threads::Thread::create (mem_fun (*this, &BaseUI::main_thread)); @@ -115,6 +124,24 @@ BaseUI::quit () } } +#ifdef PLATFORM_WINDOWS +gboolean +BaseUI::_request_handler (gpointer data) +{ + BaseUI* ui = static_cast<BaseUI*>(data); + return ui->request_handler (); +} + +bool +BaseUI::request_handler () +{ + DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::request_handler\n"); + handle_ui_requests (); + // keep calling indefinitely at the timeout interval + return true; +} + +#else bool BaseUI::request_handler (Glib::IOCondition ioc) { @@ -133,9 +160,39 @@ BaseUI::request_handler (Glib::IOCondition ioc) /* handle requests */ + DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::request_handler\n"); handle_ui_requests (); } return true; } - +#endif + +void +BaseUI::signal_new_request () +{ + DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::signal_new_request\n"); +#ifdef PLATFORM_WINDOWS + // handled in timeout, how to signal...? +#else + request_channel.wakeup (); +#endif +} + +/** + * This method relies on the caller having already set m_context + */ +void +BaseUI::attach_request_source () +{ + DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::attach_request_source\n"); +#ifdef PLATFORM_WINDOWS + GSource* request_source = g_timeout_source_new(200); + g_source_set_callback (request_source, &BaseUI::_request_handler, this, NULL); + g_source_attach (request_source, m_context->gobj()); +#else + request_channel.ios()->attach (m_context); + /* glibmm hack - drop the refptr to the IOSource now before it can hurt */ + request_channel.drop_ios (); +#endif +} diff --git a/libs/pbd/clear_dir.cc b/libs/pbd/clear_dir.cc index 29410d41e5..2f9c7b772d 100644 --- a/libs/pbd/clear_dir.cc +++ b/libs/pbd/clear_dir.cc @@ -17,13 +17,22 @@ */ -#include <string> +#ifdef COMPILER_MSVC +#include <io.h> // Microsoft's nearest equivalent to <unistd.h> +using PBD::readdir; +using PBD::opendir; +using PBD::closedir; +#else #include <dirent.h> #include <unistd.h> +#endif + +#include <string> #include <sys/stat.h> #include <errno.h> #include <string.h> +#include <glib/gstdio.h> #include <glibmm/miscutils.h> #include "pbd/error.h" @@ -66,7 +75,7 @@ PBD::clear_directory (const string& dir, size_t* size, vector<string>* paths) continue; } - if (::unlink (fullpath.c_str())) { + if (::g_unlink (fullpath.c_str())) { error << string_compose (_("cannot remove file %1 (%2)"), fullpath, strerror (errno)) << endmsg; ret = 1; diff --git a/libs/pbd/debug.cc b/libs/pbd/debug.cc index c86afbe87e..fba457c83e 100644 --- a/libs/pbd/debug.cc +++ b/libs/pbd/debug.cc @@ -24,6 +24,8 @@ #include <vector> #include <algorithm> +#include <boost/tokenizer.hpp> + #include "pbd/debug.h" #include "i18n.h" @@ -47,6 +49,7 @@ uint64_t PBD::DEBUG::FileManager = PBD::new_debug_bit ("filemanager"); uint64_t PBD::DEBUG::Pool = PBD::new_debug_bit ("pool"); uint64_t PBD::DEBUG::EventLoop = PBD::new_debug_bit ("eventloop"); uint64_t PBD::DEBUG::AbstractUI = PBD::new_debug_bit ("abstractui"); +uint64_t PBD::DEBUG::FileUtils = PBD::new_debug_bit ("fileutils"); uint64_t PBD::debug_bits = 0x0; @@ -75,36 +78,31 @@ PBD::set_debug_bits (uint64_t bits) int PBD::parse_debug_options (const char* str) { - char* p; - char* sp; + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep (","); + tokenizer tokens (string(str), sep); uint64_t bits = 0; - char* copy = strdup (str); - - p = strtok_r (copy, ",", &sp); - while (p) { - if (strcasecmp (p, "list") == 0) { + for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { + if (*tok_iter == "list") { list_debug_options (); - free (copy); return 1; } - if (strcasecmp (p, "all") == 0) { + if (*tok_iter == "all") { PBD::set_debug_bits (~0ULL); - free (copy); return 0; } for (map<const char*,uint64_t>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) { - if (strncasecmp (p, i->first, strlen (p)) == 0) { + const char* cstr = (*tok_iter).c_str(); + + if (strncasecmp (cstr, i->first, strlen (cstr)) == 0) { bits |= i->second; } } - - p = strtok_r (0, ",", &sp); } - free (copy); PBD::set_debug_bits (bits); return 0; } diff --git a/libs/pbd/debug_rt_alloc.c b/libs/pbd/debug_rt_alloc.c index 81e640b66d..7e578a2367 100644 --- a/libs/pbd/debug_rt_alloc.c +++ b/libs/pbd/debug_rt_alloc.c @@ -22,9 +22,10 @@ #define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> -#include <pthread.h> #include <stdlib.h> +#include "pbd/pthread_utils.h" + int (*pbd_alloc_allowed) () = 0; /** Thread-local key whose value is set to 1 if malloc checking is disabled diff --git a/libs/pbd/epa.cc b/libs/pbd/epa.cc index 8b8a23491b..c7a1d41b0e 100644 --- a/libs/pbd/epa.cc +++ b/libs/pbd/epa.cc @@ -17,12 +17,19 @@ */ +#include <glib.h> + #include <cstdlib> #include "pbd/epa.h" #include "pbd/strsplit.h" +#ifdef COMPILER_MSVC +#define environ _environ +_CRTIMP extern char ** _environ; +#else extern char** environ; +#endif using namespace PBD; using namespace std; @@ -61,7 +68,7 @@ EnvironmentalProtectionAgency::save () /* fetch environment from named environment variable, rather than "environ" */ - const char* estr = getenv (_envname.c_str()); + const char* estr = g_getenv (_envname.c_str()); if (!estr) { return; @@ -117,7 +124,7 @@ EnvironmentalProtectionAgency::restore () const clear (); for (map<string,string>::const_iterator i = e.begin(); i != e.end(); ++i) { - setenv (i->first.c_str(), i->second.c_str(), 1); + g_setenv (i->first.c_str(), i->second.c_str(), 1); } } @@ -137,6 +144,6 @@ EnvironmentalProtectionAgency::clear () const } string before = estring.substr (0, equal); - unsetenv(before.c_str()); + g_unsetenv(before.c_str()); } -} +} diff --git a/libs/pbd/fallback_folders.cc b/libs/pbd/fallback_folders.cc new file mode 100644 index 0000000000..f17e69e417 --- /dev/null +++ b/libs/pbd/fallback_folders.cc @@ -0,0 +1,591 @@ +/* + Copyright (C) 2008 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. + +*/ + +#include <pbd/fallback_folders.h> +#include <glib.h> +#include <glibmm.h> +#include <string.h> + + + +#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!! +#include <shlobj.h> +#include <winreg.h> + +//*************************************************************** +// +// get_win_special_folder() +// +// Gets the full path name that corresponds of one of the Windows +// special folders, such as "My Documents" and the like. The input +// parameter must be one of the corresponding CSIDL values, such +// as CSIDL_SYSTEM etc. +// +// Returns: +// +// On Success: A pointer to a newly allocated string containing +// the name of the special folder (must later be freed). +// On Failure: NULL +// +gchar * +get_win_special_folder (int csidl) +{ +wchar_t path[PATH_MAX+1]; +HRESULT hr; +LPITEMIDLIST pidl = 0; +gchar *retval = 0; + + if (S_OK == (hr = SHGetSpecialFolderLocation (0, csidl, &pidl))) + { + if (SHGetPathFromIDListW (pidl, path)) + retval = g_utf16_to_utf8 ((const gunichar2*)path, -1, 0, 0, 0); + CoTaskMemFree (pidl); + } + + return retval; +} +#endif // PLATFORM_WINDOWS + +namespace PBD { + +static gchar **fallback_folders = 0; + +//*************************************************************** +// +// get_platform_fallback_folders() +// +// Returns an array of folders to fall back to if the folders +// weren't named at build time and subsequently couldn't be found +// in the user's environment. This might not be needed any more +// because the function 'fixup_bundle_environment()' (in the +// gtk2_ardour branch) now explicitly sets up any environment +// paths that the program will need at run time. However, having +// the folders here might help us to simplify the above function +// which would be useful (currently, there are different versions +// of 'fixup_bundle_environment()' for each supported platform). +// Twelve fallback folders are currently catered for, corresponding to:- +// +// LOCALEDIR +// GTK_DIR +// CONFIG_DIR +// ARDOUR_DIR +// MODULE_DIR +// DATA_DIR +// ICONS_DIR +// PIXMAPS_DIR +// CONTROL_SURFACES_DIR +// VAMP_DIR +// LADSPA_PATH - note that there's only one entry in the path +// VST_PATH - note that there may only be one entry in the path +// +// Returns: +// +// On Success: A pointer to an array containing the above dirs. +// On Failure: NULL +// +#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!! + +static gchar** +get_platform_fallback_folders () +{ +gchar **fallback_dir_vector = 0; +const gchar *pUsrHome = 0; // Do not free !! + + if (!fallback_folders) + { + GArray *pFallbackDirs; + gchar *pAppData = 0; + gchar *pMyAppData = 0; + gchar *pExeRoot = 0; + gchar *pPersonal = 0; + + pFallbackDirs = g_array_new (TRUE, TRUE, sizeof (char *)); + + if (pFallbackDirs) + { + /* Get the path for the user's personal folder */ + gchar *pPersonalTemp = get_win_special_folder (CSIDL_PERSONAL); + + /* and the path for the user's personal application data */ + gchar *pMyAppDataTemp = get_win_special_folder (CSIDL_LOCAL_APPDATA); + + /* and the path for common application data ("Documents and Settings\All Users\Application Data") */ + gchar *pAppDataTemp = get_win_special_folder (CSIDL_COMMON_APPDATA); + + if (0 == pAppDataTemp) + pAppData = g_build_filename("C:\\", "Documents and Settings", "All Users", "Application Data", PROGRAM_NAME, "local", 0); + else + { + pAppData = g_build_filename(pAppDataTemp, PROGRAM_NAME, "local", 0); + g_free (pAppDataTemp); + } + + if (0 == pMyAppDataTemp) + { + pMyAppData = g_build_filename(g_get_home_dir(), "Application Data", "local", 0); + } + else + { + pMyAppData = g_build_filename(pMyAppDataTemp, 0); + g_free (pMyAppDataTemp); + } + + if (0 == pPersonalTemp) + pPersonal = g_build_filename(g_get_home_dir(), 0); + else + { + pPersonal = g_build_filename(pPersonalTemp, 0); + g_free (pPersonalTemp); + } + + /* Get the path to the running application */ + pExeRoot = g_win32_get_package_installation_directory_of_module (0); + + if (0 == pExeRoot) + { + pExeRoot = g_build_filename("C:\\", "Program Files", PROGRAM_NAME, 0); + } + + if ((pExeRoot) && (pAppData) && (pMyAppData) && (pPersonal)) + { + gchar tmp[PATH_MAX+1]; + gchar* p; + + // Build our LOCALEDIR entry + if (0 != (p = g_build_filename(pAppData, "share", "locale", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our GTK_DIR entry + if (0 != (p = g_build_filename(pPersonal, ".gtk-2.0", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our CONFIG_DIR entry + if (0 != (p = g_build_filename(pAppData, "etc", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our ARDOUR_DIR entry + p = g_build_filename(pMyAppData, PROGRAM_NAME, 0); + + if (0 != p) + { + g_array_append_val (pFallbackDirs, p); + + // Build our MODULE_DIR entry + strcpy(tmp, pExeRoot); + if (0 != (p = strrchr (tmp, G_DIR_SEPARATOR))) + { + *p = '\0'; + + if (0 != (p = g_build_filename(tmp, 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our DATA_DIR entry + if (0 != (p = g_build_filename(pAppData, "share", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our ICONS_DIR entry + if (0 != (p = g_build_filename(pAppData, "share", "icons", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our PIXMAPS_DIR entry + if (0 != (p = g_build_filename(pAppData, "share", "pixmaps", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our CONTROL_SURFACES_DIR entry + if (0 != (p = g_build_filename(pExeRoot, "bin", "surfaces", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our VAMP_DIR entry + p = g_build_filename(pExeRoot, "bin", "vamp", 0); + if (p) + g_array_append_val (pFallbackDirs, p); + else + g_array_append_val (pFallbackDirs, ""); + + // Next, build our LADSPA_PATH entry + p = g_build_filename(pExeRoot, "bin", "plugins", 0); + if (p) + g_array_append_val (pFallbackDirs, p); + else + g_array_append_val (pFallbackDirs, ""); + + // And finally, build our VST_PATH entry + DWORD dwType = REG_SZ; HKEY hKey; + DWORD dwSize = PATH_MAX; p = 0; + if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\VST", 0, KEY_READ, &hKey)) + { + // Look for the user's VST Registry entry + if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize)) + p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), 0); + + RegCloseKey (hKey); + } + + if (p == 0) + if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\VST", 0, KEY_READ, &hKey)) + { + // Look for a global VST Registry entry + if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize)) + p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), 0); + + RegCloseKey (hKey); + } + + if (p == 0) + { + gchar *pVSTx86 = 0; + gchar *pProgFilesX86 = get_win_special_folder (CSIDL_PROGRAM_FILESX86); + + if (pProgFilesX86) + { + // Look for a VST folder under C:\Program Files (x86) + if (pVSTx86 = g_build_filename (pProgFilesX86, "Steinberg", "VSTPlugins", 0)) + { + if (Glib::file_test (pVSTx86, Glib::FILE_TEST_EXISTS)) + if (Glib::file_test (pVSTx86, Glib::FILE_TEST_IS_DIR)) + p = g_build_filename (pVSTx86, 0); + + g_free (pVSTx86); + } + + g_free (pProgFilesX86); + } + + if (p == 0) + { + // Look for a VST folder under C:\Program Files + gchar *pVST = 0; + gchar *pProgFiles = get_win_special_folder (CSIDL_PROGRAM_FILES); + + if (pProgFiles) + { + if (pVST = g_build_filename (pProgFiles, "Steinberg", "VSTPlugins", 0)) + { + if (Glib::file_test (pVST, Glib::FILE_TEST_EXISTS)) + if (Glib::file_test (pVST, Glib::FILE_TEST_IS_DIR)) + p = g_build_filename (pVST, 0); + + g_free (pVST); + } + + g_free (pProgFiles); + } + } + } + + if (p == 0) + { + // If all else failed, assume the plugins are under "My Documents" + pUsrHome = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); + if (pUsrHome) + p = g_build_filename (pUsrHome, "Plugins", "VST", 0); + else + { + pUsrHome = g_build_filename(g_get_home_dir(), "My Documents", 0); + if (pUsrHome) + p = g_build_filename (pUsrHome, "Plugins", "VST", 0); + } + } + else + { + gchar* q = 0; + + // Concatenate the registry path with the user's personal path + pUsrHome = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); + + if (pUsrHome) + { + q = p; + p = g_build_path (";", q, g_build_filename(pUsrHome, "Plugins", "VST", 0), 0); + } + else + { + pUsrHome = g_build_filename(g_get_home_dir(), "My Documents", 0); + if (pUsrHome) + { + q = p; + p = g_build_path (";", q, g_build_filename (pUsrHome, "Plugins", "VST", 0), 0); + } + } + } + + if (p) //VST + g_array_append_val (pFallbackDirs, p); + else + g_array_append_val (pFallbackDirs, ""); + + // BUNDLED_LV2 + p = g_build_filename(pExeRoot, "bin", "lv2", 0); + if (p) + g_array_append_val (pFallbackDirs, p); + else + g_array_append_val (pFallbackDirs, ""); + } + } + } + } + } + } + } + } + } + } + + g_free (pAppData); + g_free (pMyAppData); + g_free (pExeRoot); + g_free (pPersonal); + } + + fallback_dir_vector = fallback_folders = (gchar **) g_array_free (pFallbackDirs, FALSE); + } + } + else + fallback_dir_vector = fallback_folders; + + return (fallback_dir_vector); +} + +#else +// Assume Linux, Cygwin or OS-X. Note that in all 3 cases we only +// need to cater for unbundled releases (those built by a user from +// source). Bundled releases of Ardour and Mixbus now specifically +// write their folders and paths to the user's environment at startup. +// See the function 'fixup_bundle_environment()'. + +static gchar** +get_platform_fallback_folders () +{ +gchar **fallback_dir_vector = 0; +gchar *pUsrHome = 0; + + if (!fallback_folders) + { + GArray *pFallbackDirs; + gchar *pAppData = 0; + gchar *pExeRoot = 0; + gchar *pPersonal = 0; + + pFallbackDirs = g_array_new (TRUE, TRUE, sizeof (char *)); + + if (pFallbackDirs) + { + pAppData = g_build_filename("/usr", "local", 0); + pExeRoot = g_build_filename("/usr", "local", "lib", "ardour2", 0); + pPersonal = g_build_filename(g_get_home_dir(), 0); + + if ((pExeRoot) && (pAppData) && (pPersonal)) + { + gchar tmp[PATH_MAX+1]; + gchar* p; + + // Build our LOCALEDIR entry + if (0 != (p = g_build_filename(pAppData, "share", "locale", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our GTK_DIR entry + if (0 != (p = g_build_filename(pPersonal, ".gtk-2.0", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our CONFIG_DIR entry + if (0 != (p = g_build_filename(pAppData, "etc", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our ARDOUR_DIR entry + p = ""; // Empty string (temporary) + if (0 != p) + { + g_array_append_val (pFallbackDirs, p); + + // Build our MODULE_DIR entry + strcpy(tmp, pExeRoot); + if (0 != (p = strrchr (tmp, G_DIR_SEPARATOR))) + { + *p = '\0'; + + if (0 != (p = g_build_filename(tmp, 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our DATA_DIR entry + if (0 != (p = g_build_filename(pAppData, "share", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our ICONS_DIR entry (re-use 'tmp') + strcpy(tmp, "/usr/local/share/ardour2"); + if (0 != (p = g_build_filename(tmp, "icons", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our PIXMAPS_DIR entry + if (0 != (p = g_build_filename(tmp, "pixmaps", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our CONTROL_SURFACES_DIR entry + if (0 != (p = g_build_filename(pExeRoot, "surfaces", 0))) + { + g_array_append_val (pFallbackDirs, p); + + // Build our VAMP_DIR entry + p = g_build_filename(pExeRoot, "vamp", 0); + if (p) + g_array_append_val (pFallbackDirs, p); + + // Next, build our LADSPA_PATH entry + p = g_build_filename(Glib::path_get_dirname(pExeRoot).c_str(), "plugins", 0); + if (p) + g_array_append_val (pFallbackDirs, p); + + // And finally, build our VST_PATH entry + if (g_getenv("HOME")) + p = g_build_filename(g_getenv("HOME"), "VST", "plugins", 0); + else + p = g_build_filename(g_get_home_dir(), "VST", "plugins", 0); + + if (p) + g_array_append_val (pFallbackDirs, p); + } + } + } + } + } + } + } + } + } + } + + g_free (pAppData); + g_free (pExeRoot); + g_free (pPersonal); + } + + fallback_dir_vector = fallback_folders = (gchar **) g_array_free (pFallbackDirs, FALSE); + } + } + else + fallback_dir_vector = fallback_folders; + + if (pUsrHome) + g_free (pUsrHome); + + return (fallback_dir_vector); +} +#endif + + +//*************************************************************** +// +// get_platform_fallback_folder() +// +// Returns a const gchar* which points to a string describing +// the full path to the Ardour fallback folder corresponding to +// the supplied index. See 'get_platform_fallback_folders()' for a +// complete list of the supported index enumerations. Calling this +// function will initialize the fallback folder array if it wasn't +// already initiaized. The array should then (eventually) be freed +// using 'free_platform_fallback_folders()'. +// +// Returns: +// +// On Success: A pointer to the path string contained at the +// relevant index. +// On Failure: NULL +// +LIBPBD_API G_CONST_RETURN gchar* PBD_APICALLTYPE +get_platform_fallback_folder (PBD::fallback_folder_t index) +{ + if ((index >= 0) && (index < FALLBACK_FOLDER_MAX)) + return ((G_CONST_RETURN gchar *)get_platform_fallback_folders ()[index]); + else + return (G_CONST_RETURN gchar *) 0; +} + + +//*************************************************************** +// +// alloc_platform_fallback_folders() +// +// Calls 'get_platform_fallback_folders()' to ensure that memory +// for the fallback folder array is already allocated before the +// array gets used. It doesn't cause any problems if the array gets +// used prior to calling this function (since the memory will get +// allocated anyway, on fist usage). Either way however, the momory +// must later be freed using 'free_platform_fallback_folders()'. +// +// Returns: +// +// The value obtained from 'get_platform_fallback_folders()' +// +LIBPBD_API G_CONST_RETURN gchar* G_CONST_RETURN * PBD_APICALLTYPE +alloc_platform_fallback_folders () +{ + return ((G_CONST_RETURN gchar* G_CONST_RETURN *)get_platform_fallback_folders ()); +} + + +//*************************************************************** +// +// free_platform_fallback_folders() +// +// Frees the memory that was previously allocated for the Ardour +// fallback folder array. +// +// Returns: +// +// NONE. +// +LIBPBD_API void PBD_APICALLTYPE +free_platform_fallback_folders () +{ +int index = FOLDER_LOCALE; + + if (fallback_folders) + { + gchar *p = get_platform_fallback_folders()[(fallback_folder_t)index++]; + + while (index < (FALLBACK_FOLDER_MAX+1)) { + if (p) + g_free (p); + + if (index < FALLBACK_FOLDER_MAX) + p = get_platform_fallback_folders()[(fallback_folder_t)index++]; + else + break; + } + + fallback_folders = 0; + } +} + +} // namespace PBD + diff --git a/libs/pbd/ffs.cc b/libs/pbd/ffs.cc new file mode 100644 index 0000000000..557504f14e --- /dev/null +++ b/libs/pbd/ffs.cc @@ -0,0 +1,49 @@ +/* + Copyright (C) 2013 Tim Mayberry + + 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. + +*/ + +#include "pbd/ffs.h" + +#ifndef COMPILER_MSVC +#include <strings.h> +#endif + +namespace PBD { +int +ffs (int x) +{ +#if defined (COMPILER_MINGW) + return __builtin_ffs(x); +#elif defined (COMPILER_MSVC) + unsigned long index; +#ifdef WIN64 + if (0 != _BitScanForward64(&index, (__int64)x)) +#else + if (0 != _BitScanForward(&index, (unsigned long)x)) +#endif + index++; // Make the result 1-based + else + index = 0; // All bits were zero + + return (int)index; +#else + return ::ffs(x); +#endif +} + +} diff --git a/libs/pbd/file_manager.cc b/libs/pbd/file_manager.cc index a71ffca190..2cfa63ae39 100644 --- a/libs/pbd/file_manager.cc +++ b/libs/pbd/file_manager.cc @@ -18,19 +18,22 @@ */ #include <sys/time.h> -#include <sys/resource.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <cassert> #include <cstdio> +#include <glib.h> +#include <glib/gstdio.h> + #ifdef __APPLE__ #include <mach/mach_time.h> #endif #include "pbd/compose.h" #include "pbd/file_manager.h" +#include "pbd/resource.h" #include "pbd/debug.h" using namespace std; @@ -41,12 +44,11 @@ FileManager* FileDescriptor::_manager; FileManager::FileManager () : _open (0) { - struct rlimit rl; - int const r = getrlimit (RLIMIT_NOFILE, &rl); + struct ResourceLimit rl; /* XXX: this is a bit arbitrary */ - if (r == 0) { - _max_open = rl.rlim_cur - 64; + if (get_resource_limit (OpenFiles, rl)) { + _max_open = rl.current_limit - 64; } else { _max_open = 256; } @@ -116,10 +118,14 @@ FileManager::allocate (FileDescriptor* d) #ifdef __APPLE__ d->_last_used = mach_absolute_time(); -#else +#elif defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) struct timespec t; clock_gettime (CLOCK_MONOTONIC, &t); d->_last_used = t.tv_sec + (double) t.tv_nsec / 10e9; +#else + struct timeval now; + gettimeofday (&now, NULL); + d->_last_used = now.tv_sec + (double) now.tv_usec / 10e6; #endif d->_refcount++; @@ -222,8 +228,19 @@ bool FdFileDescriptor::open () { /* we must have a lock on the FileManager's mutex */ - - _fd = ::open (_path.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); + + /* files must be opened with O_BINARY flag on windows + * or it treats the file as a text stream and puts in + * line endings in etc + */ +#ifdef WIN32 +#define WRITE_FLAGS O_RDWR | O_CREAT | O_BINARY +#define READ_FLAGS O_RDONLY | O_BINARY +#else +#define WRITE_FLAGS O_RDWR | O_CREAT +#define READ_FLAGS O_RDONLY +#endif + _fd = ::g_open (_path.c_str(), _writeable ? WRITE_FLAGS : READ_FLAGS, _mode); return (_fd == -1); } diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc index bb290fa6aa..44254989c1 100644 --- a/libs/pbd/file_utils.cc +++ b/libs/pbd/file_utils.cc @@ -23,6 +23,10 @@ #include <glib.h> #include <glib/gstdio.h> +#ifdef COMPILER_MINGW +#include <io.h> // For W_OK +#endif + #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> #include <glibmm/pattern.h> @@ -31,6 +35,7 @@ #include "pbd/compose.h" #include "pbd/file_utils.h" +#include "pbd/debug.h" #include "pbd/error.h" #include "pbd/pathscanner.h" #include "pbd/stl_delete.h" @@ -76,6 +81,11 @@ find_matching_files_in_directory (const std::string& directory, std::string full_path(directory); full_path = Glib::build_filename (full_path, *file_iter); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1\n", full_path) + ); + result.push_back(full_path); } } @@ -94,7 +104,7 @@ find_matching_files_in_directories (const vector<std::string>& paths, } void -find_matching_files_in_search_path (const SearchPath& search_path, +find_matching_files_in_search_path (const Searchpath& search_path, const Glib::PatternSpec& pattern, vector<std::string>& result) { @@ -102,7 +112,7 @@ find_matching_files_in_search_path (const SearchPath& search_path, } bool -find_file_in_search_path(const SearchPath& search_path, +find_file_in_search_path(const Searchpath& search_path, const string& filename, std::string& result) { @@ -113,24 +123,28 @@ find_file_in_search_path(const SearchPath& search_path, if (tmp.size() == 0) { + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("No file matching %1 found in Path: %2\n", filename, search_path.to_string()) + ); return false; } -#if 0 if (tmp.size() != 1) { - info << string_compose - ( - "Found more than one file matching %1 in search path %2", - filename, - search_path () - ) - << endmsg; + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found more that one file matching %1 in Path: %2\n", filename, search_path.to_string()) + ); } -#endif result = tmp.front(); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1 in Path: %2\n", filename, search_path.to_string()) + ); + return true; } @@ -188,9 +202,9 @@ get_absolute_path (const std::string & p) bool equivalent_paths (const std::string& a, const std::string& b) { - struct stat bA; + GStatBuf bA; int const rA = g_stat (a.c_str(), &bA); - struct stat bB; + GStatBuf bB; int const rB = g_stat (b.c_str(), &bB); return (rA == 0 && rB == 0 && bA.st_dev == bB.st_dev && bA.st_ino == bB.st_ino); @@ -221,7 +235,7 @@ exists_and_writable (const std::string & p) make us unwritable. */ - struct stat statbuf; + GStatBuf statbuf; if (g_stat (p.c_str(), &statbuf) != 0) { /* doesn't exist - not writable */ diff --git a/libs/pbd/fpu.cc b/libs/pbd/fpu.cc index 8929491cd9..73bc7e599d 100644 --- a/libs/pbd/fpu.cc +++ b/libs/pbd/fpu.cc @@ -16,7 +16,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#ifndef COMPILER_MSVC #include "libpbd-config.h" #define _XOPEN_SOURCE 600 @@ -141,3 +141,7 @@ FPU::FPU () FPU::~FPU () { } + +#else // COMPILER_MSVC + const char* pbd_fpu = "pbd/msvc/fpu.cc takes precedence over this file"; +#endif // COMPILER_MSVC diff --git a/libs/pbd/glib_semaphore.cc b/libs/pbd/glib_semaphore.cc new file mode 100644 index 0000000000..7565e0c069 --- /dev/null +++ b/libs/pbd/glib_semaphore.cc @@ -0,0 +1,68 @@ +/* + Copyright (C) 2010 Tim Mayberry + + 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. + +*/ + +#include "pbd/glib_semaphore.h" + +namespace PBD { + +GlibSemaphore::GlibSemaphore (gint initial_val) + : + m_counter(initial_val) +{ } + +void +GlibSemaphore::wait () +{ + Glib::Threads::Mutex::Lock guard (m_mutex); + + while (m_counter.get() < 1) { + m_cond.wait(m_mutex); + } + + // this shouldn't need to be inside the lock + --m_counter; +} + +bool +GlibSemaphore::try_wait () +{ + if (!m_mutex.trylock()) + { + return false; + } + // lock successful + while (m_counter.get() < 1) { + m_cond.wait(m_mutex); + } + + // the order of these should not matter + --m_counter; + m_mutex.unlock(); + return true; +} + +void +GlibSemaphore::post () +{ + // atomic, no locking required + ++m_counter; + m_cond.signal(); +} + +} // namespace PBD diff --git a/libs/pbd/localeguard.cc b/libs/pbd/localeguard.cc new file mode 100644 index 0000000000..12093beeaa --- /dev/null +++ b/libs/pbd/localeguard.cc @@ -0,0 +1,34 @@ +#include <cstring> +#include <locale.h> +#include <stdlib.h> + +#include "pbd/localeguard.h" + +// JE - added temporarily, to reduce the delay effects when calling +// setlocale() recursively in a Windows GUI thread (we should think +// about moving the caller(s) into a dedicated worker thread). +std::string PBD::LocaleGuard::current; + +PBD::LocaleGuard::LocaleGuard (const char* str) + : old(0) +{ + if (current != str) { + old = strdup (setlocale (LC_NUMERIC, NULL)); + if (strcmp (old, str)) { + if (setlocale (LC_NUMERIC, str)) + current = str; + } + } +} + +PBD::LocaleGuard::~LocaleGuard () +{ + if (old) { + if (setlocale (LC_NUMERIC, old)) + current = old; + + free ((char*)old); + } +} + + diff --git a/libs/pbd/localtime_r.cc b/libs/pbd/localtime_r.cc new file mode 100644 index 0000000000..c72e3eb458 --- /dev/null +++ b/libs/pbd/localtime_r.cc @@ -0,0 +1,41 @@ +#ifdef WAF_BUILD +#include "libpbd-config.h" +#endif + +#ifndef HAVE_LOCALTIME_R +#include <time.h> +#include <string.h> + +#include "pbd/pthread_utils.h" +#include "pbd/localtime_r.h" + +#ifdef localtime_r +#undef localtime_r +#endif + +struct tm * +localtime_r(const time_t *const timep, struct tm *p_tm) +{ + static pthread_mutex_t time_mutex; + static int time_mutex_inited = 0; + struct tm *tmp; + + if (!time_mutex_inited) + { + time_mutex_inited = 1; + pthread_mutex_init(&time_mutex, NULL); + } + + pthread_mutex_lock(&time_mutex); + tmp = localtime(timep); + if (tmp) + { + memcpy(p_tm, tmp, sizeof(struct tm)); + tmp = p_tm; + } + pthread_mutex_unlock(&time_mutex); + + return tmp; +} + +#endif diff --git a/libs/pbd/mountpoint.cc b/libs/pbd/mountpoint.cc index 46cea42e0a..65f011c745 100644 --- a/libs/pbd/mountpoint.cc +++ b/libs/pbd/mountpoint.cc @@ -17,7 +17,7 @@ $Id$ */ - +#ifndef COMPILER_MSVC #include <cstdio> #include <cstring> #include <string> @@ -94,6 +94,14 @@ mountpoint (string path) return best; } +#elif defined(PLATFORM_WINDOWS) + +string +mountpoint (string path) +{ + // TODO ... if needed +} + #else // !HAVE_GETMNTENT #include <sys/param.h> @@ -164,3 +172,7 @@ main (int argc, char *argv[]) } #endif // TEST_MOUNTPOINT + +#else // COMPILER_MSVC + const char* pbd_mountpoint = "pbd/msvc/mountpoint.cc takes precedence over this file"; +#endif // COMPILER_MSVC diff --git a/libs/pbd/msvc/fpu.cc b/libs/pbd/msvc/fpu.cc new file mode 100644 index 0000000000..6997405928 --- /dev/null +++ b/libs/pbd/msvc/fpu.cc @@ -0,0 +1,124 @@ +#ifdef COMPILER_MSVC // Added by JE - 05-12-2009. Inline assembler instructions + // have been changed to Intel format and (in the case of + // cpuid) was replaced by the equivalent VC++ system call). +#define _XOPEN_SOURCE 600 +#include <cstdlib> +#include <stdint.h> +#include <intrin.h> // Added by JE - 05-12-2009 + +#include <pbd/fpu.h> +#include <pbd/error.h> + +#include "i18n.h" + +using namespace PBD; +using namespace std; + +FPU::FPU () +{ + unsigned long cpuflags = 0; + + _flags = (Flags)0; + +#ifndef ARCH_X86 + return; + +#else + +#ifndef USE_X86_64_ASM +int cpuInfo[4]; + + __cpuid (cpuInfo, 1); + cpuflags = cpuInfo[3]; +/* + __asm { // This is how the original section would look if converted to Intel syntax. + // However, I have grave doubts about whether it's doing the right thing. + // It seems as if the intention was to retrieve feature information from + // the processor. However, feature information is returned in the ebx register + // (if you believe Wikipedia) or in edx (if you believe Microsoft). Unfortunately, + // both registers get ignored in the original code!! Confused?? Join the club!! + mov eax, 1 + push ebx + cpuid + mov edx, 0 + pop ebx + mov cpuflags, ecx // This can't be right, surely??? + }; */ +#else +// Note that this syntax is currently still in AT&T format ! + asm volatile ( + "pushq %%rbx\n" + "movq $1, %%rax\n" + "cpuid\n" + "movq %%rdx, %0\n" + "popq %%rbx\n" + : "=r" (cpuflags) + : + : "%rax", "%rcx", "%rdx", "memory" + ); + +#endif /* USE_X86_64_ASM */ + + if (cpuflags & (1<<25)) { + _flags = Flags (_flags | (HasSSE|HasFlushToZero)); + } + + if (cpuflags & (1<<26)) { + _flags = Flags (_flags | HasSSE2); + } + + if (cpuflags & (1 << 24)) { + bool aligned_malloc = false; // Added by JE - 05-12-2009 + char* fxbuf = 0; +// This section changed by JE - 05-12-2009 +#ifdef NO_POSIX_MEMALIGN +#if defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // All of these support '_aligned_malloc()' + fxbuf = (char *) _aligned_malloc(512, 16); // (note that they all need at least MSVC runtime 7.0) + aligned_malloc = true; +#else + fxbuf = (char *) malloc(512); +#endif +#else + fxbuf = posix_memalign ((void**)&fxbuf, 16, 512); +#endif + // Verify that fxbuf is correctly aligned + unsigned long buf_addr = (unsigned long)(void*)fxbuf; + if ((0 == buf_addr) || (buf_addr % 16)) + error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg; + else + { + memset(fxbuf, 0, 512); // Initialize the buffer !!! Added by JE - 12-12-2009 + + __asm { + mov eax, fxbuf + fxsave [eax] + }; + + uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]); + + /* if the mask is zero, set its default value (from intel specs) */ + + if (mxcsr_mask == 0) { + mxcsr_mask = 0xffbf; + } + + if (mxcsr_mask & (1<<6)) { + _flags = Flags (_flags | HasDenormalsAreZero); + } + + if (aligned_malloc) + _aligned_free (fxbuf); + else + free (fxbuf); + } + } +#endif // ARCH_X86 +} + +FPU::~FPU () +{ +} + +#else // !COMPILER_MSVC + const char* pbd_fpu = "original pbd/fpu.cc takes precedence over this file"; +#endif // COMPILER_MSVC diff --git a/libs/pbd/msvc/getopt.c b/libs/pbd/msvc/getopt.c new file mode 100644 index 0000000000..2f539a59cf --- /dev/null +++ b/libs/pbd/msvc/getopt.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef COMPILER_MSVC +#include "pbd/msvc_pbd.h" +#endif +#include "getopt.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +__BEGIN_DECLS // Added by JE - 31-01-2010 +// All 'GETOPT_API' declarations added by JE - 31-01-2010 +GETOPT_API int opterr = 1; /* if error message should be printed */ +GETOPT_API int optind = 1; /* index into parent argv vector */ +GETOPT_API int optopt; /* character checked for validity */ +GETOPT_API int optreset; /* reset getopt */ +GETOPT_API char *optarg; /* argument associated with option */ + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(int nargc, // Argument list ratified by JE - 03-01-2010 + char * const *nargv, + const char *ostr) +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = (char*)strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':' && optopt != BADCH) + (void)fprintf(stderr, "%s: illegal option -- %c\n", + "progname", optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + "progname", optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} +__END_DECLS // Added by JE - 31-01-2010 diff --git a/libs/pbd/msvc/getopt.h b/libs/pbd/msvc/getopt.h new file mode 100644 index 0000000000..233a0eefa6 --- /dev/null +++ b/libs/pbd/msvc/getopt.h @@ -0,0 +1,110 @@ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ +/* $FreeBSD: src/include/getopt.h,v 1.1 2002/09/29 04:14:30 eric Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#ifdef PLATFORM_WINDOWS +/* from <sys/cdefs.h> */ +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +# else +# define __BEGIN_DECLS +# define __END_DECLS +# endif +# define __P(args) args +#endif + +/*#ifndef PLATFORM_WINDOWS +#include <sys/cdefs.h> +#include <unistd.h> +#endif*/ + +#ifdef PLATFORM_WINDOWS +# if !defined(GETOPT_API) +# define GETOPT_API __declspec(dllimport) +# endif +#endif + +/* + * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions + */ +#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +__BEGIN_DECLS +GETOPT_API int getopt_long __P((int, char * const *, const char *, + const struct option *, int *)); +__END_DECLS +#endif + +#ifdef PLATFORM_WINDOWS +/* These are global getopt variables */ +__BEGIN_DECLS + +GETOPT_API extern int opterr, /* if error message should be printed */ + optind, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +GETOPT_API extern char* optarg; /* argument associated with option */ + +/* Original getopt */ +GETOPT_API int getopt __P((int, char * const *, const char *)); + +__END_DECLS +#endif + +#endif /* !_GETOPT_H_ */ diff --git a/libs/pbd/msvc/getopt_long.c b/libs/pbd/msvc/getopt_long.c new file mode 100644 index 0000000000..06c459ab84 --- /dev/null +++ b/libs/pbd/msvc/getopt_long.c @@ -0,0 +1,546 @@ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ +/* $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.2 2002/10/16 22:18:42 alfred Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include <stdlib.h> +#include <string.h> + +#ifdef PLATFORM_WINDOWS +#ifdef COMPILER_MSVC +#include "pbd/msvc_pbd.h" // Defines 'GETOPT_API' +#endif +/* Windows needs warnx(). We change the definition though: + * 1. (another) global is defined, opterrmsg, which holds the error message + * 2. errors are always printed out on stderr w/o the program name + * Note that opterrmsg always gets set no matter what opterr is set to. The + * error message will not be printed if opterr is 0 as usual. + */ + +#include "getopt.h" +#include <stdio.h> +#include <stdarg.h> + +GETOPT_API extern char opterrmsg[128]; +char opterrmsg[128]; /* last error message is stored here */ + +static void warnx(int print_error, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (fmt != NULL) + _vsnprintf(opterrmsg, 128, fmt, ap); + else + opterrmsg[0]='\0'; + va_end(ap); + if (print_error) { + fprintf(stderr, opterrmsg); + fprintf(stderr, "\n"); + } +} + +#endif /*PLATFORM_WINDOWS*/ + +/* not part of the original file */ +#ifndef _DIAGASSERT +#define _DIAGASSERT(X) +#endif + +#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND +#define REPLACE_GETOPT +#endif + +#ifdef REPLACE_GETOPT +#ifdef __weak_alias +__weak_alias(getopt,_getopt) +#endif +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#elif HAVE_CONFIG_H && !HAVE_DECL_OPTRESET +static int optreset; +#endif + +#ifdef __weak_alias +__weak_alias(getopt_long,_getopt_long) +#endif + +#if !HAVE_GETOPT_LONG +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return b; +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, + int panonopt_end, + int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + _DIAGASSERT(nargv != NULL); + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(int nargc, + char * const *nargv, + const char *options) +{ + char *oli; /* option letter list index */ + int optchar; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((*(place = nargv[optind]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!PERMUTE) { + /* + * if no permutation wanted, stop parsing + * at first non-option + */ + return -1; + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + if (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = (char*)strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(illoptchar, optchar); +#else + warnx(PRINT_ERROR, illoptchar, optchar); +#endif + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(recargchar, optchar); +#else + warnx(PRINT_ERROR, recargchar, optchar); +#endif + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(recargchar, optchar); +#else + warnx(PRINT_ERROR, recargchar, optchar); +#endif + optopt = optchar; + return BADARG; + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +__BEGIN_DECLS // Added by JE - 31-01-2010 +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the real getopt] + */ +GETOPT_API int // 'GETOPT_API' declaration added by JE - 31-01-2010 +getopt(int nargc, + char * const *nargv, + const char *options) +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + ++optind; + /* + * We found an option (--), so if we skipped non-options, + * we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, + nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + retval = -1; + } + return retval; +} +#endif + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +GETOPT_API int // 'GETOPT_API' declaration added by JE - 31-01-2010 +getopt_long(int nargc, + char * const *nargv, + const char *options, + const struct option *long_options, + int *idx) +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* idx may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + break; + } + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); +#else + warnx(PRINT_ERROR, ambig, (int)current_argv_len, + current_argv); +#endif + optopt = 0; + return BADCH; + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); +#else + warnx(PRINT_ERROR, noarg, (int)current_argv_len, + current_argv); +#endif + /* + * XXX: GNU sets optopt to val regardless of + * flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return BADARG; + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use + * next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' + * indicates no error should be generated + */ +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(recargstring, current_argv); +#else + warnx(PRINT_ERROR, recargstring, current_argv); +#endif + /* + * XXX: GNU sets optopt to val regardless + * of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return BADARG; + } + } else { /* unknown option */ +#ifndef PLATFORM_WINDOWS + if (PRINT_ERROR) + warnx(illoptstring, current_argv); +#else + warnx(PRINT_ERROR, illoptstring, current_argv); +#endif + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +} +__END_DECLS // Added by JE - 31-01-2010 + +#endif /* !GETOPT_LONG */ diff --git a/libs/pbd/msvc/mountpoint.cc b/libs/pbd/msvc/mountpoint.cc new file mode 100644 index 0000000000..d30b24462f --- /dev/null +++ b/libs/pbd/msvc/mountpoint.cc @@ -0,0 +1,166 @@ +/* + Copyright (C) 2002 Paul Davis + + 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. + + $Id: mountpoint.cc 3920 2008-10-11 12:34:46Z paul $ +*/ + +#ifdef COMPILER_MSVC + +/* TODO - Still to be implemented */ + +#include <cstdio> +#include <cstring> +#include <string> +#include <cstring> +#include <limits.h> + +#include <pbd/mountpoint.h> + +using std::string; + +#if HAVE_GETMNTENT +#include <mntent.h> + +struct mntent_sorter { + bool operator() (const mntent *a, const mntent *b) { + return strcmp (a->mnt_dir, b->mnt_dir); + } +}; + +string +mountpoint (string path) +{ + FILE *mntf; + mntent *mnt; + unsigned int maxmatch = 0; + unsigned int matchlen; + const char *cpath = path.c_str(); + char best[PATH_MAX+1]; + + if ((mntf = setmntent ("/etc/mtab", "r")) == 0) { + return ""; + } + + best[0] = '\0'; + + while ((mnt = getmntent (mntf))) { + unsigned int n; + + n = 0; + matchlen = 0; + + /* note: strcmp's semantics are not + strict enough to use for this. + */ + + while (cpath[n] && mnt->mnt_dir[n]) { + if (cpath[n] != mnt->mnt_dir[n]) { + break; + } + matchlen++; + n++; + } + + if (cpath[matchlen] == '\0') { + + endmntent (mntf); + return mnt->mnt_dir; + + } else { + + if (matchlen > maxmatch) { + snprintf (best, sizeof(best), "%s", mnt->mnt_dir); + maxmatch = matchlen; + } + } + } + + endmntent (mntf); + + return best; +} + +#else // !HAVE_GETMNTENT + +string +mountpoint (string path) +{ +return ""; + +/* // The rest is commented out temporarily by JE - 30-11-2009 + // (I think this must be the implementation for MacOS). + struct statfs *mntbufp = 0; + int count; + unsigned int maxmatch = 0; + unsigned int matchlen; + const char *cpath = path.c_str(); + char best[PATH_MAX+1]; + + if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) { + free(mntbufp); + return "\0"; + } + + best[0] = '\0'; + + for (int i = 0; i < count; ++i) { + unsigned int n = 0; + matchlen = 0; + + // note: strcmp's semantics are not + // strict enough to use for this. + + while (cpath[n] && mntbufp[i].f_mntonname[n]) { + if (cpath[n] != mntbufp[i].f_mntonname[n]) { + break; + } + matchlen++; + n++; + } + + if (cpath[matchlen] == '\0') { + snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname); + free(mntbufp); + return best; + + } else { + + if (matchlen > maxmatch) { + snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname); + maxmatch = matchlen; + } + } + } + + return best; +*/ +} +#endif // HAVE_GETMNTENT + +#ifdef TEST_MOUNTPOINT + +main (int argc, char *argv[]) +{ + printf ("mp of %s = %s\n", argv[1], mountpoint (argv[1]).c_str()); + exit (0); +} + +#endif // TEST_MOUNTPOINT + +#else // !COMPILER_MSVC + const char* pbd_mountpoint = "original pbd/mountpoint.cc takes precedence over this file"; +#endif // COMPILER_MSVC diff --git a/libs/pbd/msvc/msvc_pbd.cc b/libs/pbd/msvc/msvc_pbd.cc new file mode 100644 index 0000000000..5b9c9d449a --- /dev/null +++ b/libs/pbd/msvc/msvc_pbd.cc @@ -0,0 +1,914 @@ +/* + 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. + +*/ + +#ifdef COMPILER_MSVC + +#include <WTypes.h> + +extern "C" WINBASEAPI BOOL WINAPI +CreateHardLinkA( LPCSTR lpFileName, + LPCSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes ); // Needs kernel32.lib on anything higher than Win2K + +#include <algorithm> +#include <string> +#include <io.h> +#include <math.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <pbd/error.h> +#include <ardourext/misc.h> +#include <ardourext/pthread.h> // Should ensure that we include the right + // version - but we'll check anyway, later + +#include <glibmm.h> + +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 + +struct timezone +{ + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +LIBPBD_API int PBD_APICALLTYPE +gettimeofday(struct timeval *__restrict tv, __timezone_ptr_t tz) // Does this need to be exported ? +{ +FILETIME ft; +unsigned __int64 tmpres = 0; +static int tzflag = 0; + + if (NULL != tv) + { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + /*converting file time to unix epoch*/ + tmpres /= 10; /*convert into microseconds*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) + { + struct timezone *ptz = static_cast<struct timezone*> (tz); + if (!tzflag) + { + _tzset(); + tzflag++; + } + if (ptz) + { + ptz->tz_minuteswest = _timezone / 60; + ptz->tz_dsttime = _daylight; + } + } + + return 0; +} + +// Define the default comparison operators for Windows (ptw32) 'pthread_t' (not used +// by Ardour AFAIK but would be needed if an array of 'pthread_t' had to be sorted). +#ifndef PTHREAD_H // Defined by PTW32 (Linux and other versions define _PTHREAD_H) +#error "An incompatible version of 'pthread.h' is #included. Use only the Windows (ptw32) version!" +#else +LIBPBD_API bool operator> (const pthread_t& lhs, const pthread_t& rhs) +{ + return (std::greater<void*>()(lhs.p, rhs.p)); +} + +LIBPBD_API bool operator< (const pthread_t& lhs, const pthread_t& rhs) +{ + return (std::less<void*>()(lhs.p, rhs.p)); +} + +LIBPBD_API bool operator!= (const pthread_t& lhs, const pthread_t& rhs) +{ + return (std::not_equal_to<void*>()(lhs.p, rhs.p)); +} + +LIBPBD_API bool operator== (const pthread_t& lhs, const pthread_t& rhs) +{ + return (!(lhs != rhs)); +} +#endif + +// Functions supplied (later) to std::transform +//*************************************************************** +// +// invert_backslash() +// +// Examines a supplied ASCII character and (if the character is +// a backslash) converts it to a forward slash, +// +// Returns: +// +// The supplied character (converted, if it was a backslash) +// +char invert_backslash(char character) +{ + if ('\\' == character) + character = '/'; + + return (character); +} + +//*************************************************************** +// +// invert_forwardslash() +// +// Examines a supplied ASCII character and (if the character is +// a forward slash) converts it to a backslash, +// +// Returns: +// +// The supplied character (converted, if it was a fwd slash) +// +char invert_forwardslash(char character) +{ + if ('/' == character) + character = '\\'; + + return (character); +} + + +//*************************************************************** +// +// pread() +// +// Emulates pread() using _lseek()/_read()/_lseek(). +// +// Returns: +// +// On Success: The number of bytes read from the file +// On Failure: -1 +// +LIBPBD_API ssize_t PBD_APICALLTYPE +pread(int handle, void *buf, size_t nbytes, off_t offset) +{ +int old_errno; +ssize_t ret; + + off_t old_offset = _tell(handle); + + if (0 > old_offset) + ret = (-1); + else + { + _lseek(handle, offset, SEEK_SET); + ret = _read(handle, buf, nbytes); + + old_errno = errno; + _lseek(handle, old_offset, SEEK_SET); + errno = old_errno; + } + + return (ret); +} + + +//*************************************************************** +// +// pwrite() +// +// Emulates pwrite() using _lseek()/_write()/_lseek(). +// +// Returns: +// +// On Success: The number of bytes written to the file +// On Failure: -1 +// +LIBPBD_API ssize_t PBD_APICALLTYPE +pwrite(int handle, const void *buf, size_t nbytes, off_t offset) +{ +int old_errno; +ssize_t ret; + + off_t old_offset = _lseek(handle, offset, SEEK_SET); + + if (0 > old_offset) + ret = (-1); + else + { + ret = _write(handle, buf, nbytes); + + old_errno = errno; + _lseek(handle, old_offset, SEEK_SET); + errno = old_errno; + } + + return (ret); +} + +//*************************************************************** +// +// round() +// +// Emulates round() using floor(). +// +// Returns: +// +// On Success: The largest integer that is less than or +// equal to 'x'. +// On Failure: None +// +LIBPBD_API double PBD_APICALLTYPE +round(double x) +{ + return (floor(x)); +} + +namespace PBD { + +//*************************************************************** +// +// TestForMinimumSpecOS() +// +// Tests the user's OS to see if it is Win2K or later (could be +// expanded quite easily to accommodate other OS's) +// +// Returns: +// +// On Success: TRUE (if the user's OS matches the minimum spec) +// On Failure: FALSE otherwise +// +LIBPBD_API bool PBD_APICALLTYPE +TestForMinimumSpecOS(char *revision /* currently ignored */) +{ +bool bRet = true; +#ifdef PLATFORM_WINDOWS + bRet = false; + HINSTANCE hKernelDll = (HINSTANCE)dlopen("kernel32.dll", RTLD_NOW); + + if (hKernelDll) + { + // 'CreateHardLink()' is only available from Win2K onwards. + if (NULL != dlsym(hKernelDll, "CreateHardLinkA")) + bRet = true; + + dlclose(hKernelDll); + } +#endif + // Other OS's could be accommodated here + + return (bRet); +} + + +//*************************************************************** +// +// realpath() +// +// Emulates POSIX realpath() using Win32 _fullpath(). +// +// Returns: +// +// On Success: A pointer to the resolved (absolute) path +// On Failure: NULL +// +LIBPBD_API char* PBD_APICALLTYPE +realpath (const char *original_path, char resolved_path[_MAX_PATH+1]) +{ +char *pRet = NULL; +bool bIsSymLink = 0; // We'll probably need to test the incoming path + // to find out if it points to a Windows shortcut + // (or a hard link) and set this appropriately. + if (bIsSymLink) + { + // At the moment I'm not sure if Windows '_fullpath()' is directly + // equivalent to POSIX 'realpath()' - in as much as the latter will + // resolve the supplied path if it happens to point to a symbolic + // link ('_fullpath()' probably DOESN'T do this but I'm not really + // sure if Ardour needs such functionality anyway). Therefore we'll + // possibly need to add that functionality here at a later date. + } + else + { + char temp[(MAX_PATH+1)*6]; // Allow for maximum length of a path in UTF8 characters + + // POSIX 'realpath()' requires that the buffer size is at + // least PATH_MAX+1, so assume that the user knew this !! + pRet = _fullpath(temp, Glib::locale_from_utf8(original_path).c_str(), _MAX_PATH); + if (NULL != pRet) + strcpy(resolved_path, Glib::locale_to_utf8(temp).c_str()); + } + + return (pRet); +} + + +//*************************************************************** +// +// opendir() +// +// Creates a pointer to a DIR structure, appropriately filled in +// and ready to begin a directory search iteration. +// +// Returns: +// +// On Success: Pointer to a (heap based) DIR structure +// On Failure: NULL +// +LIBPBD_API DIR* PBD_APICALLTYPE +opendir (const char *szPath) +{ +wchar_t wpath[PATH_MAX+1]; +unsigned int rc; +DIR *pDir = 0; + + errno = 0; + + if (!szPath) + errno = EFAULT; + + if ((!errno) && ('\0' == szPath[0])) + errno = ENOTDIR; + + // Determine if the given path really is a directory + + if (!errno) + if (0 == MultiByteToWideChar (CP_UTF8, 0, (LPCSTR)szPath, -1, (LPWSTR)wpath, sizeof(wpath))) + errno = EFAULT; + + if ((!errno) && ((rc = GetFileAttributesW(wpath)) == -1)) + errno = ENOENT; + + if ((!errno) && (!(rc & FILE_ATTRIBUTE_DIRECTORY))) + // Error. Entry exists but not a directory. */ + errno = ENOTDIR; + + if (!errno) + { + // Allocate enough memory to store DIR structure, plus + // the complete directory path originally supplied. + pDir = (DIR *)malloc(sizeof(DIR) + strlen(szPath) + strlen("\\") + strlen ("*")); + + if (!pDir) + { + // Error - out of memory + errno = ENOMEM; + } + } + + if (!errno) + { + // Create the search expression + strcpy(pDir->dd_name, szPath); + + // Add a backslash if the path doesn't already end with one + if (pDir->dd_name[0] != '\0' && + pDir->dd_name[strlen(pDir->dd_name) - 1] != '/' && + pDir->dd_name[strlen(pDir->dd_name) - 1] != '\\') + { + strcat (pDir->dd_name, "\\"); + } + + // Add the search pattern + strcat(pDir->dd_name, "*"); + + // Initialize handle to -1 so that a premature closedir() + // doesn't try to call _findclose() on it. + pDir->dd_handle = (-1); + + // Initialize the status + pDir->dd_stat = 0; + + // Initialize the dirent structure. 'ino' and 'reclen' are invalid under Win32 + // and 'name' simply points at the appropriate part of the findfirst_t struct. + pDir->dd_dir.d_ino = 0; + pDir->dd_dir.d_reclen = 0; + pDir->dd_dir.d_namlen = 0; + strcpy(pDir->dd_dir.d_name, pDir->dd_dta.name); + + return (pDir); // Succeeded + } + + if (pDir) + free (pDir); + return (DIR *) 0; // Failed +} + + +//*************************************************************** +// +// readdir() +// +// Return a pointer to a dirent struct, filled with information +// about the next entry in the directory. +// +// Returns: +// +// On Success: A pointer to the supplied DIR's 'dirent' struct +// On Failure: NULL +// +LIBPBD_API struct dirent* PBD_APICALLTYPE +readdir (DIR* pDir) +{ +int old_errno = 0; +errno = 0; + + // Check for valid DIR struct + if (!pDir) + errno = EFAULT; + + if ((strcmp(pDir->dd_dir.d_name, pDir->dd_dta.name)) && (!errno)) + // The structure does not seem to be set up correctly + errno = EINVAL; + else + { + if (pDir->dd_stat < 0) + { + // We have already returned all files in this directory + // (or the structure has an invalid dd_stat). + return (struct dirent *)0; + } + else if (pDir->dd_stat == 0) + { + // We haven't started the search yet. + // Start the search + pDir->dd_handle = _findfirst (Glib::locale_from_utf8(pDir->dd_name).c_str(), &(pDir->dd_dta)); + + if (pDir->dd_handle == -1) + // The directory is empty + pDir->dd_stat = -1; + else + pDir->dd_stat = 1; + } + else + { + // Do not return ENOENT on last file in directory + old_errno = errno; + + // Get the next search entry + if (_findnext (pDir->dd_handle, &(pDir->dd_dta))) + { + // We are off the end or otherwise error + errno = old_errno; + _findclose (pDir->dd_handle); + pDir->dd_handle = -1; + pDir->dd_stat = -1; + } + else + // Update to indicate the correct status number + pDir->dd_stat++; + } + + if (pDir->dd_stat > 0) + { + // We successfully got an entry. Details about the file are + // already appropriately filled in except for the length of + // file name. + strcpy(pDir->dd_dir.d_name, pDir->dd_dta.name); + pDir->dd_dir.d_namlen = strlen (pDir->dd_dir.d_name); + return (&pDir->dd_dir); // Succeeded + } + } + + return (struct dirent *) 0; // Failed +} + + +//*************************************************************** +// +// closedir() +// +// Frees the resources allocated by opendir(). +// +// Returns: +// +// On Success: 0 +// On Failure: -1 +// +LIBPBD_API int PBD_APICALLTYPE +closedir (DIR *pDir) +{ +int rc = 0; + + errno = 0; + + if (!pDir) + errno = EFAULT; + else + { + if ((-1) != pDir->dd_handle) + rc = _findclose (pDir->dd_handle); + + // Free the DIR structure + free (pDir); + + return rc; // Succeeded + } + + return (-1); // Failed +} + +//*************************************************************** +// +// mkstemp() +// +// Emulates Linux mkstemp() using Win32 _mktemp() and _open() etc. +// +// Returns: +// +// On Success: A file descriptor for the opened file. +// On Failure: (-1) +// +LIBPBD_API int PBD_APICALLTYPE +mkstemp (char *template_name) +{ +int ret = (-1); +char *szFileName; +char szTempPath[PATH_MAX+100]; // Just ensure we have plenty of buffer space + + if (NULL != (szFileName = _mktemp(template_name))) + { + if (0 != ::GetTempPathA(sizeof(szTempPath), szTempPath)) + { + strcat(szTempPath, szFileName); + ret = _open(szTempPath, (_O_CREAT|_O_BINARY|_O_TEMPORARY|_O_RDWR|_O_TRUNC), _S_IWRITE); + } + } + + return (ret); +} + + +//*************************************************************** +// +// ntfs_link() +// +// Emulates Linux link() using Win32 CreateHardLink()(NTFS only). +// +// Returns: +// +// On Success: Non-zero. +// On Failure: Zero (call 'GetLastError()' to retrieve info) +// +LIBPBD_API int PBD_APICALLTYPE +ntfs_link (const char *existing_filepath, const char *link_filepath) +{ +int ret = 1; // 'ERROR_INVALID_FUNCTION' +bool bValidPath = false; + + // Make sure we've been sent a valid input string + if (existing_filepath && link_filepath) + { + std::string strRoot = existing_filepath; + + if ((1 < strRoot.length()) && ('\\' == existing_filepath[0]) && ('\\' == existing_filepath[1])) + { + int slashcnt = 0; + + // We've been sent a network path. Convert backslashes to forward slashes temporarily. + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash); + + // Now, if there are less than four slashes, add a fourth one or abort + std::string::iterator iter = strRoot.begin(); + while ((slashcnt < 4) && (iter != strRoot.end())) + { + if ('/' == (*iter)) + slashcnt++; + + ++iter; + } + + if (slashcnt > 2) + { + // If only 3 slashes were counted, add a trailing slash + if (slashcnt == 3) + strRoot += '/'; + + // Now find the position of the fourth slash + iter = strRoot.begin(); + int charcnt = 0; + for (slashcnt=0; slashcnt<4;) + { + charcnt++; + + if ('/' == (*iter)) + slashcnt++; + + if (++iter == strRoot.end()) + break; + } + + strRoot.resize(charcnt); + bValidPath = true; + } + } + else + { + // Assume a standard Windows style path + if (1 < strRoot.length() && (':' == existing_filepath[1])) + { + // Convert backslashes to forward slashes temporarily. + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash); + + if (2 == strRoot.length()) + strRoot += '/'; + + if ('/' == strRoot[2]) + { + strRoot.resize(3); + bValidPath = true; + } + } + } + + if (bValidPath) + { + char szFileSystemType[_MAX_PATH+1]; + + // Restore the original backslashes + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_forwardslash); + + // Windows only supports hard links for the NTFS filing + // system, so let's make sure that's what we're using!! + if (::GetVolumeInformationA(strRoot.c_str(), NULL, 0, NULL, NULL, NULL, szFileSystemType, _MAX_PATH+1)) + { + std::string strRootFileSystemType = szFileSystemType; + std::transform(strRootFileSystemType.begin(), strRootFileSystemType.end(), strRootFileSystemType.begin(), ::toupper); +#if (_WIN32_WINNT >= 0x0500) + if (0 == strRootFileSystemType.compare("NTFS")) + { + if (TestForMinimumSpecOS()) // Hard links were only available from Win2K onwards + if (0 == CreateHardLinkA(link_filepath, existing_filepath, NULL)) + { // Note that the above API call cannot create a link to a directory, so + // should we also be checking that the supplied path was actually a file? + ret = GetLastError(); + } + else + SetLastError(ret = 0); // 'NO_ERROR' + } + else + { + ret = 4300; // 'ERROR_INVALID_MEDIA' + } +#endif + } + } + else + ret = 123; // 'ERROR_INVALID_NAME' + } + else + ret = 161; // 'ERROR_BAD_PATHNAME' + + if (ret) + { + SetLastError(ret); + return (-1); + } + else + return (0); +} + + +//*************************************************************** +// +// ntfs_unlink() +// +// Emulates Linux unlink() using Win32 DeleteFile()(NTFS only). +// +// Returns: +// +// On Success: Non-zero. +// On Failure: Zero (call 'GetLastError()' to retrieve info) +// +LIBPBD_API int PBD_APICALLTYPE +ntfs_unlink (const char *link_filepath) +{ +int ret = 1; // 'ERROR_INVALID_FUNCTION' +bool bValidPath = false; + + // Make sure we've been sent a valid input string + if (link_filepath) + { + std::string strRoot = link_filepath; + + if ((1 < strRoot.length()) && ('\\' == link_filepath[0]) && ('\\' == link_filepath[1])) + { + int slashcnt = 0; + + // We've been sent a network path. Convert backslashes to forward slashes temporarily. + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash); + + // Now, if there are less than four slashes, add a fourth one or abort + std::string::iterator iter = strRoot.begin(); + while ((slashcnt < 4) && (iter != strRoot.end())) + { + if ('/' == (*iter)) + slashcnt++; + + ++iter; + } + + if (slashcnt > 2) + { + // If only 3 slashes were counted, add a trailing slash + if (slashcnt == 3) + strRoot += '/'; + + // Now find the position of the fourth slash + iter = strRoot.begin(); + int charcnt = 0; + for (slashcnt=0; slashcnt<4;) + { + charcnt++; + + if ('/' == (*iter)) + slashcnt++; + + if (++iter == strRoot.end()) + break; + } + + strRoot.resize(charcnt); + bValidPath = true; + } + } + else + { + // Assume a standard Windows style path + if (1 < strRoot.length() && (':' == link_filepath[1])) + { + // Convert backslashes to forward slashes temporarily. + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash); + + if (2 == strRoot.length()) + strRoot += '/'; + + if ('/' == strRoot[2]) + { + strRoot.resize(3); + bValidPath = true; + } + } + } + + if (bValidPath) + { + char szFileSystemType[_MAX_PATH+1]; + + // Restore the original backslashes + std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_forwardslash); + + // Windows only supports hard links for the NTFS filing + // system, so let's make sure that's what we're using!! + if (::GetVolumeInformationA(strRoot.c_str(), NULL, 0, NULL, NULL, NULL, szFileSystemType, _MAX_PATH+1)) + { + std::string strRootFileSystemType = szFileSystemType; + std::transform(strRootFileSystemType.begin(), strRootFileSystemType.end(), strRootFileSystemType.begin(), ::toupper); +#if (_WIN32_WINNT >= 0x0500) + if (0 == strRootFileSystemType.compare("NTFS")) + if (TestForMinimumSpecOS()) // Hard links were only available from Win2K onwards + if (0 == DeleteFileA(link_filepath)) + ret = GetLastError(); + else + ret = 0; // 'NO_ERROR' +#endif + } + } + else + ret = 123; // 'ERROR_INVALID_NAME' + } + else + ret = 161; // 'ERROR_BAD_PATHNAME' + + if (ret) + { + SetLastError(ret); + return (-1); + } + else + return (0); +} + +} // namespace PBD + + +//*************************************************************** +// +// dlopen() +// +// Emulates POSIX dlopen() using Win32 LoadLibrary(). +// +// Returns: +// +// On Success: A handle to the opened DLL +// On Failure: NULL +// +LIBPBD_API void* PBD_APICALLTYPE +dlopen (const char *file_name, int mode) +{ + // Note that 'mode' is ignored in Win32 + return(::LoadLibraryA(Glib::locale_from_utf8(file_name).c_str())); +} + + +//*************************************************************** +// +// dlclose() +// +// Emulates POSIX dlclose() using Win32 FreeLibrary(). +// +// Returns: +// +// On Success: A non-zero number +// On Failure: 0 +// +LIBPBD_API int PBD_APICALLTYPE +dlclose (void *handle) +{ + return (::FreeLibrary((HMODULE)handle)); +} + + +//*************************************************************** +// +// dlsym() +// +// Emulates POSIX dlsym() using Win32 GetProcAddress(). +// +// Returns: +// +// On Success: A pointer to the found function or symbol +// On Failure: NULL +// +LIBPBD_API void* PBD_APICALLTYPE +dlsym (void *handle, const char *symbol_name) +{ + // First test for RTLD_DEFAULT and RTLD_NEXT + if ((handle == 0/*RTLD_DEFAULT*/) || (handle == ((void *) -1L)/*RTLD_NEXT*/)) + { + return 0; // Not yet supported for Win32 + } + else + return (::GetProcAddress((HMODULE)handle, symbol_name)); +} + +#define LOCAL_ERROR_BUF_SIZE 1024 +static char szLastWinError[LOCAL_ERROR_BUF_SIZE]; +//*************************************************************** +// +// dlerror() +// +// Emulates POSIX dlerror() using Win32 GetLastError(). +// +// Returns: +// +// On Success: The translated message corresponding to the +// last error +// On Failure: NULL (if the last error was ERROR_SUCCESS) +// +LIBPBD_API char* PBD_APICALLTYPE +dlerror () +{ + DWORD dwLastErrorId = GetLastError(); + if (ERROR_SUCCESS == dwLastErrorId) + return 0; + else + { + if (0 == FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwLastErrorId, + 0, + szLastWinError, + LOCAL_ERROR_BUF_SIZE, + 0)) + { + sprintf(szLastWinError, "Could not decipher the previous error message"); + } + + // POSIX dlerror() seems to reset the + // error system, so emulate that here + SetLastError(ERROR_SUCCESS); + } + + return(szLastWinError); +} + +#endif // COMPILER_MSVC diff --git a/libs/pbd/msvc/msvc_poll.cc b/libs/pbd/msvc/msvc_poll.cc new file mode 100644 index 0000000000..921638a3f5 --- /dev/null +++ b/libs/pbd/msvc/msvc_poll.cc @@ -0,0 +1,215 @@ +/* + 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. + +*/ + +#ifdef COMPILER_MSVC + +//#include <glib/gtimer.h> +#include "pbd/msvc_pbd.h" + +#ifndef _DWORD_DEFINED +#define _DWORD_DEFINED +typedef unsigned long DWORD; +#endif // !_DWORD_DEFINED + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Note that this entire strategy failed to work, at least for pipes. It turned * + * out that Windows 'tell()' always returns 0 when used on a pipe. This strategy * + * is now deprecated, having been replaced by a new pipe-like object, which I've * + * called 'PBD::pipex'. This polling functionality is included here mostly so * + * that Ardour will build and launch under Windows. However, any module that * + * relies on polling a pipe will eventually need to use the new pipex object. * + * This code will allow it to compile and link successfully, although it won't * + * poll successfully at run time. Having said that, these functions might well * + * work for ports and/or other machanisms that get represented by a file handle. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int poll_input (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout) +{ +DWORD dwOldTickCount, + dwNewTickCount = GetTickCount(); +bool input = false, + error = false; +int ret = 0; + + if (NULL != fds) + { + nfds_t loop; + short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND); + + errno = NO_ERROR; + + do + { + dwOldTickCount = dwNewTickCount; + + for (loop=0; loop<nfds; loop++) + fds[loop].revents = 0; + + for (loop=0; (loop<nfds && !error); loop++) + { + if (!(fds[loop].events & ev_mask)) + { + long pos = _tell(fds[loop].fd); + + if (0 > pos) + { + // An error occured ('errno' should have been set by '_tell()') + ret = (-1); + fds[loop].revents = POLLERR; + if (fds[loop].events & POLLRDNORM) + fds[loop].revents |= POLLRDNORM; + if (fds[loop].events & POLLRDBAND) + fds[loop].revents |= POLLRDBAND; + if (fds[loop].events & POLLPRI) + fds[loop].revents |= POLLPRI; + + // Do we want to abort on error? + if (fds[loop].events & POLLERR) + error = true; + } + else if (pos > 0) + { + // Input characters were found for this fd + ret += 1; + if (fds[loop].events & POLLRDNORM) + fds[loop].revents |= POLLRDNORM; + if (fds[loop].events & POLLRDBAND) + fds[loop].revents |= POLLRDBAND; + if (fds[loop].events & POLLPRI) + fds[loop].revents |= POLLPRI; + + // Do we want to abort on input? + if ((fds[loop].events & POLLIN) || + (fds[loop].events & POLLPRI) || + (fds[loop].events & POLLRDNORM) || + (fds[loop].events & POLLRDBAND)) + input = true; + } + } + } + + if (input) + break; + + dwNewTickCount = GetTickCount(); + elapsed_time += (dwNewTickCount-dwOldTickCount); + // Note that the above will wrap round if the user leaves + // his computer powered up for more than about 50 days! + + // Sleep briefly because GetTickCount() only has an accuracy of 10mS + Sleep(10); // For some reason 'g_usleep()' craps over everything here. Different 'C' runtimes??? + + } while ((!error) && ((timeout == (-1)) || (elapsed_time < timeout))); + } + else + { + errno = ERROR_BAD_ARGUMENTS; + ret = (-1); + } + + return (ret); +} + +int poll_output (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout) +{ +int ret = 0; // This functionality is not yet implemented + + if (NULL != fds) + { + // Just flag whichever pollfd was specified for writing + short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND); + + errno = NO_ERROR; + elapsed_time = 0; + + for (nfds_t loop=0; loop<nfds; loop++) + { + if (fds[loop].events & ev_mask) + { + fds[loop].revents = POLLNVAL; + errno = ERROR_INVALID_ACCESS; + ret = (-1); + } + } + } + else + { + errno = ERROR_BAD_ARGUMENTS; + ret = (-1); + } + + return (ret); +} + +//*************************************************************** +// +// poll() +// +// Emulates POSIX poll() using Win32 _tell(). +// +// Returns: +// +// On Success: A positive integer indicating the total number +// of file descriptors that were available for +// writing or had data available for reading. +// On Failure: -1 (the actual error is saved in 'errno'). +// +LIBPBD_API int PBD_APICALLTYPE +poll (struct pollfd *fds, nfds_t nfds, int timeout) +{ +int elapsed_time = 0; +int ret = (-1); + + // Note that this functionality is not fully implemented. + // At the time of writing, Ardour seems only to poll on + // read pipes. Therefore return an error if any write + // pipe seems to have been specified or if too many file + // descriptors were passed. + short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND); + + if ((nfds > OPEN_MAX) || (nfds > NPOLLFILE)) + { + errno = ERROR_TOO_MANY_OPEN_FILES; + } + else + { + ret = 0; + + for (nfds_t loop=0; loop<nfds; loop++) + { + if (fds[loop].events & ev_mask) + { + ret = poll_output(fds, nfds, elapsed_time, timeout); + break; + } + } + + if (0 == ret) + { + // Poll for input + ret = poll_input(fds, nfds, elapsed_time, timeout); + } + } + + return (ret); +} + +#endif //COMPILER_MSVC diff --git a/libs/pbd/pathexpand.cc b/libs/pbd/pathexpand.cc index 4911f12788..5784ec9428 100644 --- a/libs/pbd/pathexpand.cc +++ b/libs/pbd/pathexpand.cc @@ -18,8 +18,10 @@ */ #include <vector> -#include <climits> #include <iostream> +#include <climits> +#include <cerrno> +#include <cstdlib> #include <regex.h> @@ -32,6 +34,22 @@ using std::string; using std::vector; string +PBD::canonical_path (const std::string& path) +{ +#ifdef COMPILER_MINGW + return path; +#else + char buf[PATH_MAX+1]; + + if (!realpath (path.c_str(), buf) && (errno != ENOENT)) { + return path; + } + + return string (buf); +#endif +} + +string PBD::path_expand (string path) { if (path.empty()) { @@ -97,13 +115,7 @@ PBD::path_expand (string path) /* canonicalize */ - char buf[PATH_MAX+1]; - - if (realpath (path.c_str(), buf)) { - return buf; - } else { - return string(); - } + return canonical_path (path); } string diff --git a/libs/pbd/pathscanner.cc b/libs/pbd/pathscanner.cc index fac2dcfd96..b9b501a120 100644 --- a/libs/pbd/pathscanner.cc +++ b/libs/pbd/pathscanner.cc @@ -18,11 +18,19 @@ $Id$ */ +#ifdef COMPILER_MSVC +#include <stdlib.h> +#include <stdio.h> +using PBD::readdir; +using PBD::opendir; +using PBD::closedir; +#else +#include <dirent.h> #include <cstdlib> #include <cstdio> +#endif #include <cstring> #include <vector> -#include <dirent.h> #include <sys/types.h> #include <sys/stat.h> diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index d43bc64f63..67c39b57e4 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -28,6 +28,15 @@ #include "i18n.h" +#ifdef COMPILER_MSVC +#include <ardourext/misc.h> // Needed for 'DECLARE_DEFAULT_COMPARISONS'. Objects in an STL container can be + // searched and sorted. Thus, when instantiating the container, MSVC complains + // if the type of object being contained has no appropriate comparison operators + // defined (specifically, if operators '<' and '==' are undefined). This seems + // to be the case with ptw32 'pthread_t' which is a simple struct. +DECLARE_DEFAULT_COMPARISONS(ptw32_handle_t) +#endif + using namespace std; template<typename RequestBuffer> void @@ -146,7 +155,7 @@ AbstractUI<RequestObject>::get_request (RequestType rt) return 0; } - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated per-thread request of type %2, caller %3\n", name(), rt, pthread_self())); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated per-thread request of type %2, caller %3\n", name(), rt, pthread_name())); vec.buf[0]->type = rt; vec.buf[0]->valid = true; @@ -158,7 +167,7 @@ AbstractUI<RequestObject>::get_request (RequestType rt) * are not at work. */ - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated normal heap request of type %2, caller %3\n", name(), rt, pthread_self())); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated normal heap request of type %2, caller %3\n", name(), rt, pthread_name())); RequestObject* req = new RequestObject; req->type = rt; @@ -213,7 +222,7 @@ AbstractUI<RequestObject>::handle_ui_requests () for (i = request_buffers.begin(); i != request_buffers.end(); ) { if ((*i).second->dead) { DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 deleting dead per-thread request buffer for %3 @ %4\n", - name(), pthread_self(), i->first, i->second)); + name(), pthread_name(), i->second)); delete (*i).second; RequestBufferMapIterator tmp = i; ++tmp; @@ -241,7 +250,7 @@ AbstractUI<RequestObject>::handle_ui_requests () request_buffer_map_lock.lock (); if (!req->valid) { - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", name(), pthread_name(), req->type)); delete req; request_buffer_map_lock.unlock (); continue; @@ -253,7 +262,7 @@ AbstractUI<RequestObject>::handle_ui_requests () */ if (req->invalidation) { - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 remove request from its invalidation list\n", name(), pthread_self())); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 remove request from its invalidation list\n", name(), pthread_name())); /* after this call, if the object referenced by the * invalidation record is deleted, it will no longer @@ -281,7 +290,7 @@ AbstractUI<RequestObject>::handle_ui_requests () lm.release (); - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 execute request type %3\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 execute request type %3\n", name(), pthread_name(), req->type)); /* and lets do it ... this is a virtual call so that each * specific type of UI can have its own set of requests without @@ -290,7 +299,7 @@ AbstractUI<RequestObject>::handle_ui_requests () do_request (req); - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 delete heap request type %3\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 delete heap request type %3\n", name(), pthread_name(), req->type)); delete req; /* re-acquire the list lock so that we check again */ @@ -315,7 +324,7 @@ AbstractUI<RequestObject>::send_request (RequestObject *req) /* the thread that runs this UI's event loop is sending itself a request: we dispatch it immediately and inline. */ - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of request type %3\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of request type %3\n", name(), pthread_name(), req->type)); do_request (req); } else { @@ -334,13 +343,13 @@ AbstractUI<RequestObject>::send_request (RequestObject *req) RequestBuffer* rbuf = per_thread_request_buffer.get (); if (rbuf != 0) { - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send per-thread request type %3\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send per-thread request type %3\n", name(), pthread_name(), req->type)); rbuf->increment_write_ptr (1); } else { /* no per-thread buffer, so just use a list with a lock so that it remains single-reader/single-writer semantics */ - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send heap request type %3\n", name(), pthread_self(), req->type)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send heap request type %3\n", name(), pthread_name(), req->type)); Glib::Threads::Mutex::Lock lm (request_list_lock); request_list.push_back (req); } @@ -349,7 +358,7 @@ AbstractUI<RequestObject>::send_request (RequestObject *req) at the per-thread and generic request lists. */ - request_channel.wakeup (); + signal_new_request (); } } @@ -357,7 +366,7 @@ template<typename RequestObject> void AbstractUI<RequestObject>::call_slot (InvalidationRecord* invalidation, const boost::function<void()>& f) { if (caller_is_self()) { - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of call slot via functor @ %3, invalidation %4\n", name(), pthread_self(), &f, invalidation)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of call slot via functor @ %3, invalidation %4\n", name(), pthread_name(), &f, invalidation)); f (); return; } @@ -368,7 +377,7 @@ AbstractUI<RequestObject>::call_slot (InvalidationRecord* invalidation, const bo return; } - DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 queue call-slot using functor @ %3, invalidation %4\n", name(), pthread_self(), &f, invalidation)); + DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 queue call-slot using functor @ %3, invalidation %4\n", name(), pthread_name(), &f, invalidation)); /* copy semantics: copy the functor into the request object */ diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h index f78ba26090..1ceefe7b3b 100644 --- a/libs/pbd/pbd/abstract_ui.h +++ b/libs/pbd/pbd/abstract_ui.h @@ -52,7 +52,7 @@ class Touchable; template<typename RequestObject> -class ABSTRACT_UI_API AbstractUI : public BaseUI /* see notes in visibility.h about why this is not LIBPBD_API */ +class /*ABSTRACT_UI_API*/ AbstractUI : public BaseUI /* see notes in visibility.h about why this is not LIBPBD_API */ { public: AbstractUI (const std::string& name); @@ -74,8 +74,22 @@ class ABSTRACT_UI_API AbstractUI : public BaseUI /* see notes in visibility.h ab , ui (uir) {} }; typedef typename RequestBuffer::rw_vector RequestBufferVector; + +#if defined(__MINGW32__) + + struct pthread_cmp + { + bool operator() (const ptw32_handle_t& thread1, const ptw32_handle_t& thread2) + { + return thread1.p < thread2.p; + } + }; + typedef typename std::map<pthread_t,RequestBuffer*, pthread_cmp>::iterator RequestBufferMapIterator; + typedef std::map<pthread_t,RequestBuffer*, pthread_cmp> RequestBufferMap; +#else typedef typename std::map<pthread_t,RequestBuffer*>::iterator RequestBufferMapIterator; typedef std::map<pthread_t,RequestBuffer*> RequestBufferMap; +#endif RequestBufferMap request_buffers; static Glib::Threads::Private<RequestBuffer> per_thread_request_buffer; diff --git a/libs/pbd/pbd/atomic_counter.h b/libs/pbd/pbd/atomic_counter.h new file mode 100644 index 0000000000..1e1998e1f1 --- /dev/null +++ b/libs/pbd/pbd/atomic_counter.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2010 Tim Mayberry + + 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 PBD_ATOMIC_COUNTER_H +#define PBD_ATOMIC_COUNTER_H + +#include <glib.h> + +namespace PBD { + +class atomic_counter +{ + /** + * Prevent copying and assignment + */ + atomic_counter (const atomic_counter&); + atomic_counter& operator= (const atomic_counter&); + +public: + + atomic_counter (gint value = 0) + : + m_value(value) + { } + + gint get() const + { + return g_atomic_int_get (&m_value); + } + + void set (gint new_value) + { + g_atomic_int_set (&m_value, new_value); + } + + void increment () + { + g_atomic_int_inc (&m_value); + } + + void operator++ () + { + increment (); + } + + bool decrement_and_test () + { + return g_atomic_int_dec_and_test (&m_value); + } + + bool operator-- () + { + return decrement_and_test (); + } + + bool compare_and_exchange (gint old_value, gint new_value) + { + return g_atomic_int_compare_and_exchange + ( + &m_value, + old_value, + new_value + ); + } + + /** + * convenience method, \see compare_and_exchange + */ + bool cas (gint old_value, gint new_value) + { + return compare_and_exchange (old_value, new_value); + } + +private: + + // Has to be mutable when using the apple version of gcc. + mutable volatile gint m_value; + +}; + +} // namespace PBD + +#endif // PBD_ATOMIC_COUNTER_H diff --git a/libs/pbd/pbd/base_ui.h b/libs/pbd/pbd/base_ui.h index ee2bbf5ee9..ea1afbbb5a 100644 --- a/libs/pbd/pbd/base_ui.h +++ b/libs/pbd/pbd/base_ui.h @@ -72,13 +72,13 @@ class LIBPBD_API BaseUI : public sigc::trackable, public PBD::EventLoop void quit (); protected: - CrossThreadChannel request_channel; bool _ok; Glib::RefPtr<Glib::MainLoop> _main_loop; - Glib::Threads::Thread* run_loop_thread; + Glib::RefPtr<Glib::MainContext> m_context; + Glib::Threads::Thread* run_loop_thread; Glib::Threads::Mutex _run_lock; - Glib::Threads::Cond _running; + Glib::Threads::Cond _running; /* this signals _running from within the event loop, from an idle callback @@ -93,9 +93,17 @@ class LIBPBD_API BaseUI : public sigc::trackable, public PBD::EventLoop virtual void thread_init () {}; +#ifdef PLATFORM_WINDOWS + static gboolean _request_handler (gpointer); + bool request_handler (); +#else /** Called when there input ready on the request_channel */ bool request_handler (Glib::IOCondition); +#endif + + void signal_new_request (); + void attach_request_source (); /** Derived UI objects must implement this method, * which will be called whenever there are requests @@ -106,6 +114,10 @@ class LIBPBD_API BaseUI : public sigc::trackable, public PBD::EventLoop private: std::string _name; BaseUI* base_ui_instance; + +#ifndef PLATFORM_WINDOWS + CrossThreadChannel request_channel; +#endif static uint64_t rt_bit; diff --git a/libs/pbd/pbd/cartesian.h b/libs/pbd/pbd/cartesian.h index 20c8b27088..5f0b951d5f 100644 --- a/libs/pbd/pbd/cartesian.h +++ b/libs/pbd/pbd/cartesian.h @@ -97,7 +97,7 @@ struct LIBPBD_API AngularVector { } }; -LIBPBD_API inline void CartesianVector::angular (AngularVector& a) const { +inline void CartesianVector::angular (AngularVector& a) const { cartesian_to_spherical (x, y, z, a.azi, a.ele, a.length); } diff --git a/libs/pbd/pbd/compose.h b/libs/pbd/pbd/compose.h index a80cb213b2..cb4182699f 100644 --- a/libs/pbd/pbd/compose.h +++ b/libs/pbd/pbd/compose.h @@ -204,7 +204,7 @@ namespace StringPrivate // a series of functions which accept a format string on the form "text %1 // more %2 less %3" and a number of templated parameters and spits out the // composited string - template <typename T1> LIBPBD_API + template <typename T1> inline std::string string_compose(const std::string &fmt, const T1 &o1) { StringPrivate::Composition c(fmt); @@ -212,7 +212,7 @@ namespace StringPrivate return c.str(); } - template <typename T1, typename T2> LIBPBD_API + template <typename T1, typename T2> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2) { @@ -221,7 +221,7 @@ namespace StringPrivate return c.str(); } - template <typename T1, typename T2, typename T3> LIBPBD_API + template <typename T1, typename T2, typename T3> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3) { @@ -230,7 +230,7 @@ namespace StringPrivate return c.str(); } - template <typename T1, typename T2, typename T3, typename T4> LIBPBD_API + template <typename T1, typename T2, typename T3, typename T4> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4) @@ -240,7 +240,7 @@ namespace StringPrivate return c.str(); } - template <typename T1, typename T2, typename T3, typename T4, typename T5> LIBPBD_API + template <typename T1, typename T2, typename T3, typename T4, typename T5> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5) @@ -251,7 +251,7 @@ namespace StringPrivate } template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6> LIBPBD_API + typename T6> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6) @@ -262,7 +262,7 @@ namespace StringPrivate } template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7> LIBPBD_API + typename T6, typename T7> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -274,7 +274,7 @@ namespace StringPrivate } template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8> LIBPBD_API + typename T6, typename T7, typename T8> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -286,7 +286,7 @@ namespace StringPrivate } template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9> LIBPBD_API + typename T6, typename T7, typename T8, typename T9> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -298,7 +298,7 @@ namespace StringPrivate } template <typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9, typename T10> LIBPBD_API + typename T6, typename T7, typename T8, typename T9, typename T10> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -313,7 +313,7 @@ namespace StringPrivate template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, - typename T11> LIBPBD_API + typename T11> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -328,7 +328,7 @@ namespace StringPrivate template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, - typename T11, typename T12> LIBPBD_API + typename T11, typename T12> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -343,7 +343,7 @@ namespace StringPrivate template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, - typename T11, typename T12, typename T13> LIBPBD_API + typename T11, typename T12, typename T13> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -359,7 +359,7 @@ namespace StringPrivate template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, - typename T11, typename T12, typename T13, typename T14> LIBPBD_API + typename T11, typename T12, typename T13, typename T14> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, @@ -376,7 +376,7 @@ namespace StringPrivate template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, - typename T15> LIBPBD_API + typename T15> inline std::string string_compose(const std::string &fmt, const T1 &o1, const T2 &o2, const T3 &o3, const T4 &o4, const T5 &o5, const T6 &o6, diff --git a/libs/pbd/pbd/convert.h b/libs/pbd/pbd/convert.h index 1269254906..6580a6e8e7 100644 --- a/libs/pbd/pbd/convert.h +++ b/libs/pbd/pbd/convert.h @@ -47,7 +47,7 @@ LIBPBD_API std::string length2string (const int64_t frames, const double sample_ LIBPBD_API std::vector<std::string> internationalize (const char *, const char **); LIBPBD_API bool strings_equal_ignore_case (const std::string& a, const std::string& b); -template <class T> std::string LIBPBD_API +template <class T> std::string /*LIBPBD_API*/ to_string (T t, std::ios_base & (*f)(std::ios_base&)) { std::ostringstream oss; diff --git a/libs/pbd/pbd/debug.h b/libs/pbd/pbd/debug.h index dc7e1ce906..54577f1a7e 100644 --- a/libs/pbd/pbd/debug.h +++ b/libs/pbd/pbd/debug.h @@ -45,6 +45,7 @@ namespace PBD { LIBPBD_API extern uint64_t Pool; LIBPBD_API extern uint64_t EventLoop; LIBPBD_API extern uint64_t AbstractUI; + extern uint64_t FileUtils; } } diff --git a/libs/pbd/pbd/demangle.h b/libs/pbd/pbd/demangle.h index c9f5c194c0..12dc58839c 100644 --- a/libs/pbd/pbd/demangle.h +++ b/libs/pbd/pbd/demangle.h @@ -32,7 +32,7 @@ namespace PBD { - template<typename T> LIBPBD_API + template<typename T> /*LIBPBD_API*/ std::string demangled_name (T const & obj) { #ifdef __GNUC__ diff --git a/libs/pbd/pbd/fallback_folders.h b/libs/pbd/pbd/fallback_folders.h new file mode 100644 index 0000000000..db8992db6d --- /dev/null +++ b/libs/pbd/pbd/fallback_folders.h @@ -0,0 +1,62 @@ +/* + 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 __platform_fallback_folders_h__ +#define __platform_fallback_folders_h__ + +#include <pbd/msvc_pbd.h> +#include <glib/gtypes.h> + +#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!! + LIBPBD_API gchar* PBD_APICALLTYPE get_win_special_folder (int csidl); +#endif + +namespace PBD { + + typedef enum fallback_folder_t { + FOLDER_LOCALE, + FOLDER_GTK, + FOLDER_CONFIG, + FOLDER_ARDOUR, + FOLDER_MODULE, + FOLDER_DATA, + FOLDER_ICONS, + FOLDER_PIXMAPS, + FOLDER_CONTROL_SURFACES, + FOLDER_VAMP, + FOLDER_LADSPA, + FOLDER_VST, + FOLDER_BUNDLED_LV2, + FALLBACK_FOLDER_MAX + }; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + LIBPBD_API G_CONST_RETURN gchar* PBD_APICALLTYPE get_platform_fallback_folder (PBD::fallback_folder_t index); + LIBPBD_API G_CONST_RETURN gchar* G_CONST_RETURN * PBD_APICALLTYPE alloc_platform_fallback_folders (); + LIBPBD_API void PBD_APICALLTYPE free_platform_fallback_folders (); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +} // namespace PBD + +#endif /* __platform_fallback_folders_h__ */ diff --git a/libs/pbd/uuid_boost.cc b/libs/pbd/pbd/ffs.h index 1a988b9820..f21fc82a39 100644 --- a/libs/pbd/uuid_boost.cc +++ b/libs/pbd/pbd/ffs.h @@ -1,6 +1,5 @@ /* - Copyright (C) 2008 Paul Davis - Author: Sakari Bergen + Copyright (C) 2013 Tim Mayberry 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 @@ -18,20 +17,13 @@ */ -#include "pbd/uuid.h" +#ifndef __libpbd_ffs_h__ +#define __libpbd_ffs_h__ -using namespace PBD; +#include "pbd/libpbd_visibility.h" -UUID& -UUID::operator= (std::string const & str) -{ - boost::uuids::string_generator gen; - *((boost::uuids::uuid*) this) = gen (str); - return *this; -} +namespace PBD { + LIBPBD_API int ffs(int x); +} -std::string -UUID::to_s () const -{ - return std::string ((const char*) data, size()); -} +#endif /* __libpbd_ffs_h__ */ diff --git a/libs/pbd/pbd/file_utils.h b/libs/pbd/pbd/file_utils.h index 6f8a98b697..01ff8606a7 100644 --- a/libs/pbd/pbd/file_utils.h +++ b/libs/pbd/pbd/file_utils.h @@ -69,15 +69,15 @@ find_matching_files_in_directories (const std::vector<std::string>& directory_pa std::vector<std::string>& result); /** - * Takes a SearchPath and puts a list of all the files in the search path + * Takes a Searchpath and puts a list of all the files in the search path * that match pattern into the result vector. * - * @param search_path A SearchPath + * @param search_path A Searchpath * @param pattern A Glib::PatternSpec used to match the files * @param result A vector in which to place the resulting matches. */ LIBPBD_API void -find_matching_files_in_search_path (const SearchPath& search_path, +find_matching_files_in_search_path (const Searchpath& search_path, const Glib::PatternSpec& pattern, std::vector<std::string>& result); @@ -88,7 +88,7 @@ find_matching_files_in_search_path (const SearchPath& search_path, * @return true If file is found within the search path. */ LIBPBD_API bool -find_file_in_search_path (const SearchPath& search_path, +find_file_in_search_path (const Searchpath& search_path, const std::string& filename, std::string& result); diff --git a/libs/pbd/pbd/floating.h b/libs/pbd/pbd/floating.h index e5d582625a..c0003a3113 100644 --- a/libs/pbd/pbd/floating.h +++ b/libs/pbd/pbd/floating.h @@ -26,13 +26,15 @@ #ifndef __libpbd__floating_h__ #define __libpbd__floating_h__ +#include <stdint.h> + #include <cmath> #include "pbd/libpbd_visibility.h" namespace PBD { -union LIBPBD_API Float_t +union /*LIBPBD_API*/ Float_t { Float_t (float num = 0.0f) : f(num) {} diff --git a/libs/pbd/pbd/functor_command.h b/libs/pbd/pbd/functor_command.h index d2aacd18ac..6cca13209f 100644 --- a/libs/pbd/pbd/functor_command.h +++ b/libs/pbd/pbd/functor_command.h @@ -37,7 +37,7 @@ namespace PBD { template <class obj_type, class arg_type> -class LIBPBD_API FunctorCommand : public Command +class /*LIBPBD_API*/ FunctorCommand : public Command { private: typedef void (obj_type::*functor_type)(arg_type); diff --git a/libs/pbd/pbd/glib_semaphore.h b/libs/pbd/pbd/glib_semaphore.h new file mode 100644 index 0000000000..7f96120d7d --- /dev/null +++ b/libs/pbd/pbd/glib_semaphore.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2010 Tim Mayberry + + 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 PBD_GLIB_SEMAPHORE_H +#define PBD_GLIB_SEMAPHORE_H + +#include <glibmm/threads.h> + +#include "pbd/libpbd_visibility.h" +#include "atomic_counter.h" + +namespace PBD { + +class LIBPBD_API GlibSemaphore +{ + + // prevent copying and assignment + GlibSemaphore(const GlibSemaphore& sema); + GlibSemaphore& operator= (const GlibSemaphore& sema); + +public: + + GlibSemaphore (gint initial_val = 1); + + void wait (); + + bool try_wait (); + + void post (); + +private: + + atomic_counter m_counter; + Glib::Threads::Cond m_cond; + Glib::Threads::Mutex m_mutex; + +}; + +} // namespace PBD + +#endif // PBD_SEMAPHORE_H diff --git a/libs/pbd/pbd/localeguard.h b/libs/pbd/pbd/localeguard.h new file mode 100644 index 0000000000..21ea5380fa --- /dev/null +++ b/libs/pbd/pbd/localeguard.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 1999-2010 Paul Davis + + 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 __pbd_localeguard_h__ +#define __pbd_localeguard_h__ + +#include <string> + +namespace PBD { + +struct LIBPBD_API /* Added by JE - */ LocaleGuard { + LocaleGuard (const char*); + ~LocaleGuard (); + const char* old; + + /* JE - temporary !!!! */static std::string current; +}; + +}; // namespace + +#endif /* __pbd_localeguard_h__ */ diff --git a/libs/pbd/pbd/localtime_r.h b/libs/pbd/pbd/localtime_r.h new file mode 100644 index 0000000000..ad5b89d134 --- /dev/null +++ b/libs/pbd/pbd/localtime_r.h @@ -0,0 +1,13 @@ +#ifndef PBD_LOCALTIME_R +#define PBD_LOCALTIME_R +#include <time.h> + +#ifdef COMPILER_MSVC + #define localtime_r( _clock, _result ) \ + ( *(_result) = *localtime( (_clock) ), \ + (_result) ) +#else + extern struct tm *localtime_r(const time_t *const timep, struct tm *p_tm); +#endif + +#endif diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h index 6560780f3c..f6d11a0b33 100644 --- a/libs/pbd/pbd/memento_command.h +++ b/libs/pbd/pbd/memento_command.h @@ -51,7 +51,7 @@ * can do `just-in-time' binding from the crossfade ID. */ template <class obj_T> -class LIBPBD_API MementoCommandBinder : public PBD::Destructible +class /*LIBPBD_API*/ MementoCommandBinder : public PBD::Destructible { public: /** @return Stateful object to operate on */ @@ -68,7 +68,7 @@ public: /** A simple MementoCommandBinder which binds directly to an object */ template <class obj_T> -class LIBPBD_API SimpleMementoCommandBinder : public MementoCommandBinder<obj_T> +class /*LIBPBD_API*/ SimpleMementoCommandBinder : public MementoCommandBinder<obj_T> { public: SimpleMementoCommandBinder (obj_T& o) @@ -100,7 +100,7 @@ private: * memento, and redo is restoring the after memento. */ template <class obj_T> -class LIBPBD_API MementoCommand : public Command +class /*LIBPBD_API*/ MementoCommand : public Command { public: MementoCommand (obj_T& a_object, XMLNode* a_before, XMLNode* a_after) diff --git a/libs/pbd/pbd/msvc_pbd.h b/libs/pbd/pbd/msvc_pbd.h new file mode 100644 index 0000000000..a623ca2eb2 --- /dev/null +++ b/libs/pbd/pbd/msvc_pbd.h @@ -0,0 +1,256 @@ +/* + 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_pbd_h_ +#define _msvc_pbd_h_ + +#ifdef PBD_IS_IN_WIN_STATIC_LIB // #define if your project uses libpbd (under Windows) as a static library +#undef LIBPBD_DLL +#define PBD_IS_IN_WINDLL 0 +#endif + +#include <pbd/libpbd_visibility.h> + +#ifndef COMPILER_MSVC +#include <sys/time.h> +#else +#include <ardourext/misc.h> +#include <ardourext/sys/time.h> +#endif + +#if !defined(PBD_IS_IN_WINDLL) + #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW) + // If you need '__declspec' compatibility, add extra compilers to the above as necessary + #define PBD_IS_IN_WINDLL 1 + #else + #define PBD_IS_IN_WINDLL 0 + #endif +#endif + +#if PBD_IS_IN_WINDLL && !defined(PBD_APICALLTYPE) + #if defined(BUILDING_PBD) + #define PBD_APICALLTYPE __cdecl + #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point + #define PBD_APICALLTYPE __cdecl + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#elif !defined(PBD_APICALLTYPE) + // Other compilers / platforms could be accommodated here + #define PBD_APICALLTYPE +#ifndef GETOPT_API + #define GETOPT_API + #define GETOPT_APICALLTYPE +#endif +#endif + +#ifndef GETOPT_API + #if defined(BUILDING_GETOPT) + #define GETOPT_API __declspec(dllexport) + #define GETOPT_APICALLTYPE __cdecl + #elif defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MINGW32__) + #define GETOPT_API __declspec(dllimport) + #define GETOPT_APICALLTYPE __cdecl + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#endif // GETOPT_API + +#ifndef _MAX_PATH +#define _MAX_PATH 260 +#endif +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// This function is (hopefully) temporary and is placed here +// because 'g_usleep()' doesn't seem to work very well for glib-win32 +// JE - let's see if we can do without this now! void pbd_g_usleep (unsigned long microseconds); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#ifndef POLLIN +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define NPOLLFILE 64 + +#define POLLRDNORM POLLIN +#define POLLRDBAND POLLIN +#define POLLWRNORM POLLOUT +#define POLLWRBAND POLLOUT +#endif + +#ifdef PLATFORM_WINDOWS + +#ifndef PBDEXTN_API + #if defined(BUILDING_PBDEXTN) + #define PBDEXTN_API __declspec(dllexport) + #define PBDEXTN_APICALLTYPE __cdecl + #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point + #define PBDEXTN_API __declspec(dllimport) + #define PBDEXTN_APICALLTYPE __cdecl + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#endif // PBDEXTN_API + +#ifndef CYGIMPORT_API + #define CYGIMPORT_API __declspec(dllimport) + #define CYGIMPORT_APICALLTYPE __cdecl +#endif // CYGIMPORT_API + +#ifndef __THROW +#define __THROW throw() +#endif + +#ifndef RTLD_DEFAULT +#define RTLD_DEFAULT ((void *) 0) +#define RTLD_NEXT ((void *) -1L) +#define RTLD_LAZY 0x00001 +#define RTLD_NOW 0x00002 +#define RTLD_BINDING_MASK 0x00003 +#define RTLD_NOLOAD 0x00004 +#define RTLD_GLOBAL 0x00004 +#define RTLD_DEEPBIND 0x00008 +#endif + +#ifndef OPEN_MAX +#define OPEN_MAX 32 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +PBDEXTN_API int PBDEXTN_APICALLTYPE cyginit (unsigned int result); +LIBPBD_API int PBD_APICALLTYPE dlclose (void *handle) __THROW; +LIBPBD_API void* PBD_APICALLTYPE dlopen (const char *file_name, int mode) __THROW; +LIBPBD_API void* PBD_APICALLTYPE dlsym (void *handle, const char *symbol_name) __THROW; +LIBPBD_API char* PBD_APICALLTYPE dlerror () __THROW; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#ifndef __CYGWIN__ +/* For whatever reason, Ardour's 'libevoral' refuses to build as a DLL if we include both 'rpc.h' */ +/* and 'WinSock2.h'. It doesn't seem to matter which order we #include them. Given that we can't */ +/* edit 'rpc.h' or 'WinSock2.h', just make sure we don't #include them when building libevoral. */ +#ifndef BUILDING_EVORAL +#include <rpc.h> +typedef int (FAR PBDEXTN_APICALLTYPE *CYGINIT_API)(unsigned int); +#endif +#include <io.h> +#include <sys/types.h> + +#ifndef FILENAME_MAX +#define FILENAME_MAX (260) +#endif + +#ifndef _SSIZE_T_ +#define _SSIZE_T_ +typedef long _ssize_t; + +#ifndef _NO_OLDNAMES +typedef _ssize_t ssize_t; +#endif +#endif /* ! _SSIZE_T_ */ + +struct dirent +{ + long d_ino; // Always zero + unsigned short d_reclen; // Always zero + unsigned short d_namlen; // Length of name in d_name + char d_name[FILENAME_MAX]; // File name +}; + +// This is an internal data structure. Do not use it +// except as an argument to one of the functions below. +typedef struct +{ + // Disk transfer area for this dir + struct _finddata_t dd_dta; + + // 'dirent' struct to return from dir (NOTE: this + // is not thread safe). + struct dirent dd_dir; + + // '_findnext()' handle + long dd_handle; + + // Current status of search: + // 0 = not started yet (next entry to read is first entry) + // -1 = off the end + // Otherwise - positive (0 based) index of next entry + int dd_stat; + + // Full path for dir with search pattern (struct will be extended) + char dd_name[1]; +} DIR; + +struct pollfd +{ + int fd; + short events; + short revents; +}; + +typedef unsigned int nfds_t; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +LIBPBD_API int __cdecl gettimeofday(struct timeval *__restrict tv, __timezone_ptr_t tz); +LIBPBD_API ssize_t PBD_APICALLTYPE pread(int handle, void *buf, size_t nbytes, off_t offset); +LIBPBD_API ssize_t PBD_APICALLTYPE pwrite(int handle, const void *buf, size_t nbytes, off_t offset); +LIBPBD_API int PBD_APICALLTYPE poll(struct pollfd *fds, nfds_t nfds, int timeout); +LIBPBD_API double PBD_APICALLTYPE round(double x); + +namespace PBD { + +LIBPBD_API bool PBD_APICALLTYPE TestForMinimumSpecOS(char *revision="currently ignored"); +LIBPBD_API char* PBD_APICALLTYPE realpath (const char *original_path, char resolved_path[_MAX_PATH+1]); +LIBPBD_API int PBD_APICALLTYPE mkstemp (char *template_name); +LIBPBD_API int PBD_APICALLTYPE ntfs_link (const char *existing_filepath, const char *link_filepath); +LIBPBD_API int PBD_APICALLTYPE ntfs_unlink (const char *link_filepath); + +// These are used to replicate 'dirent.h' functionality +LIBPBD_API DIR* PBD_APICALLTYPE opendir (const char *szPath); +LIBPBD_API struct dirent* PBD_APICALLTYPE readdir (DIR *pDir); +LIBPBD_API int PBD_APICALLTYPE closedir (DIR *pDir); + +} // namespace PBD + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif // !__CYGWIN__ +#endif // PLATFORM_WINDOWS +#endif // _msvc_pbd_h_ diff --git a/libs/pbd/pbd/pathexpand.h b/libs/pbd/pbd/pathexpand.h index 5f1c03f8ee..5c5d4cf772 100644 --- a/libs/pbd/pbd/pathexpand.h +++ b/libs/pbd/pbd/pathexpand.h @@ -24,6 +24,7 @@ #include "pbd/libpbd_visibility.h" namespace PBD { + LIBPBD_API std::string canonical_path (const std::string& path); LIBPBD_API std::string path_expand (std::string path); LIBPBD_API std::string search_path_expand (std::string path); } diff --git a/libs/pbd/pbd/pathscanner.h b/libs/pbd/pbd/pathscanner.h index ef6499c759..d62203c008 100644 --- a/libs/pbd/pbd/pathscanner.h +++ b/libs/pbd/pbd/pathscanner.h @@ -22,7 +22,11 @@ #include <vector> #include <string> +#ifdef COMPILER_MSVC +#include <ardourext/misc.h> +#else #include <regex.h> +#endif #include "pbd/libpbd_visibility.h" diff --git a/libs/pbd/pbd/properties.h b/libs/pbd/pbd/properties.h index 27a0be1895..70d18db4c7 100644 --- a/libs/pbd/pbd/properties.h +++ b/libs/pbd/pbd/properties.h @@ -37,7 +37,7 @@ namespace PBD { /** Parent class for classes which represent a single scalar property in a Stateful object */ template<class T> -class LIBPBD_API PropertyTemplate : public PropertyBase +class /*LIBPBD_API*/ PropertyTemplate : public PropertyBase { public: PropertyTemplate (PropertyDescriptor<T> p, T const& v) @@ -197,7 +197,7 @@ private: PropertyTemplate (PropertyTemplate<T> const &); }; -template<class T> LIBPBD_API +template<class T> /*LIBPBD_API*/ std::ostream & operator<<(std::ostream& os, PropertyTemplate<T> const& s) { return os << s.val (); @@ -207,7 +207,7 @@ std::ostream & operator<<(std::ostream& os, PropertyTemplate<T> const& s) * with types that can be written to / read from stringstreams. */ template<class T> -class LIBPBD_API Property : public PropertyTemplate<T> +class /*LIBPBD_API*/ Property : public PropertyTemplate<T> { public: Property (PropertyDescriptor<T> q, T const& v) @@ -285,7 +285,7 @@ private: * separators, etc. */ template<> -class LIBPBD_API Property<std::string> : public PropertyTemplate<std::string> +class /*LIBPBD_API*/ Property<std::string> : public PropertyTemplate<std::string> { public: Property (PropertyDescriptor<std::string> d, std::string const & v) @@ -319,7 +319,7 @@ private: }; template<class T> -class LIBPBD_API EnumProperty : public Property<T> +class /*LIBPBD_API*/ EnumProperty : public Property<T> { public: EnumProperty (PropertyDescriptor<T> q, T const& v) @@ -352,7 +352,7 @@ private: * one. */ template <class T> -class LIBPBD_API SharedStatefulProperty : public PropertyBase +class /*LIBPBD_API*/ SharedStatefulProperty : public PropertyBase { public: typedef boost::shared_ptr<T> Ptr; diff --git a/libs/pbd/pbd/property_basics.h b/libs/pbd/pbd/property_basics.h index 2da21ddb84..d0eb1db922 100644 --- a/libs/pbd/pbd/property_basics.h +++ b/libs/pbd/pbd/property_basics.h @@ -38,7 +38,7 @@ class LIBPBD_API StatefulDiffCommand; typedef GQuark PropertyID; template<typename T> -struct LIBPBD_API PropertyDescriptor { +struct /*LIBPBD_API*/ PropertyDescriptor { PropertyDescriptor () : property_id (0) {} PropertyDescriptor (PropertyID pid) : property_id (pid) {} @@ -47,16 +47,17 @@ struct LIBPBD_API PropertyDescriptor { }; /** A list of IDs of Properties that have changed in some situation or other */ -class LIBPBD_API PropertyChange : public std::set<PropertyID> +class /*LIBPBD_API*/ PropertyChange : public std::set<PropertyID> { public: - PropertyChange() {} + LIBPBD_API PropertyChange() {} + LIBPBD_API ~PropertyChange() {} template<typename T> PropertyChange(PropertyDescriptor<T> p); - PropertyChange(const PropertyChange& other) : std::set<PropertyID> (other) {} + LIBPBD_API PropertyChange(const PropertyChange& other) : std::set<PropertyID> (other) {} - PropertyChange operator=(const PropertyChange& other) { + LIBPBD_API PropertyChange operator=(const PropertyChange& other) { clear (); insert (other.begin (), other.end ()); return *this; @@ -65,7 +66,7 @@ public: template<typename T> PropertyChange operator=(PropertyDescriptor<T> p); template<typename T> bool contains (PropertyDescriptor<T> p) const; - bool contains (const PropertyChange& other) const { + LIBPBD_API bool contains (const PropertyChange& other) const { for (const_iterator x = other.begin (); x != other.end (); ++x) { if (find (*x) != end ()) { return true; @@ -74,8 +75,8 @@ public: return false; } - void add (PropertyID id) { insert (id); } - void add (const PropertyChange& other) { insert (other.begin (), other.end ()); } + LIBPBD_API void add (PropertyID id) { insert (id); } + LIBPBD_API void add (const PropertyChange& other) { insert (other.begin (), other.end ()); } template<typename T> void add (PropertyDescriptor<T> p); }; diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h index c66feb73a5..37ce723715 100644 --- a/libs/pbd/pbd/pthread_utils.h +++ b/libs/pbd/pbd/pthread_utils.h @@ -20,7 +20,11 @@ #ifndef __pbd_pthread_utils__ #define __pbd_pthread_utils__ +#ifdef COMPILER_MSVC +#include <ardourext/pthread.h> +#else #include <pthread.h> +#endif #include <signal.h> #include <string> #include <stdint.h> diff --git a/libs/pbd/pbd/rcu.h b/libs/pbd/pbd/rcu.h index 6ee68afabf..eceec24cd5 100644 --- a/libs/pbd/pbd/rcu.h +++ b/libs/pbd/pbd/rcu.h @@ -45,7 +45,7 @@ and managed object. */ template<class T> -class LIBPBD_API RCUManager +class /*LIBPBD_API*/ RCUManager { public: @@ -111,7 +111,7 @@ class LIBPBD_API RCUManager means that no actual objects will be deleted incorrectly if this is misused. */ template<class T> -class LIBPBD_API SerializedRCUManager : public RCUManager<T> +class /*LIBPBD_API*/ SerializedRCUManager : public RCUManager<T> { public: @@ -214,7 +214,7 @@ private: */ template<class T> -class LIBPBD_API RCUWriter +class /*LIBPBD_API*/ RCUWriter { public: diff --git a/libs/pbd/pbd/resource.h b/libs/pbd/pbd/resource.h new file mode 100644 index 0000000000..ec826e4930 --- /dev/null +++ b/libs/pbd/pbd/resource.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2011 Tim Mayberry + + 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. + +*/ + +#include <stdint.h> + +namespace PBD { + +typedef uint64_t rlimit_t; + +enum ResourceType { + OpenFiles +}; + +struct ResourceLimit +{ + rlimit_t current_limit; + rlimit_t max_limit; +}; + +/** + * @return true on success, false on error + */ +bool +get_resource_limit (ResourceType resource, ResourceLimit& limit); + +/** + * @return true on success, false on error + */ +bool +set_resource_limit (ResourceType resource, const ResourceLimit& limit); + + +} // namespace PBD diff --git a/libs/pbd/pbd/ringbuffer.h b/libs/pbd/pbd/ringbuffer.h index bb2b8244f9..e3cec6adf1 100644 --- a/libs/pbd/pbd/ringbuffer.h +++ b/libs/pbd/pbd/ringbuffer.h @@ -26,7 +26,7 @@ #include "pbd/libpbd_visibility.h" template<class T> -class LIBPBD_API RingBuffer +class /*LIBPBD_API*/ RingBuffer { public: RingBuffer (guint sz) { @@ -120,7 +120,7 @@ class LIBPBD_API RingBuffer guint size_mask; }; -template<class T> LIBPBD_API guint +template<class T> /*LIBPBD_API*/ guint RingBuffer<T>::read (T *dest, guint cnt) { guint free_cnt; @@ -159,7 +159,7 @@ RingBuffer<T>::read (T *dest, guint cnt) return to_read; } -template<class T> LIBPBD_API guint +template<class T> /*LIBPBD_API*/ guint RingBuffer<T>::write (T const *src, guint cnt) { @@ -199,8 +199,8 @@ RingBuffer<T>::write (T const *src, guint cnt) return to_write; } -template<class T> LIBPBD_API void -RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec) +template<class T> /*LIBPBD_API*/ void +RingBuffer<T>::get_read_vector (typename RingBuffer<T>::rw_vector *vec) { guint free_cnt; @@ -240,8 +240,8 @@ RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec) } } -template<class T> LIBPBD_API void -RingBuffer<T>::get_write_vector (RingBuffer<T>::rw_vector *vec) +template<class T> /*LIBPBD_API*/ void +RingBuffer<T>::get_write_vector (typename RingBuffer<T>::rw_vector *vec) { guint free_cnt; diff --git a/libs/pbd/pbd/ringbufferNPT.h b/libs/pbd/pbd/ringbufferNPT.h index 65fe939597..cd17299961 100644 --- a/libs/pbd/pbd/ringbufferNPT.h +++ b/libs/pbd/pbd/ringbufferNPT.h @@ -32,7 +32,7 @@ namespace PBD { /* ringbuffer class where the element size is not required to be a power of two */ template<class T> -class LIBPBD_API RingBufferNPT +class /*LIBPBD_API*/ RingBufferNPT { public: RingBufferNPT (size_t sz) { @@ -120,7 +120,7 @@ class LIBPBD_API RingBufferNPT mutable gint read_ptr; }; -template<class T> LIBPBD_API size_t +template<class T> /*LIBPBD_API*/ size_t RingBufferNPT<T>::read (T *dest, size_t cnt) { size_t free_cnt; @@ -159,7 +159,7 @@ RingBufferNPT<T>::read (T *dest, size_t cnt) return to_read; } -template<class T> LIBPBD_API size_t +template<class T> /*LIBPBD_API*/ size_t RingBufferNPT<T>::write (const T *src, size_t cnt) { size_t free_cnt; @@ -198,8 +198,8 @@ RingBufferNPT<T>::write (const T *src, size_t cnt) return to_write; } -template<class T> LIBPBD_API void -RingBufferNPT<T>::get_read_vector (RingBufferNPT<T>::rw_vector *vec) +template<class T> /*LIBPBD_API*/ void +RingBufferNPT<T>::get_read_vector (typename RingBufferNPT<T>::rw_vector *vec) { size_t free_cnt; size_t cnt2; @@ -238,8 +238,8 @@ RingBufferNPT<T>::get_read_vector (RingBufferNPT<T>::rw_vector *vec) } } -template<class T> LIBPBD_API void -RingBufferNPT<T>::get_write_vector (RingBufferNPT<T>::rw_vector *vec) +template<class T> /*LIBPBD_API*/ void +RingBufferNPT<T>::get_write_vector (typename RingBufferNPT<T>::rw_vector *vec) { size_t free_cnt; size_t cnt2; diff --git a/libs/pbd/pbd/search_path.h b/libs/pbd/pbd/search_path.h index ad0b6c75d5..909bffb0a4 100644 --- a/libs/pbd/pbd/search_path.h +++ b/libs/pbd/pbd/search_path.h @@ -17,8 +17,8 @@ */ -#ifndef PBD_SEARCH_PATH_INCLUDED -#define PBD_SEARCH_PATH_INCLUDED +#ifndef __libpbd_search_path_h__ +#define __libpbd_search_path_h__ #include <string> #include <vector> @@ -28,26 +28,26 @@ namespace PBD { /** - * @class SearchPath + * @class Searchpath * - * The SearchPath class is a helper class for getting a + * The Searchpath class is a helper class for getting a * vector of paths contained in a search path string where a * "search path string" contains absolute directory paths * separated by a colon(:) or a semi-colon(;) on windows. * - * The SearchPath class does not test whether the paths exist + * The Searchpath class does not test whether the paths exist * or are directories. It is basically just a container. */ -class LIBPBD_API SearchPath : public std::vector<std::string> +class /*LIBPBD_API*/ Searchpath : public std::vector<std::string> { public: /** - * Create an empty SearchPath. + * Create an empty Searchpath. */ - SearchPath (); + LIBPBD_API Searchpath (); /** - * Initialize SearchPath from a string where the string contains + * Initialize Searchpath from a string where the string contains * one or more absolute paths to directories which are delimited * by a path separation character. The path delimeter is a * colon(:) on unix and a semi-colon(;) on windows. @@ -57,15 +57,17 @@ public: * * @param search_path A path string. */ - SearchPath (const std::string& search_path); + LIBPBD_API Searchpath (const std::string& search_path); /** - * Initialize SearchPath from a vector of paths that may or may + * Initialize Searchpath from a vector of paths that may or may * not exist. * * @param paths A vector of paths. */ - SearchPath (const std::vector<std::string>& paths); + LIBPBD_API Searchpath (const std::vector<std::string>& paths); + + LIBPBD_API ~Searchpath () {}; /** * @return a search path string. @@ -73,41 +75,41 @@ public: * The string that is returned contains the platform specific * path separator. */ - const std::string to_string () const; + LIBPBD_API const std::string to_string () const; /** * Add all the directories in path to this. */ - SearchPath& operator+= (const SearchPath& spath); + LIBPBD_API Searchpath& operator+= (const Searchpath& spath); /** * Add another directory path to the search path. */ - SearchPath& operator+= (const std::string& directory_path); + LIBPBD_API Searchpath& operator+= (const std::string& directory_path); /** - * Concatenate another SearchPath onto this. + * Concatenate another Searchpath onto this. */ - SearchPath& operator+ (const SearchPath& other); + LIBPBD_API Searchpath& operator+ (const Searchpath& other); /** * Add another path to the search path. */ - SearchPath& operator+ (const std::string& directory_path); + LIBPBD_API Searchpath& operator+ (const std::string& directory_path); /** * Add a sub-directory to each path in the search path. * @param subdir The directory name, it should not contain * any path separating tokens. */ - SearchPath& add_subdirectory_to_paths (const std::string& subdir); + LIBPBD_API Searchpath& add_subdirectory_to_paths (const std::string& subdir); protected: - void add_directory (const std::string& directory_path); - void add_directories (const std::vector<std::string>& paths); + LIBPBD_API void add_directory (const std::string& directory_path); + LIBPBD_API void add_directories (const std::vector<std::string>& paths); }; } // namespace PBD -#endif +#endif /* __libpbd_search_path_h__ */ diff --git a/libs/pbd/pbd/semaphore.h b/libs/pbd/pbd/semaphore.h index a2390f5a18..265a219e07 100644 --- a/libs/pbd/pbd/semaphore.h +++ b/libs/pbd/pbd/semaphore.h @@ -22,8 +22,11 @@ #ifdef __APPLE__ # include <mach/mach.h> -#elif defined(_WIN32) +#elif defined(PLATFORM_WINDOWS) # include <windows.h> +#ifndef INFINITE +#define INFINITE 0xffffffffL +#endif #else # include <semaphore.h> # include <errno.h> @@ -46,7 +49,7 @@ namespace PBD { only safe way to reliably signal from a real-time audio thread. The counting semantics also complement ringbuffers of events nicely. */ -class LIBPBD_API Semaphore +class /*LIBPBD_API*/ Semaphore { public: /** @@ -70,7 +73,7 @@ public: private: #if defined(__APPLE__) semaphore_t _sem; // sem_t is a worthless broken mess on OSX -#elif defined(_WIN32) +#elif defined(PLATFORM_WINDOWS) HANDLE _sem; // types are overrated anyway #else sem_t _sem; @@ -115,7 +118,7 @@ Semaphore::try_wait() return semaphore_timedwait(_sem, zero) == KERN_SUCCESS; } -#elif defined(_WIN32) +#elif defined(PLATFORM_WINDOWS) inline Semaphore::Semaphore(unsigned initial) @@ -152,7 +155,7 @@ Semaphore::try_wait() return WaitForSingleObject(_sem, 0) == WAIT_OBJECT_0; } -#else /* !defined(__APPLE__) && !defined(_WIN32) */ +#else /* !defined(__APPLE__) && !defined(PLATFORM_WINDOWS) */ Semaphore::Semaphore(unsigned initial) { diff --git a/libs/pbd/pbd/semutils.h b/libs/pbd/pbd/semutils.h index 719a3d0f46..5c0191e25b 100644 --- a/libs/pbd/pbd/semutils.h +++ b/libs/pbd/pbd/semutils.h @@ -19,7 +19,11 @@ #ifndef __pbd_semutils_h__ #define __pbd_semutils_h__ +#ifdef PLATFORM_WINDOWS +#include <windows.h> +#else #include <semaphore.h> +#endif #include "pbd/libpbd_visibility.h" @@ -27,7 +31,10 @@ namespace PBD { class LIBPBD_API ProcessSemaphore { private: -#ifdef __APPLE__ +#ifdef PLATFORM_WINDOWS + HANDLE _sem; + +#elif __APPLE__ sem_t* _sem; sem_t* ptr_to_sem() const { return _sem; } #else @@ -39,8 +46,15 @@ class LIBPBD_API ProcessSemaphore { ProcessSemaphore (const char* name, int val); ~ProcessSemaphore (); +#ifdef PLATFORM_WINDOWS + + int signal (); + int wait (); + +#else int signal () { return sem_post (ptr_to_sem()); } int wait () { return sem_wait (ptr_to_sem()); } +#endif }; } diff --git a/libs/pbd/pbd/sequence_property.h b/libs/pbd/pbd/sequence_property.h index 28775b5f3c..e105e82e47 100644 --- a/libs/pbd/pbd/sequence_property.h +++ b/libs/pbd/pbd/sequence_property.h @@ -44,7 +44,7 @@ namespace PBD { * any change. */ template<typename Container> -class LIBPBD_API SequenceProperty : public PropertyBase +class /*LIBPBD_API*/ SequenceProperty : public PropertyBase { public: typedef std::set<typename Container::value_type> ChangeContainer; @@ -95,14 +95,14 @@ class LIBPBD_API SequenceProperty : public PropertyBase /* record the change described in our change member */ if (!_changes.added.empty()) { - for (typename ChangeContainer::iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) { + for (typename ChangeContainer::const_iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) { XMLNode* add_node = new XMLNode ("Add"); child->add_child_nocopy (*add_node); get_content_as_xml (*i, *add_node); } } if (!_changes.removed.empty()) { - for (typename ChangeContainer::iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) { + for (typename ChangeContainer::const_iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) { XMLNode* remove_node = new XMLNode ("Remove"); child->add_child_nocopy (*remove_node); get_content_as_xml (*i, *remove_node); @@ -171,7 +171,7 @@ class LIBPBD_API SequenceProperty : public PropertyBase with this diff(). */ - for (typename ChangeContainer::iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) { + for (typename ChangeContainer::const_iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) { (*i)->DropReferences.connect_same_thread (*cmd, boost::bind (&Destructible::drop_references, cmd)); } } @@ -311,10 +311,10 @@ class LIBPBD_API SequenceProperty : public PropertyBase } Container& operator= (const Container& other) { - for (typename Container::iterator i = _val.begin(); i != _val.end(); ++i) { + for (typename Container::const_iterator i = _val.begin(); i != _val.end(); ++i) { _changes.remove (*i); } - for (typename Container::iterator i = other.begin(); i != other.end(); ++i) { + for (typename Container::const_iterator i = other.begin(); i != other.end(); ++i) { _changes.add (*i); } return _val = other; diff --git a/libs/pbd/pbd/signals.h b/libs/pbd/pbd/signals.h index 3896fd55b5..672dc66850 100644 --- a/libs/pbd/pbd/signals.h +++ b/libs/pbd/pbd/signals.h @@ -79,7 +79,7 @@ private: }; template<typename R> -class LIBPBD_API OptionalLastValue +class /*LIBPBD_API*/ OptionalLastValue { public: typedef boost::optional<R> result_type; diff --git a/libs/pbd/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h index fbb92c8fa0..c5d9743b1e 100644 --- a/libs/pbd/pbd/stacktrace.h +++ b/libs/pbd/pbd/stacktrace.h @@ -44,7 +44,7 @@ namespace PBD { LIBPBD_API std::string demangle (const std::string&); template<typename T> -class LIBPBD_API thing_with_backtrace +class /*LIBPBD_API*/ thing_with_backtrace { public: thing_with_backtrace () { @@ -113,11 +113,11 @@ private: static Glib::Threads::Mutex all_mutex; }; -template<typename T> LIBPBD_API std::list<PBD::thing_with_backtrace<T> *> PBD::thing_with_backtrace<T>::all; -template<typename T> LIBPBD_API Glib::Threads::Mutex PBD::thing_with_backtrace<T>::all_mutex; +template<typename T> /*LIBPBD_API*/ std::list<PBD::thing_with_backtrace<T> *> PBD::thing_with_backtrace<T>::all; +template<typename T> /*LIBPBD_API*/ Glib::Threads::Mutex PBD::thing_with_backtrace<T>::all_mutex; } // namespace PBD - +// JE - !!!!#include "../pbd/stacktrace.impl" #endif /* __libpbd_stacktrace_h__ */ diff --git a/libs/pbd/pbd/stl_delete.h b/libs/pbd/pbd/stl_delete.h index b98bb5e8e3..1598a90e2c 100644 --- a/libs/pbd/pbd/stl_delete.h +++ b/libs/pbd/pbd/stl_delete.h @@ -26,7 +26,7 @@ first include the revelant container type header. */ #if defined(_CPP_VECTOR) || defined(_GLIBCXX_VECTOR) || defined(__SGI_STL_VECTOR) || defined(_LIBCPP_VECTOR) -template<class T> LIBPBD_API void vector_delete (std::vector<T *> *vec) +template<class T> /*LIBPBD_API*/ void vector_delete (std::vector<T *> *vec) { typename std::vector<T *>::iterator i; @@ -38,7 +38,7 @@ template<class T> LIBPBD_API void vector_delete (std::vector<T *> *vec) #endif // _CPP_VECTOR || _GLIBCXX_VECTOR || __SGI_STL_VECTOR || _LIBCPP_VECTOR #if defined(_CPP_MAP) || defined(_GLIBCXX_MAP) || defined(__SGI_STL_MAP) -template<class K, class T> LIBPBD_API void map_delete (std::map<K, T *> *m) +template<class K, class T> /*LIBPBD_API*/ void map_delete (std::map<K, T *> *m) { typename std::map<K, T *>::iterator i; @@ -50,7 +50,7 @@ template<class K, class T> LIBPBD_API void map_delete (std::map<K, T *> *m) #endif // _CPP_MAP || _GLIBCXX_MAP || __SGI_STL_MAP #if defined(_CPP_LIST) || defined(_GLIBCXX_LIST) || defined(__SGI_STL_LIST) -template<class T> LIBPBD_API void list_delete (std::list<T *> *l) +template<class T> /*LIBPBD_API*/ void list_delete (std::list<T *> *l) { typename std::list<T *>::iterator i; @@ -63,7 +63,7 @@ template<class T> LIBPBD_API void list_delete (std::list<T *> *l) #endif // _CPP_LIST || _GLIBCXX_LIST || __SGI_STL_LIST #if defined(_CPP_SLIST) || defined(_GLIBCXX_SLIST) || defined(__SGI_STL_SLIST) -template<class T> LIBPBD_API void slist_delete (std::slist<T *> *l) +template<class T> /*LIBPBD_API*/ void slist_delete (std::slist<T *> *l) { typename std::slist<T *>::iterator i; @@ -76,7 +76,7 @@ template<class T> LIBPBD_API void slist_delete (std::slist<T *> *l) #endif // _CPP_SLIST || _GLIBCXX_SLIST || __SGI_STL_SLIST #if defined(_CPP_SET) || defined(_GLIBCXX_SET) || defined(__SGI_STL_SET) -template<class T> void LIBPBD_API set_delete (std::set<T *> *sset) +template<class T> void /*LIBPBD_API*/ set_delete (std::set<T *> *sset) { typename std::set<T *>::iterator i; diff --git a/libs/pbd/pbd/timersub.h b/libs/pbd/pbd/timersub.h new file mode 100644 index 0000000000..6cb152414c --- /dev/null +++ b/libs/pbd/pbd/timersub.h @@ -0,0 +1,32 @@ +/* Copyright (C) 1991-1994,1996-2003,2005,2006,2009 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sys/time.h> + +#ifndef timersub +# define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + diff --git a/libs/pbd/pbd/tokenizer.h b/libs/pbd/pbd/tokenizer.h index b4b3b107c0..3253473519 100644 --- a/libs/pbd/pbd/tokenizer.h +++ b/libs/pbd/pbd/tokenizer.h @@ -37,7 +37,7 @@ namespace PBD { are discarded. */ template<typename StringType, typename Iter> -LIBPBD_API unsigned int +/*LIBPBD_API*/ unsigned int tokenize(const StringType& str, const StringType& delims, Iter it, diff --git a/libs/pbd/pbd/touchable.h b/libs/pbd/pbd/touchable.h index ed7d75df52..297be8b0f1 100644 --- a/libs/pbd/pbd/touchable.h +++ b/libs/pbd/pbd/touchable.h @@ -21,7 +21,7 @@ #include "pbd/libpbd_visibility.h" -class LIBPBD_API Touchable +class /*LIBPBD_API*/ Touchable { public: Touchable() : _delete_after_touch (false) {} @@ -37,7 +37,7 @@ class LIBPBD_API Touchable }; template<class T> -class LIBPBD_API DynamicTouchable : public Touchable +class /*LIBPBD_API*/ DynamicTouchable : public Touchable { public: DynamicTouchable (T& t, void (T::*m)(void)) @@ -53,7 +53,7 @@ class LIBPBD_API DynamicTouchable : public Touchable }; template<class T1, class T2> -class LIBPBD_API DynamicTouchable1 : public Touchable +class /*LIBPBD_API*/ DynamicTouchable1 : public Touchable { public: DynamicTouchable1 (T1& t, void (T1::*m)(T2), T2 a) @@ -70,7 +70,7 @@ class LIBPBD_API DynamicTouchable1 : public Touchable }; template<class T1, class T2, class T3> -class LIBPBD_API DynamicTouchable2 : public Touchable +class /*LIBPBD_API*/ DynamicTouchable2 : public Touchable { public: DynamicTouchable2 (T1& t, void (T1::*m)(T2, T3), T2 a1, T3 a2) diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h index 753bc13b15..794e68ce97 100644 --- a/libs/pbd/pbd/undo.h +++ b/libs/pbd/pbd/undo.h @@ -25,7 +25,11 @@ #include <map> #include <sigc++/slot.h> #include <sigc++/bind.h> +#ifndef COMPILER_MSVC #include <sys/time.h> +#else +#include <ardourext/misc.h> +#endif #include "pbd/libpbd_visibility.h" #include "pbd/command.h" diff --git a/libs/pbd/pbd/unknown_type.h b/libs/pbd/pbd/unknown_type.h index 4d984269a7..ef9db1ac43 100644 --- a/libs/pbd/pbd/unknown_type.h +++ b/libs/pbd/pbd/unknown_type.h @@ -22,9 +22,9 @@ #include <exception> -#include "pbd/libpbd_visibility.h" +//#include "pbd/libpbd_visibility.h" -class LIBPBD_API unknown_type : public std::exception { +class /*LIBPBD_API*/ unknown_type : public std::exception { public: virtual const char *what() const throw() { return "unknown type"; } }; diff --git a/libs/pbd/pbd/unwind.h b/libs/pbd/pbd/unwind.h index cf7998fdd4..5a0fe26559 100644 --- a/libs/pbd/pbd/unwind.h +++ b/libs/pbd/pbd/unwind.h @@ -25,7 +25,7 @@ namespace PBD { template <typename T> -class LIBPBD_API Unwinder { +class /*LIBPBD_API*/ Unwinder { public: Unwinder (T& var, T new_val) : _var (var), _old_val (var) { var = new_val; } ~Unwinder () { _var = _old_val; } diff --git a/libs/pbd/pbd/uuid.h b/libs/pbd/pbd/uuid.h index 333a902b4d..77e84c5f09 100644 --- a/libs/pbd/pbd/uuid.h +++ b/libs/pbd/pbd/uuid.h @@ -22,31 +22,37 @@ #define __pbd_uuid_h__ #include <string> -#include <uuid/uuid.h> +#include <boost/uuid/uuid.hpp> +#include <boost/uuid/uuid_generators.hpp> #include "pbd/libpbd_visibility.h" namespace PBD { -class LIBPBD_API UUID { +class LIBPBD_API UUID : public boost::uuids::uuid { public: - UUID () { uuid_generate (id); } - UUID (UUID const & other) { uuid_copy (id, other.id); } - UUID (std::string const & str) { uuid_parse (str.c_str(), id); } - - UUID& operator= (std::string const & str); - std::string to_s () const; - - bool operator== (UUID const & other) const { return !uuid_compare (id, other.id); } - bool operator!= (UUID const & other) const { return uuid_compare (id, other.id); } - bool operator< (UUID const & other) const { return uuid_compare (id, other.id) < 0; } - - operator bool() const { return !uuid_is_null (id); } - - private: - uuid_t id; + UUID () + : boost::uuids::uuid (boost::uuids::random_generator()()) {} + UUID (std::string const & str) + : boost::uuids::uuid (boost::uuids::string_generator()(str)) {} + explicit UUID (boost::uuids::uuid const& u) + : boost::uuids::uuid(u) + {} + + operator boost::uuids::uuid() { + return static_cast<boost::uuids::uuid&>(*this); + } + + operator boost::uuids::uuid() const { + return static_cast<boost::uuids::uuid const&>(*this); + } + + UUID& operator= (std::string const & str); + std::string to_s () const; + + operator bool() const { return !is_nil(); } }; } // namespace PBD diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc index 7b24625727..cdcd9abdd7 100644 --- a/libs/pbd/pool.cc +++ b/libs/pbd/pool.cc @@ -24,6 +24,7 @@ #include <cassert> #include "pbd/pool.h" +#include "pbd/pthread_utils.h" #include "pbd/error.h" #include "pbd/debug.h" #include "pbd/compose.h" @@ -182,7 +183,7 @@ PerThreadPool::per_thread_pool () { CrossThreadPool* p = _key.get(); if (!p) { - fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_self() << endmsg; + fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_name() << endmsg; /*NOTREACHED*/ } return p; @@ -226,9 +227,9 @@ CrossThreadPool::alloc () { void* ptr; - DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 has %3 pending free entries waiting\n", pthread_self(), name(), pending.read_space())); + DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 has %3 pending free entries waiting\n", pthread_name(), name(), pending.read_space())); while (pending.read (&ptr, 1) == 1) { - DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 pushes back a pending free list entry before allocating\n", pthread_self(), name())); + DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 pushes back a pending free list entry before allocating\n", pthread_name(), name())); free_list.write (&ptr, 1); } return Pool::alloc (); diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index 3d3cb96fb5..b8ca8fc093 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -28,9 +28,17 @@ #include <fst.h> #endif +#ifdef COMPILER_MSVC +DECLARE_DEFAULT_COMPARISONS(pthread_t) // Needed for 'DECLARE_DEFAULT_COMPARISONS'. Objects in an STL container can be + // searched and sorted. Thus, when instantiating the container, MSVC complains + // if the type of object being contained has no appropriate comparison operators + // defined (specifically, if operators '<' and '==' are undefined). This seems + // to be the case with ptw32 'pthread_t' which is a simple struct. +#endif + using namespace std; -typedef std::set<pthread_t> ThreadMap; +typedef std::list<pthread_t> ThreadMap; static ThreadMap all_threads; static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; static Glib::Threads::Private<char> thread_name (free); @@ -116,7 +124,7 @@ pthread_create_and_store (string name, pthread_t *thread, void * (*start_routin if ((ret = thread_creator (thread, &default_attr, fake_thread_start, ts)) == 0) { pthread_mutex_lock (&thread_map_lock); - all_threads.insert (*thread); + all_threads.push_back (*thread); pthread_mutex_unlock (&thread_map_lock); } @@ -149,7 +157,7 @@ pthread_kill_all (int signum) { pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if ((*i) != pthread_self()) { + if (!pthread_equal ((*i), pthread_self())) { pthread_kill ((*i), signum); } } @@ -161,6 +169,7 @@ void pthread_cancel_all () { pthread_mutex_lock (&thread_map_lock); + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ) { ThreadMap::iterator nxt = i; diff --git a/libs/pbd/resource.cc b/libs/pbd/resource.cc new file mode 100644 index 0000000000..9d6f8b1746 --- /dev/null +++ b/libs/pbd/resource.cc @@ -0,0 +1,77 @@ +/* + Copyright (C) 2011 Tim Mayberry + + 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. + +*/ + +#ifdef PLATFORM_WINDOWS +#include <stdio.h> +#else +#include <sys/time.h> +#include <sys/resource.h> +#endif + +#include "pbd/resource.h" + +namespace PBD { + +bool +get_resource_limit (ResourceType resource, ResourceLimit& limit) +{ + if (resource == OpenFiles) + { +#ifdef PLATFORM_WINDOWS + limit.current_limit = _getmaxstdio(); + limit.max_limit = 2048; + return true; +#else + struct rlimit rl; + if (getrlimit (RLIMIT_NOFILE, &rl) == 0) { + limit.current_limit = rl.rlim_cur; + limit.max_limit = rl.rlim_max; + return true; + } +#endif + } + + return false; +} + +bool +set_resource_limit (ResourceType resource, const ResourceLimit& limit) +{ + if (resource == OpenFiles) + { +#ifdef PLATFORM_WINDOWS + // no soft and hard limits on windows + rlimit_t new_max = _setmaxstdio(limit.current_limit); + + if (new_max == limit.current_limit) return true; +#else + struct rlimit rl; + rl.rlim_cur = limit.current_limit; + rl.rlim_max = limit.max_limit; + if (setrlimit (RLIMIT_NOFILE, &rl) == 0) { + return true; + } + +#endif + } + + return false; +} + +} // namespace PBD diff --git a/libs/pbd/search_path.cc b/libs/pbd/search_path.cc index 3f7be5aa56..ea08785f68 100644 --- a/libs/pbd/search_path.cc +++ b/libs/pbd/search_path.cc @@ -27,7 +27,7 @@ using namespace std; namespace { -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS const char * const path_delimiter = ";"; #else const char * const path_delimiter = ":"; @@ -37,12 +37,12 @@ const char * const path_delimiter = ":"; namespace PBD { -SearchPath::SearchPath () +Searchpath::Searchpath () { } -SearchPath::SearchPath (const string& path) +Searchpath::Searchpath (const string& path) { vector<std::string> tmp; @@ -51,13 +51,13 @@ SearchPath::SearchPath (const string& path) } } -SearchPath::SearchPath (const vector<std::string>& paths) +Searchpath::Searchpath (const vector<std::string>& paths) { add_directories (paths); } void -SearchPath::add_directory (const std::string& directory_path) +Searchpath::add_directory (const std::string& directory_path) { if (!directory_path.empty()) { push_back(directory_path); @@ -65,7 +65,7 @@ SearchPath::add_directory (const std::string& directory_path) } void -SearchPath::add_directories (const vector<std::string>& paths) +Searchpath::add_directories (const vector<std::string>& paths) { for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) { add_directory (*i); @@ -73,7 +73,7 @@ SearchPath::add_directories (const vector<std::string>& paths) } const string -SearchPath::to_string () const +Searchpath::to_string () const { string path; @@ -87,37 +87,37 @@ SearchPath::to_string () const return path; } -SearchPath& -SearchPath::operator+= (const SearchPath& spath) +Searchpath& +Searchpath::operator+= (const Searchpath& spath) { insert(end(), spath.begin(), spath.end()); return *this; } -SearchPath& -SearchPath::operator+= (const std::string& directory_path) +Searchpath& +Searchpath::operator+= (const std::string& directory_path) { add_directory (directory_path); return *this; } -SearchPath& -SearchPath::operator+ (const std::string& directory_path) +Searchpath& +Searchpath::operator+ (const std::string& directory_path) { add_directory (directory_path); return *this; } -SearchPath& -SearchPath::operator+ (const SearchPath& spath) +Searchpath& +Searchpath::operator+ (const Searchpath& spath) { - // concatenate paths into new SearchPath + // concatenate paths into new Searchpath insert(end(), spath.begin(), spath.end()); return *this; } -SearchPath& -SearchPath::add_subdirectory_to_paths (const string& subdir) +Searchpath& +Searchpath::add_subdirectory_to_paths (const string& subdir) { for (vector<std::string>::iterator i = begin(); i != end(); ++i) { // should these new paths just be added to the end of diff --git a/libs/pbd/semutils.cc b/libs/pbd/semutils.cc index 48fdd249f6..cf7b54d30e 100644 --- a/libs/pbd/semutils.cc +++ b/libs/pbd/semutils.cc @@ -23,7 +23,12 @@ using namespace PBD; ProcessSemaphore::ProcessSemaphore (const char* name, int val) { -#ifdef __APPLE__ +#ifdef PLATFORM_WINDOWS + if ((_sem = CreateSemaphore(NULL, val, 32767, name)) == NULL) { + throw failed_constructor (); + } + +#elif __APPLE__ if ((_sem = sem_open (name, O_CREAT, 0600, val)) == (sem_t*) SEM_FAILED) { throw failed_constructor (); } @@ -45,7 +50,28 @@ ProcessSemaphore::ProcessSemaphore (const char* name, int val) ProcessSemaphore::~ProcessSemaphore () { -#ifdef __APPLE__ +#ifdef PLATFORM_WINDOWS + CloseHandle(_sem); +#elif __APPLE__ sem_close (ptr_to_sem()); #endif } + +#ifdef PLATFORM_WINDOWS + +int +ProcessSemaphore::signal () +{ + // non-zero on success, opposite to posix + return !ReleaseSemaphore(_sem, 1, NULL); +} + +int +ProcessSemaphore::wait () +{ + DWORD result = 0; + result = WaitForSingleObject(_sem, INFINITE); + return (result == WAIT_OBJECT_0); +} + +#endif diff --git a/libs/pbd/sndfile_manager.cc b/libs/pbd/sndfile_manager.cc index d1dcd05256..c028bc11ba 100644 --- a/libs/pbd/sndfile_manager.cc +++ b/libs/pbd/sndfile_manager.cc @@ -22,7 +22,6 @@ */ #include <sys/time.h> -#include <sys/resource.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> diff --git a/libs/pbd/stacktrace.cc b/libs/pbd/stacktrace.cc index 0177b8c9e8..c74dd946f7 100644 --- a/libs/pbd/stacktrace.cc +++ b/libs/pbd/stacktrace.cc @@ -22,6 +22,7 @@ #include "pbd/stacktrace.h" #include <cstdio> #include <iostream> +#include <string> void PBD::trace_twb () @@ -105,7 +106,7 @@ PBD::stacktrace (std::ostream& out, int levels) #else std::string -PBD::demangle (std::string const & l) +PBD::demangle (std::string const & l) /* JE - !!!! 'PBD' namespace might possibly get removed (except it's still used in 'libs/canvas/item.cc') */ { return std::string(); } diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc index 105af75861..c4077f60af 100644 --- a/libs/pbd/stateful.cc +++ b/libs/pbd/stateful.cc @@ -18,7 +18,11 @@ $Id: stateful.cc 629 2006-06-21 23:01:03Z paul $ */ +#ifdef COMPILER_MSVC +#include <io.h> // Microsoft's nearest equivalent to <unistd.h> +#else #include <unistd.h> +#endif #include <glibmm/fileutils.h> #include <glibmm/miscutils.h> diff --git a/libs/pbd/test/filesystem_test.cc b/libs/pbd/test/filesystem_test.cc index ce2faadc82..458105d177 100644 --- a/libs/pbd/test/filesystem_test.cc +++ b/libs/pbd/test/filesystem_test.cc @@ -10,6 +10,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION (FilesystemTest); void FilesystemTest::testPathIsWithin () { +#ifndef PLATFORM_WINDOWS system ("rm -r foo"); CPPUNIT_ASSERT (g_mkdir_with_parents ("foo/bar/baz", 0755) == 0); @@ -31,5 +32,6 @@ FilesystemTest::testPathIsWithin () CPPUNIT_ASSERT (PBD::path_is_within ("foo/bar", "foo/bar")); CPPUNIT_ASSERT (PBD::path_is_within ("foo/jim/baz", "frobozz") == false); +#endif } diff --git a/libs/pbd/test/mutex_test.cc b/libs/pbd/test/mutex_test.cc new file mode 100644 index 0000000000..52c36c4695 --- /dev/null +++ b/libs/pbd/test/mutex_test.cc @@ -0,0 +1,24 @@ +#include "mutex_test.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (MutexTest); + +using namespace std; + +MutexTest::MutexTest () +{ +} + +void +MutexTest::testBasic () +{ + Glib::Threads::Mutex::Lock lm (m_mutex); + + CPPUNIT_ASSERT (lm.locked()); + + /* This will fail on POSIX systems but not on some older versions of glib + * on win32 as TryEnterCriticalSection is used and it will return true + * as CriticalSection is reentrant and fail the assertion. + */ + CPPUNIT_ASSERT (!m_mutex.trylock()); + +} diff --git a/libs/pbd/test/mutex_test.h b/libs/pbd/test/mutex_test.h new file mode 100644 index 0000000000..95b6ea3f65 --- /dev/null +++ b/libs/pbd/test/mutex_test.h @@ -0,0 +1,17 @@ +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include "glibmm/threads.h" + +class MutexTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (MutexTest); + CPPUNIT_TEST (testBasic); + CPPUNIT_TEST_SUITE_END (); + +public: + MutexTest (); + void testBasic (); + +private: + Glib::Threads::Mutex m_mutex; +}; diff --git a/libs/pbd/test/test_common.cc b/libs/pbd/test/test_common.cc index 16da3ed2a8..6e099d2f3e 100644 --- a/libs/pbd/test/test_common.cc +++ b/libs/pbd/test/test_common.cc @@ -25,10 +25,10 @@ * in an installed location on windows or by setting an environment variable * on unix. */ -PBD::SearchPath +PBD::Searchpath test_search_path () { -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS std::string wsp(g_win32_get_package_installation_directory_of_module(NULL)); return Glib::build_filename (wsp, "pbd_testdata"); #else diff --git a/libs/pbd/test/test_common.h b/libs/pbd/test/test_common.h index 0dc62f61dc..825c01fecb 100644 --- a/libs/pbd/test/test_common.h +++ b/libs/pbd/test/test_common.h @@ -21,6 +21,6 @@ #include "pbd/search_path.h" -PBD::SearchPath test_search_path (); +PBD::Searchpath test_search_path (); #endif diff --git a/libs/pbd/test/testrunner.cc b/libs/pbd/test/testrunner.cc index 1512ebd024..ea8f0aa115 100644 --- a/libs/pbd/test/testrunner.cc +++ b/libs/pbd/test/testrunner.cc @@ -4,11 +4,15 @@ #include <cppunit/TestResultCollector.h> #include <cppunit/TestRunner.h> #include <cppunit/BriefTestProgressListener.h> +#include <glibmm/thread.h> #include "scalar_properties.h" + int main () { + Glib::thread_init(); + ScalarPropertiesTest::make_property_quarks (); CppUnit::TestResult testresult; diff --git a/libs/pbd/transmitter.cc b/libs/pbd/transmitter.cc index aa5c75da19..e4266d34d7 100644 --- a/libs/pbd/transmitter.cc +++ b/libs/pbd/transmitter.cc @@ -84,12 +84,20 @@ Transmitter::deliver () /* do the right thing if this should not return */ if (does_not_return()) { +#ifndef PLATFORM_WINDOWS +// TODO !!!! Commented out temporarily (for Windows) sigset_t mask; sigemptyset (&mask); sigsuspend (&mask); /*NOTREACHED*/ exit (1); +/* JE - From what I can tell, the above code suspends + * program execution until (any) signal occurs. Not + * sure at the moment what this achieves, unless it + * provides some time for the user to see the message. + */ +#endif } } diff --git a/libs/pbd/uuid.cc b/libs/pbd/uuid.cc index 0ffeca23cb..8b55ab3381 100644 --- a/libs/pbd/uuid.cc +++ b/libs/pbd/uuid.cc @@ -20,19 +20,16 @@ #include "pbd/uuid.h" -using namespace PBD; - -UUID& -UUID::operator= (std::string const & str) +PBD::UUID& +PBD::UUID::operator= (std::string const & str) { - uuid_parse (str.c_str(), id); + boost::uuids::string_generator gen; + *((boost::uuids::uuid*) this) = gen (str); return *this; } std::string -UUID::to_s () const +PBD::UUID::to_s () const { - char buf[37]; - uuid_unparse (id, buf); - return std::string (buf); + return std::string ((const char*) data, size()); } diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 09af0f614b..d721a78675 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -38,7 +38,6 @@ libpbd_sources = [ 'controllable.cc', 'controllable_descriptor.cc', 'clear_dir.cc', - 'crossthread.cc', 'cpus.cc', 'debug.cc', 'enumwriter.cc', @@ -46,11 +45,14 @@ libpbd_sources = [ 'enums.cc', 'epa.cc', 'error.cc', + 'ffs.cc', 'file_manager.cc', 'file_utils.cc', 'fpu.cc', + 'glib_semaphore.cc', 'id.cc', 'locale_guard.cc', + 'localtime_r.cc', 'malign.cc', 'mountpoint.cc', 'openuri.cc', @@ -61,6 +63,7 @@ libpbd_sources = [ 'property_list.cc', 'pthread_utils.cc', 'receiver.cc', + 'resource.cc', 'search_path.cc', 'semutils.cc', 'shortpath.cc', @@ -90,20 +93,18 @@ def configure(conf): autowaf.configure(conf) autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', atleast_version='2.0') - if sys.platform != 'darwin': - autowaf.check_pkg(conf, 'uuid', uselib_store='UUID') conf.check(function_name='getmntent', header_name='mntent.h', define_name='HAVE_GETMNTENT',mandatory=False) conf.check(header_name='execinfo.h', define_name='HAVE_EXECINFO',mandatory=False) conf.check(header_name='unistd.h', define_name='HAVE_UNISTD',mandatory=False) conf.check_cc(function_name='posix_memalign', header_name='stdlib.h', cflags='-D_XOPEN_SOURCE=600', define_name='HAVE_POSIX_MEMALIGN', mandatory=False) + conf.check(function_name='localtime_r', header_name='time.h', define_name='HAVE_LOCALTIME_R',mandatory=False) conf.write_config_header('libpbd-config.h', remove=False) # Boost headers autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp') autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp') - # autowaf.check_header(conf, 'cxx', 'boost/uuid/uuid.hpp') def build(bld): @@ -127,6 +128,9 @@ def build(bld): if bld.is_defined('DEBUG_RT_ALLOC'): obj.source += 'debug_rt_alloc.c' + if bld.env['build_target'] != 'mingw': + obj.source += [ 'crossthread.cc' ] + obj.export_includes = ['.'] obj.includes = ['.'] obj.name = 'libpbd' @@ -150,6 +154,7 @@ def build(bld): testobj.source = ''' test/testrunner.cc test/xpath.cc + test/mutex_test.cc test/scalar_properties.cc test/signals_test.cc test/convert_test.cc @@ -161,7 +166,7 @@ def build(bld): testobj.uselib = 'CPPUNIT XML SNDFILE' testobj.use = 'libpbd' testobj.name = 'libpbd-tests' - if sys.platform != 'darwin': + if sys.platform != 'darwin' and bld.env['build_target'] != 'mingw': testobj.linkflags = ['-lrt'] diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc index a1fa77db66..69187995a1 100644 --- a/libs/pbd/xml++.cc +++ b/libs/pbd/xml++.cc @@ -167,6 +167,7 @@ XMLTree::write() const void XMLTree::debug(FILE* out) const { +#ifdef LIBXML_DEBUG_ENABLED xmlDocPtr doc; XMLNodeList children; @@ -176,6 +177,7 @@ XMLTree::debug(FILE* out) const writenode(doc, _root, doc->children, 1); xmlDebugDumpDocument (out, doc); xmlFreeDoc(doc); +#endif } const string& diff --git a/libs/qm-dsp/dsp/wavelet/Wavelet.cpp b/libs/qm-dsp/dsp/wavelet/Wavelet.cpp index 504090528c..ef792460dd 100644 --- a/libs/qm-dsp/dsp/wavelet/Wavelet.cpp +++ b/libs/qm-dsp/dsp/wavelet/Wavelet.cpp @@ -13,6 +13,10 @@ COPYING included with this distribution for more information. */ +#ifdef COMPILER_MSVC +#pragma warning(disable:4305) +#endif + #include "Wavelet.h" #include <cassert> diff --git a/libs/rubberband/rubberband/msvc_rubberband.h b/libs/rubberband/rubberband/msvc_rubberband.h new file mode 100644 index 0000000000..700b11033e --- /dev/null +++ b/libs/rubberband/rubberband/msvc_rubberband.h @@ -0,0 +1,88 @@ +/* + 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_rubberband_h__ +#define __msvc_rubberband_h__ + +#ifdef RUBBERBAND_IS_IN_WIN_STATIC_LIB // #define if your project uses librubberband (under Windows) as a static library +#define RUBBERBAND_IS_IN_WINDLL 0 +#endif + +#if !defined(RUBBERBAND_IS_IN_WINDLL) + #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW) + // If you need '__declspec' compatibility, add extra compilers to the above as necessary + #define RUBBERBAND_IS_IN_WINDLL 1 + #else + #define RUBBERBAND_IS_IN_WINDLL 0 + #endif +#endif + +#if RUBBERBAND_IS_IN_WINDLL && !defined(RUBBERBAND_API) + #if defined(BUILDING_RUBBERBAND) + #define RUBBERBAND_API __declspec(dllexport) + #define RUBBERBAND_APICALLTYPE __stdcall + #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point + #define RUBBERBAND_API __declspec(dllimport) + #define RUBBERBAND_APICALLTYPE __stdcall + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#elif !defined(RUBBERBAND_API) + // Other compilers / platforms could be accommodated here + #define RUBBERBAND_API + #define RUBBERBAND_APICALLTYPE + #define GETOPT_API + #define GETOPT_APICALLTYPE +#endif + +#ifndef GETOPT_API + #if defined(BUILDING_GETOPT) + #define GETOPT_API __declspec(dllexport) + #define GETOPT_APICALLTYPE __cdecl + #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point + #define GETOPT_API __declspec(dllimport) + #define GETOPT_APICALLTYPE __cdecl + #else + #error "Attempting to define __declspec with an incompatible compiler !" + #endif +#endif // GETOPT_API + +#ifdef COMPILER_MSVC +#include <rpc.h> + +#ifndef __THROW +#define __THROW throw() +#endif + +namespace RubberBand { + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +// These are used to replicate 'dirent.h' functionality +// RUBBERBAND_API int RUBBERBAND_APICALLTYPE placeholder(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +} // namespace Rubberband + +#endif // COMPILER_MSVC +#endif // __msvc_rubberband_h__ diff --git a/libs/rubberband/src/Profiler.h b/libs/rubberband/src/Profiler.h index 616a553ecb..d6897b817b 100644 --- a/libs/rubberband/src/Profiler.h +++ b/libs/rubberband/src/Profiler.h @@ -31,7 +31,7 @@ #include <time.h> #else #include "sysutils.h" -#ifndef _WIN32 +#ifndef PLATFORM_WINDOWS #include <sys/time.h> #endif #endif diff --git a/libs/rubberband/src/RingBuffer.h b/libs/rubberband/src/RingBuffer.h index 07312169a6..a9262c8cdc 100644 --- a/libs/rubberband/src/RingBuffer.h +++ b/libs/rubberband/src/RingBuffer.h @@ -20,7 +20,7 @@ #include <cstring> -#ifndef _WIN32 +#ifndef PLATFORM_WINDOWS #include <sys/mman.h> #endif @@ -30,7 +30,7 @@ //#define DEBUG_RINGBUFFER 1 -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS #define MLOCK(a,b) 1 #define MUNLOCK(a,b) 1 #else diff --git a/libs/rubberband/src/Scavenger.h b/libs/rubberband/src/Scavenger.h index d1b6ca9ffa..a922d7ec6e 100644 --- a/libs/rubberband/src/Scavenger.h +++ b/libs/rubberband/src/Scavenger.h @@ -19,7 +19,7 @@ #include <list> #include <iostream> -#ifndef WIN32 +#ifndef PLATFORM_WINDOWS #include <sys/time.h> #endif diff --git a/libs/rubberband/src/StretchCalculator.cpp b/libs/rubberband/src/StretchCalculator.cpp index 1541759762..18ee9cc9c3 100644 --- a/libs/rubberband/src/StretchCalculator.cpp +++ b/libs/rubberband/src/StretchCalculator.cpp @@ -12,6 +12,9 @@ COPYING included with this distribution for more information. */ +#ifdef COMPILER_MSVC +#include "bsd-3rdparty/float_cast/float_cast.h" +#endif #include "StretchCalculator.h" #include <algorithm> diff --git a/libs/rubberband/src/StretcherImpl.cpp b/libs/rubberband/src/StretcherImpl.cpp index 200c8771a8..d15a71d68e 100644 --- a/libs/rubberband/src/StretcherImpl.cpp +++ b/libs/rubberband/src/StretcherImpl.cpp @@ -12,6 +12,9 @@ COPYING included with this distribution for more information. */ +#ifdef COMPILER_MSVC +#include "bsd-3rdparty/float_cast/float_cast.h" +#endif #include "StretcherImpl.h" #include "PercussiveAudioCurve.h" #include "HighFrequencyAudioCurve.h" diff --git a/libs/rubberband/src/Thread.cpp b/libs/rubberband/src/Thread.cpp index 49f75b5b65..d5a7b2f6ff 100644 --- a/libs/rubberband/src/Thread.cpp +++ b/libs/rubberband/src/Thread.cpp @@ -16,11 +16,11 @@ #include <cstdlib> #include <iostream> -#include <cstdlib> -#include <cstdlib> +#ifndef COMPILER_MSVC #include <sys/time.h> #include <time.h> +#endif using std::cerr; using std::endl; @@ -29,7 +29,7 @@ using std::string; namespace RubberBand { -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS Thread::Thread() : m_id(0), @@ -289,7 +289,7 @@ Condition::signal() SetEvent(m_condition); } -#else /* !_WIN32 */ +#else /* !PLATFORM_WINDOWS */ Thread::Thread() : @@ -562,7 +562,7 @@ Condition::signal() pthread_cond_signal(&m_condition); } -#endif /* !_WIN32 */ +#endif /* !PLATFORM_WINDOWS */ MutexLocker::MutexLocker(Mutex *mutex) : m_mutex(mutex) diff --git a/libs/rubberband/src/Thread.h b/libs/rubberband/src/Thread.h index 061469297e..63a5a65b67 100644 --- a/libs/rubberband/src/Thread.h +++ b/libs/rubberband/src/Thread.h @@ -15,11 +15,11 @@ #ifndef _RUBBERBAND_THREAD_H_ #define _RUBBERBAND_THREAD_H_ -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS #include <windows.h> -#else /* !_WIN32 */ +#else /* !PLATFORM_WINDOWS */ #include <pthread.h> -#endif /* !_WIN32 */ +#endif /* !PLATFORM_WINDOWS */ #include <string> @@ -33,7 +33,7 @@ namespace RubberBand class Thread { public: -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS typedef HANDLE Id; #else typedef pthread_t Id; @@ -53,7 +53,7 @@ protected: virtual void run() = 0; private: -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS HANDLE m_id; bool m_extant; static DWORD WINAPI staticRun(LPVOID lpParam); @@ -75,7 +75,7 @@ public: bool trylock(); private: -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS HANDLE m_mutex; #ifndef NO_THREAD_CHECKS DWORD m_lockedBy; @@ -123,7 +123,7 @@ public: private: -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS HANDLE m_mutex; HANDLE m_condition; bool m_locked; diff --git a/libs/rubberband/src/bsd-3rdparty/float_cast/float_cast.h b/libs/rubberband/src/bsd-3rdparty/float_cast/float_cast.h index 1ba0e03bdc..0e3d8a4040 100644 --- a/libs/rubberband/src/bsd-3rdparty/float_cast/float_cast.h +++ b/libs/rubberband/src/bsd-3rdparty/float_cast/float_cast.h @@ -35,6 +35,9 @@ ** long int lrint (double x) ; */ +#ifndef __FLOAT_CAST_H__ // Added by JE - 30-11-2009 +#define __FLOAT_CAST_H__ + #if (defined (WIN32) || defined (_WIN32)) #include <math.h> @@ -69,5 +72,5 @@ #endif - +#endif // __FLOAT_CAST_H__ diff --git a/libs/rubberband/src/main.cpp b/libs/rubberband/src/main.cpp index 1c80696180..cdc62e8afa 100644 --- a/libs/rubberband/src/main.cpp +++ b/libs/rubberband/src/main.cpp @@ -23,7 +23,7 @@ #include <cstring> #include "sysutils.h" -#ifdef __MSVC__ +#ifdef COMPILER_MSVC #include "bsd-3rdparty/getopt/getopt.h" #else #include <getopt.h> @@ -36,7 +36,7 @@ using namespace std; using namespace RubberBand; -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS using RubberBand::gettimeofday; using RubberBand::usleep; #endif @@ -324,7 +324,7 @@ int main(int argc, char **argv) cerr << "Using time ratio " << ratio; cerr << " and frequency ratio " << frequencyshift << endl; -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS RubberBand:: #endif timeval tv; @@ -495,7 +495,11 @@ int main(int argc, char **argv) } delete[] obf; } else { +#ifdef PLATFORM_WINDOWS + RubberBand::usleep(10000); +#else usleep(10000); +#endif } } @@ -506,7 +510,7 @@ int main(int argc, char **argv) cerr << "in: " << countIn << ", out: " << countOut << ", ratio: " << float(countOut)/float(countIn) << ", ideal output: " << lrint(countIn * ratio) << ", error: " << abs(lrint(countIn * ratio) - int(countOut)) << endl; -#ifdef _WIN32 +#ifdef PLATFORM_WINDOWS RubberBand:: #endif timeval etv; diff --git a/libs/rubberband/src/sysutils.h b/libs/rubberband/src/sysutils.h index a529afde0d..3883c59ff5 100644 --- a/libs/rubberband/src/sysutils.h +++ b/libs/rubberband/src/sysutils.h @@ -15,7 +15,7 @@ #ifndef _RUBBERBAND_SYSINFO_H_ #define _RUBBERBAND_SYSINFO_H_ -#ifdef __MSVC__ +#ifdef COMPILER_MSVC #include "bsd-3rdparty/float_cast/float_cast.h" #define R__ __restrict #endif @@ -28,11 +28,11 @@ #define R__ #endif -#ifdef __MINGW32__ +#ifdef COMPILER_MINGW #include <malloc.h> #endif -#ifdef __MSVC__ +#ifdef COMPILER_MSVC #define alloca _alloca #endif diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h index 72726600c9..f5af008e4a 100644 --- a/libs/surfaces/control_protocol/control_protocol/control_protocol.h +++ b/libs/surfaces/control_protocol/control_protocol/control_protocol.h @@ -145,7 +145,7 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope void prev_track (uint32_t initial_id); private: - ControlProtocol (const ControlProtocol&); /* noncopyable */ + LIBCONTROLCP_LOCAL ControlProtocol (const ControlProtocol&); /* noncopyable */ bool _active; }; diff --git a/libs/surfaces/control_protocol/wscript b/libs/surfaces/control_protocol/wscript index 235c6c06cb..c79a3a2dbc 100644 --- a/libs/surfaces/control_protocol/wscript +++ b/libs/surfaces/control_protocol/wscript @@ -28,7 +28,7 @@ def build(bld): if bld.is_defined ('INTERNAL_SHARED_LIBS'): obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=controlcp_sources) # defines for this library - obj.defines = [ 'LIBCONTROLCP_DLL_EXPORTS=1' ] + obj.defines = [ 'LIBCONTROLCP_DLL_EXPORTS' ] obj.cxxflags = [ '-fvisibility=hidden' ] obj.cflags = [ '-fvisibility=hidden' ] else: diff --git a/libs/surfaces/frontier/kernel_drivers/tranzport.c b/libs/surfaces/frontier/kernel_drivers/tranzport.c index 6893f66921..b7b6709d56 100644 --- a/libs/surfaces/frontier/kernel_drivers/tranzport.c +++ b/libs/surfaces/frontier/kernel_drivers/tranzport.c @@ -445,7 +445,7 @@ static void usb_tranzport_interrupt_out_callback(struct urb *urb) { struct usb_tranzport *dev = urb->context; - /* sync/async unlink faults aren't errors */ + /* sync/async ::g_unlink faults aren't errors */ if (urb->status && !(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 2ea9079b49..bae6a48837 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -105,7 +105,7 @@ static const char * const midimap_env_variable_name = "ARDOUR_MIDIMAPS_PATH"; static const char* const midi_map_dir_name = "midi_maps"; static const char* const midi_map_suffix = ".map"; -SearchPath +Searchpath system_midi_map_search_path () { bool midimap_path_defined = false; @@ -115,7 +115,7 @@ system_midi_map_search_path () return spath_env; } - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(midi_map_dir_name); return spath; } @@ -127,7 +127,7 @@ user_midi_map_directory () } static bool -midi_map_filter (const string &str, void */*arg*/) +midi_map_filter (const string &str, void* /*arg*/) { return (str.length() > strlen(midi_map_suffix) && str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix))); @@ -138,7 +138,7 @@ GenericMidiControlProtocol::reload_maps () { vector<string *> *midi_maps; PathScanner scanner; - SearchPath spath (system_midi_map_search_path()); + Searchpath spath (system_midi_map_search_path()); spath += user_midi_map_directory (); midi_maps = scanner (spath.to_string(), midi_map_filter, 0, false, true); diff --git a/libs/surfaces/generic_midi/interface.cc b/libs/surfaces/generic_midi/interface.cc index 94edb0ba80..1f2ae7b127 100644 --- a/libs/surfaces/generic_midi/interface.cc +++ b/libs/surfaces/generic_midi/interface.cc @@ -24,7 +24,7 @@ using namespace ARDOUR; -ControlProtocol* +ControlProtocol* ARDOURSURFACE_LOCAL new_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s) { GenericMidiControlProtocol* gmcp; @@ -43,35 +43,30 @@ new_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s return gmcp; } -void +void ARDOURSURFACE_LOCAL delete_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp) { delete cp; } -bool +bool ARDOURSURFACE_LOCAL probe_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/) { return GenericMidiControlProtocol::probe (); } +// Field names commented out by JE - 06-01-2010 static ControlProtocolDescriptor generic_midi_descriptor = { - name : "Generic MIDI", - id : "uri://ardour.org/surfaces/generic_midi:0", - ptr : 0, - module : 0, - mandatory : 0, - supports_feedback : true, - probe : probe_generic_midi_protocol, - initialize : new_generic_midi_protocol, - destroy : delete_generic_midi_protocol + /*name : */ "Generic MIDI", + /*id : */ "uri://ardour.org/surfaces/generic_midi:0", + /*ptr : */ 0, + /*module : */ 0, + /*mandatory : */ 0, + /*supports_feedback : */ true, + /*probe : */ probe_generic_midi_protocol, + /*initialize : */ new_generic_midi_protocol, + /*destroy : */ delete_generic_midi_protocol }; - -extern "C" { -ControlProtocolDescriptor* -protocol_descriptor () { - return &generic_midi_descriptor; -} -} +extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &generic_midi_descriptor; } diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc index d78dd5e644..a26617fd67 100644 --- a/libs/surfaces/generic_midi/midicontrollable.cc +++ b/libs/surfaces/generic_midi/midicontrollable.cc @@ -27,6 +27,8 @@ #include "pbd/xml++.h" #include "pbd/stacktrace.h" +#include "midi++/types.h" // Added by JE - 06-01-2009. All instances of 'byte' changed to 'MIDI::byte' (for clarification) +#include "midi++/port.h" #include "midi++/channel.h" #include "ardour/async_midi_port.h" @@ -55,7 +57,7 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& last_controllable_value = 0.0f; control_type = none; _control_description = "MIDI Control: none"; - control_additional = (byte) -1; + control_additional = (MIDI::byte) -1; feedback = true; // for now } @@ -73,7 +75,7 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& last_controllable_value = 0.0f; control_type = none; _control_description = "MIDI Control: none"; - control_additional = (byte) -1; + control_additional = (MIDI::byte) -1; feedback = true; // for now } @@ -108,7 +110,7 @@ MIDIControllable::drop_external_control () { midi_forget (); control_type = none; - control_additional = (byte) -1; + control_additional = (MIDI::byte) -1; } void @@ -313,7 +315,7 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg) } void -MIDIControllable::midi_sense_program_change (Parser &, byte msg) +MIDIControllable::midi_sense_program_change (Parser &, MIDI::byte msg) { if (!controllable) { if (lookup_controllable ()) { @@ -349,7 +351,7 @@ MIDIControllable::midi_sense_pitchbend (Parser &, pitchbend_t pb) } void -MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/) +MIDIControllable::midi_receiver (Parser &, MIDI::byte *msg, size_t /*len*/) { /* we only respond to channel messages */ diff --git a/libs/surfaces/generic_midi/wscript b/libs/surfaces/generic_midi/wscript index 186f270463..e871aeeec1 100644 --- a/libs/surfaces/generic_midi/wscript +++ b/libs/surfaces/generic_midi/wscript @@ -34,6 +34,7 @@ def build(bld): obj.includes = ['.', './generic_midi'] obj.name = 'libardour_generic_midi' obj.target = 'ardour_generic_midi' + obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ] obj.uselib = 'GTKMM GTK GDK' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.vnum = LIBARDOUR_GENERIC_MIDI_LIB_VERSION diff --git a/libs/surfaces/mackie/device_info.cc b/libs/surfaces/mackie/device_info.cc index 45fd2faebd..04cbfecc56 100644 --- a/libs/surfaces/mackie/device_info.cc +++ b/libs/surfaces/mackie/device_info.cc @@ -24,6 +24,7 @@ #include "pbd/xml++.h" #include "pbd/error.h" #include "pbd/pathscanner.h" +#include "pbd/convert.h" #include "ardour/filesystem_paths.h" @@ -221,7 +222,7 @@ DeviceInfo::set_state (const XMLNode& node, int /* version */) /* strip count is mandatory */ if ((child = node.child ("Strips")) != 0) { if ((prop = child->property ("value")) != 0) { - if ((_strip_cnt = atoi (prop->value())) == 0) { + if ((_strip_cnt = atoi (prop->value().c_str())) == 0) { _strip_cnt = 8; } } @@ -231,7 +232,7 @@ DeviceInfo::set_state (const XMLNode& node, int /* version */) if ((child = node.child ("Extenders")) != 0) { if ((prop = child->property ("value")) != 0) { - if ((_extenders = atoi (prop->value())) == 0) { + if ((_extenders = atoi (prop->value().c_str())) == 0) { _extenders = 0; } } @@ -441,7 +442,7 @@ static const char * const devinfo_env_variable_name = "ARDOUR_MCP_PATH"; static const char* const devinfo_dir_name = "mcp"; static const char* const devinfo_suffix = ".device"; -static SearchPath +static Searchpath devinfo_search_path () { bool devinfo_path_defined = false; @@ -451,14 +452,14 @@ devinfo_search_path () return spath_env; } - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(devinfo_dir_name); return spath; } static bool -devinfo_filter (const string &str, void */*arg*/) +devinfo_filter (const string &str, void* /*arg*/) { return (str.length() > strlen(devinfo_suffix) && str.find (devinfo_suffix) == (str.length() - strlen (devinfo_suffix))); @@ -471,7 +472,7 @@ DeviceInfo::reload_device_info () vector<string> s; vector<string *> *devinfos; PathScanner scanner; - SearchPath spath (devinfo_search_path()); + Searchpath spath (devinfo_search_path()); devinfos = scanner (spath.to_string(), devinfo_filter, 0, false, true); device_info.clear (); diff --git a/libs/surfaces/mackie/device_profile.cc b/libs/surfaces/mackie/device_profile.cc index ea57458e1c..ddbb4782db 100644 --- a/libs/surfaces/mackie/device_profile.cc +++ b/libs/surfaces/mackie/device_profile.cc @@ -55,7 +55,7 @@ static const char * const devprofile_env_variable_name = "ARDOUR_MCP_PATH"; static const char* const devprofile_dir_name = "mcp"; static const char* const devprofile_suffix = ".profile"; -static SearchPath +static Searchpath devprofile_search_path () { bool devprofile_path_defined = false; @@ -65,7 +65,7 @@ devprofile_search_path () return spath_env; } - SearchPath spath (ardour_data_search_path()); + Searchpath spath (ardour_data_search_path()); spath.add_subdirectory_to_paths(devprofile_dir_name); return spath; @@ -78,7 +78,7 @@ user_devprofile_directory () } static bool -devprofile_filter (const string &str, void */*arg*/) +devprofile_filter (const string &str, void* /*arg*/) { return (str.length() > strlen(devprofile_suffix) && str.find (devprofile_suffix) == (str.length() - strlen (devprofile_suffix))); @@ -91,7 +91,7 @@ DeviceProfile::reload_device_profiles () vector<string> s; vector<string *> *devprofiles; PathScanner scanner; - SearchPath spath (devprofile_search_path()); + Searchpath spath (devprofile_search_path()); devprofiles = scanner (spath.to_string(), devprofile_filter, 0, false, true); device_profiles.clear (); diff --git a/libs/surfaces/mackie/interface.cc b/libs/surfaces/mackie/interface.cc index 294a222a6b..35216da263 100644 --- a/libs/surfaces/mackie/interface.cc +++ b/libs/surfaces/mackie/interface.cc @@ -29,7 +29,7 @@ using namespace ARDOUR; using namespace PBD; using namespace std; -ControlProtocol* +static ControlProtocol* new_mackie_protocol (ControlProtocolDescriptor*, Session* s) { MackieControlProtocol* mcp = 0; @@ -47,7 +47,7 @@ new_mackie_protocol (ControlProtocolDescriptor*, Session* s) return mcp; } -void +static void delete_mackie_protocol (ControlProtocolDescriptor*, ControlProtocol* cp) { try @@ -66,34 +66,28 @@ delete_mackie_protocol (ControlProtocolDescriptor*, ControlProtocol* cp) So anything that can be changed in the UI should not be used here to prevent loading of the lib. */ -bool +static bool probe_mackie_protocol (ControlProtocolDescriptor*) { return MackieControlProtocol::probe(); } +// Field names commented out by JE - 06-01-2010 static ControlProtocolDescriptor mackie_descriptor = { - name : "Mackie", - id : "uri://ardour.org/surfaces/mackie:0", - ptr : 0, - module : 0, - mandatory : 0, + /*name : */ "Mackie", + /*id : */ "uri://ardour.org/surfaces/mackie:0", + /*ptr : */ 0, + /*module : */ 0, + /*mandatory : */ 0, // actually, the surface does support feedback, but all this // flag does is show a submenu on the UI, which is useless for the mackie // because feedback is always on. In any case, who'd want to use the // mcu without the motorised sliders doing their thing? - supports_feedback : false, - probe : probe_mackie_protocol, - initialize : new_mackie_protocol, - destroy : delete_mackie_protocol + /*supports_feedback : */ false, + /*probe : */ probe_mackie_protocol, + /*initialize : */ new_mackie_protocol, + /*destroy : */ delete_mackie_protocol }; -extern "C" { - -ControlProtocolDescriptor* -protocol_descriptor () { - return &mackie_descriptor; -} - -} +extern "C" LIBCONTROLCP_API ControlProtocolDescriptor* protocol_descriptor () { return &mackie_descriptor; } diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index e9bef5a9b0..c83ce819d9 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -29,7 +29,6 @@ #include <float.h> #include <sys/time.h> #include <errno.h> -#include <poll.h> #include <boost/shared_array.hpp> @@ -1272,7 +1271,9 @@ MackieControlProtocol::midi_input_handler (IOCondition ioc, MIDI::Port* port) */ if (!_device_info.uses_ipmidi()) { +#ifndef PLATFORM_WINDOWS CrossThreadChannel::drain (port->selectable()); +#endif } DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name())); diff --git a/libs/surfaces/mackie/wscript b/libs/surfaces/mackie/wscript index beba402fa1..2dc546a5d7 100644 --- a/libs/surfaces/mackie/wscript +++ b/libs/surfaces/mackie/wscript @@ -46,6 +46,8 @@ def build(bld): # need ../libs because some GTK2 header files require stuff there obj.includes = ['.', '../libs'] obj.name = 'libardour_mcp' + obj.defines = [ 'LIBCONTROLCP_EXPORTS' ] + obj.defines += [ 'PACKAGE="libardour_mcp"' ] obj.target = 'ardour_mcp' obj.uselib = 'GTKMM' obj.use = 'libardour libardour_cp libgtkmm2ext' diff --git a/libs/surfaces/osc/interface.cc b/libs/surfaces/osc/interface.cc index a414d4eb82..7c09828f46 100644 --- a/libs/surfaces/osc/interface.cc +++ b/libs/surfaces/osc/interface.cc @@ -23,7 +23,7 @@ using namespace ARDOUR; -ControlProtocol* +static ControlProtocol* new_osc_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s) { OSC* osc = new OSC (*s, Config->get_osc_port()); @@ -33,13 +33,13 @@ new_osc_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s) return osc; } -void +static void delete_osc_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp) { delete cp; } -bool +static bool probe_osc_protocol (ControlProtocolDescriptor* /*descriptor*/) { return true; // we can always do OSC @@ -57,10 +57,5 @@ static ControlProtocolDescriptor osc_descriptor = { destroy : delete_osc_protocol }; -extern "C" { -ControlProtocolDescriptor* -protocol_descriptor () { - return &osc_descriptor; -} -} +extern "C" LIBCONTROLCP_API ControlProtocolDescriptor* protocol_descriptor () { return &osc_descriptor; } diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 37fe0715eb..e252d22e3d 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -28,6 +28,7 @@ #include <unistd.h> #include <fcntl.h> +#include <glib/gstdio.h> #include <glibmm/miscutils.h> #include <pbd/convert.h> @@ -190,7 +191,7 @@ OSC::start () int fd = mkstemp(tmpstr); if (fd >= 0 ) { - unlink (tmpstr); + ::g_unlink (tmpstr); close (fd); _osc_unix_server = lo_server_new (tmpstr, error_callback); @@ -293,11 +294,11 @@ OSC::stop () } if (!_osc_unix_socket_path.empty()) { - unlink (_osc_unix_socket_path.c_str()); + ::g_unlink (_osc_unix_socket_path.c_str()); } if (!_osc_url_file.empty() ) { - unlink (_osc_url_file.c_str() ); + ::g_unlink (_osc_url_file.c_str() ); } // Delete any active route observers diff --git a/libs/surfaces/osc/wscript b/libs/surfaces/osc/wscript index cd77f99871..a00663e977 100644 --- a/libs/surfaces/osc/wscript +++ b/libs/surfaces/osc/wscript @@ -30,6 +30,7 @@ def build(bld): obj.defines = [ 'PACKAGE="ardour_osc"' ] obj.includes = ['.', './osc'] obj.name = 'libardour_osc' + obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ] obj.target = 'ardour_osc' obj.uselib = ' LO ' obj.use = 'libardour libardour_cp libpbd' diff --git a/libs/surfaces/tranzport/interface.cc b/libs/surfaces/tranzport/interface.cc index 16ff22687a..3cf7090783 100644 --- a/libs/surfaces/tranzport/interface.cc +++ b/libs/surfaces/tranzport/interface.cc @@ -23,7 +23,7 @@ using namespace ARDOUR; -ControlProtocol* +static ControlProtocol* new_tranzport_protocol (ControlProtocolDescriptor* descriptor, Session* s) { TranzportControlProtocol* tcp = new TranzportControlProtocol (*s); @@ -37,13 +37,13 @@ new_tranzport_protocol (ControlProtocolDescriptor* descriptor, Session* s) } -void +static void delete_tranzport_protocol (ControlProtocolDescriptor* descriptor, ControlProtocol* cp) { delete cp; } -bool +static bool probe_tranzport_protocol (ControlProtocolDescriptor* descriptor) { return TranzportControlProtocol::probe(); @@ -62,10 +62,6 @@ static ControlProtocolDescriptor tranzport_descriptor = { }; -extern "C" { -ControlProtocolDescriptor* -protocol_descriptor () { - return &tranzport_descriptor; -} -} +extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &tranzport_descriptor; } + diff --git a/libs/surfaces/tranzport/wscript b/libs/surfaces/tranzport/wscript index dfc10f5525..05fd7cf5d6 100644 --- a/libs/surfaces/tranzport/wscript +++ b/libs/surfaces/tranzport/wscript @@ -42,6 +42,7 @@ def build(bld): obj.defines = [ 'PACKAGE="ardour_tranzport"' ] obj.includes = ['.', './tranzport'] obj.name = 'libardour_tranzport' + obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ] obj.target = 'ardour_tranzport' obj.use = 'libardour libardour_cp' obj.vnum = LIBARDOUR_TRANZPORT_LIB_VERSION diff --git a/libs/surfaces/wiimote/interface.cc b/libs/surfaces/wiimote/interface.cc index 318bc40adf..8695facb8d 100644 --- a/libs/surfaces/wiimote/interface.cc +++ b/libs/surfaces/wiimote/interface.cc @@ -29,7 +29,7 @@ using namespace ARDOUR; using namespace PBD; -ControlProtocol* +static ControlProtocol* new_wiimote_protocol (ControlProtocolDescriptor*, Session* s) { WiimoteControlProtocol* wmcp = new WiimoteControlProtocol (*s); @@ -37,13 +37,13 @@ new_wiimote_protocol (ControlProtocolDescriptor*, Session* s) return wmcp; } -void +static void delete_wiimote_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp) { delete cp; } -bool +static bool probe_wiimote_protocol (ControlProtocolDescriptor*) { return WiimoteControlProtocol::probe (); @@ -61,13 +61,5 @@ static ControlProtocolDescriptor wiimote_descriptor = { destroy : delete_wiimote_protocol }; - -extern "C" { - -ControlProtocolDescriptor* -protocol_descriptor () { - return &wiimote_descriptor; -} - -} +extern "C" LIBCONTROLCP_API ControlProtocolDescriptor* protocol_descriptor () { return &wiimote_descriptor; } diff --git a/libs/surfaces/wiimote/wscript b/libs/surfaces/wiimote/wscript index f3c36275c8..e63713c855 100644 --- a/libs/surfaces/wiimote/wscript +++ b/libs/surfaces/wiimote/wscript @@ -28,6 +28,7 @@ def build(bld): obj.defines = [ 'PACKAGE="ardour_wiimote"' ] obj.includes = ['.', '../libs'] obj.name = 'libardour_wiimote' + obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ] obj.target = 'ardour_wiimote' obj.uselib = 'GTKMM CWIID' obj.use = 'libardour libardour_cp libgtkmm2ext' diff --git a/libs/surfaces/wscript b/libs/surfaces/wscript index d9009bee25..29edc427b2 100644 --- a/libs/surfaces/wscript +++ b/libs/surfaces/wscript @@ -23,10 +23,6 @@ children = [ 'control_protocol', 'frontier', 'generic_midi', - 'mackie', - 'osc', - 'tranzport', - 'wiimote' ] def options(opt): @@ -39,16 +35,22 @@ def sub_config_and_use(conf, name, has_objects = True): def configure(conf): autowaf.set_recursive() autowaf.configure(conf) - + for i in children: sub_config_and_use(conf, i) + if (conf.env['build_target'] == 'mingw'): return + #autowaf.check_pkg(conf, 'libusb-1.0', uselib_store='USB', mandatory=False) #if Options.options.tranzport and conf.is_defined('HAVE_USB'): # conf.define('BUILD_TRANZPORT', 1) - autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24") - + if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE', mandatory=False): + sub_config_and_use(conf, 'mackie') + + if autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24"): + sub_config_and_use(conf, 'osc') + conf.check_cc (header_name='cwiid.h', define_name='HAVE_CWIID_H',mandatory=False) if conf.is_defined('HAVE_CWIID_H'): conf.check_cc (header_name='bluetooth/bluetooth.h', define_name='HAVE_BLUETOOTH_H',mandatory=False) @@ -56,6 +58,7 @@ def configure(conf): autowaf.check_pkg(conf, 'cwiid', uselib_store='CWIID', atleast_version='0.6.00',mandatory=False) if conf.is_defined ('HAVE_CWIID'): conf.define ('BUILD_WIIMOTE', 1) + sub_config_and_use(conf, 'wiimote') else: print('You have the cwiid headers needed to compile wiimote support BUT you are missing the pkg-config file for cwiid') else: @@ -65,8 +68,9 @@ def configure(conf): def build(bld): bld.recurse('control_protocol') - bld.recurse('generic_midi') - bld.recurse('mackie') + if (bld.env['build_target'] == 'mingw'): return + if bld.is_defined ('BUILD_MACKIE'): + bld.recurse('mackie') if bld.is_defined ('HAVE_LO'): bld.recurse('osc') if bld.is_defined('BUILD_WIIMOTE'): diff --git a/libs/taglib/taglib/apefooter.h b/libs/taglib/taglib/apefooter.h deleted file mode 120000 index 4478ae1861..0000000000 --- a/libs/taglib/taglib/apefooter.h +++ /dev/null @@ -1 +0,0 @@ -./ape/apefooter.h
\ No newline at end of file diff --git a/libs/taglib/taglib/apeitem.h b/libs/taglib/taglib/apeitem.h deleted file mode 120000 index 4b5757ca25..0000000000 --- a/libs/taglib/taglib/apeitem.h +++ /dev/null @@ -1 +0,0 @@ -./ape/apeitem.h
\ No newline at end of file diff --git a/libs/taglib/taglib/apetag.h b/libs/taglib/taglib/apetag.h deleted file mode 120000 index 6e08d878ca..0000000000 --- a/libs/taglib/taglib/apetag.h +++ /dev/null @@ -1 +0,0 @@ -./ape/apetag.h
\ No newline at end of file diff --git a/libs/taglib/taglib/attachedpictureframe.h b/libs/taglib/taglib/attachedpictureframe.h deleted file mode 120000 index f48f568c55..0000000000 --- a/libs/taglib/taglib/attachedpictureframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/attachedpictureframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/commentsframe.h b/libs/taglib/taglib/commentsframe.h deleted file mode 120000 index 54c9c1d848..0000000000 --- a/libs/taglib/taglib/commentsframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/commentsframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/flacfile.h b/libs/taglib/taglib/flacfile.h deleted file mode 120000 index 163f8fe06b..0000000000 --- a/libs/taglib/taglib/flacfile.h +++ /dev/null @@ -1 +0,0 @@ -./flac/flacfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/flacproperties.h b/libs/taglib/taglib/flacproperties.h deleted file mode 120000 index 3f2524267c..0000000000 --- a/libs/taglib/taglib/flacproperties.h +++ /dev/null @@ -1 +0,0 @@ -./flac/flacproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/generalencapsulatedobjectframe.h b/libs/taglib/taglib/generalencapsulatedobjectframe.h deleted file mode 120000 index dbb35ace6a..0000000000 --- a/libs/taglib/taglib/generalencapsulatedobjectframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/generalencapsulatedobjectframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v1genres.h b/libs/taglib/taglib/id3v1genres.h deleted file mode 120000 index a6e5fa27d5..0000000000 --- a/libs/taglib/taglib/id3v1genres.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v1/id3v1genres.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v1tag.h b/libs/taglib/taglib/id3v1tag.h deleted file mode 120000 index 0843ca4c7b..0000000000 --- a/libs/taglib/taglib/id3v1tag.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v1/id3v1tag.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2extendedheader.h b/libs/taglib/taglib/id3v2extendedheader.h deleted file mode 120000 index ce495056cf..0000000000 --- a/libs/taglib/taglib/id3v2extendedheader.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2extendedheader.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2footer.h b/libs/taglib/taglib/id3v2footer.h deleted file mode 120000 index ad6745fd9e..0000000000 --- a/libs/taglib/taglib/id3v2footer.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2footer.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2frame.h b/libs/taglib/taglib/id3v2frame.h deleted file mode 120000 index cbb258be8c..0000000000 --- a/libs/taglib/taglib/id3v2frame.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2frame.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2framefactory.h b/libs/taglib/taglib/id3v2framefactory.h deleted file mode 120000 index 32fcfab860..0000000000 --- a/libs/taglib/taglib/id3v2framefactory.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2framefactory.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2header.h b/libs/taglib/taglib/id3v2header.h deleted file mode 120000 index 90639420a4..0000000000 --- a/libs/taglib/taglib/id3v2header.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2header.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2synchdata.h b/libs/taglib/taglib/id3v2synchdata.h deleted file mode 120000 index 45374981b4..0000000000 --- a/libs/taglib/taglib/id3v2synchdata.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2synchdata.h
\ No newline at end of file diff --git a/libs/taglib/taglib/id3v2tag.h b/libs/taglib/taglib/id3v2tag.h deleted file mode 120000 index e9b6219657..0000000000 --- a/libs/taglib/taglib/id3v2tag.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/id3v2tag.h
\ No newline at end of file diff --git a/libs/taglib/taglib/mpcfile.h b/libs/taglib/taglib/mpcfile.h deleted file mode 120000 index 3f31e3d713..0000000000 --- a/libs/taglib/taglib/mpcfile.h +++ /dev/null @@ -1 +0,0 @@ -./mpc/mpcfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/mpcproperties.h b/libs/taglib/taglib/mpcproperties.h deleted file mode 120000 index 81f0916dfc..0000000000 --- a/libs/taglib/taglib/mpcproperties.h +++ /dev/null @@ -1 +0,0 @@ -./mpc/mpcproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/mpegfile.h b/libs/taglib/taglib/mpegfile.h deleted file mode 120000 index 9906423f74..0000000000 --- a/libs/taglib/taglib/mpegfile.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/mpegfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/mpegheader.h b/libs/taglib/taglib/mpegheader.h deleted file mode 120000 index beb79d9d17..0000000000 --- a/libs/taglib/taglib/mpegheader.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/mpegheader.h
\ No newline at end of file diff --git a/libs/taglib/taglib/mpegproperties.h b/libs/taglib/taglib/mpegproperties.h deleted file mode 120000 index ca2391c005..0000000000 --- a/libs/taglib/taglib/mpegproperties.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/mpegproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/oggfile.h b/libs/taglib/taglib/oggfile.h deleted file mode 120000 index 629411e4a6..0000000000 --- a/libs/taglib/taglib/oggfile.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/oggfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/oggflacfile.h b/libs/taglib/taglib/oggflacfile.h deleted file mode 120000 index a637866754..0000000000 --- a/libs/taglib/taglib/oggflacfile.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/flac/oggflacfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/oggpage.h b/libs/taglib/taglib/oggpage.h deleted file mode 120000 index c1d996bd86..0000000000 --- a/libs/taglib/taglib/oggpage.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/oggpage.h
\ No newline at end of file diff --git a/libs/taglib/taglib/oggpageheader.h b/libs/taglib/taglib/oggpageheader.h deleted file mode 120000 index 1bb403504c..0000000000 --- a/libs/taglib/taglib/oggpageheader.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/oggpageheader.h
\ No newline at end of file diff --git a/libs/taglib/taglib/relativevolumeframe.h b/libs/taglib/taglib/relativevolumeframe.h deleted file mode 120000 index 98cbd6b46e..0000000000 --- a/libs/taglib/taglib/relativevolumeframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/relativevolumeframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/speexfile.h b/libs/taglib/taglib/speexfile.h deleted file mode 120000 index 69b8223553..0000000000 --- a/libs/taglib/taglib/speexfile.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/speex/speexfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/speexproperties.h b/libs/taglib/taglib/speexproperties.h deleted file mode 120000 index 28b883c1d2..0000000000 --- a/libs/taglib/taglib/speexproperties.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/speex/speexproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/taglib.h b/libs/taglib/taglib/taglib.h deleted file mode 120000 index 8a9f286ab9..0000000000 --- a/libs/taglib/taglib/taglib.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/taglib.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tbytevector.h b/libs/taglib/taglib/tbytevector.h deleted file mode 120000 index 2aba448a9c..0000000000 --- a/libs/taglib/taglib/tbytevector.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tbytevector.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tbytevectorlist.h b/libs/taglib/taglib/tbytevectorlist.h deleted file mode 120000 index e2308fae3b..0000000000 --- a/libs/taglib/taglib/tbytevectorlist.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tbytevectorlist.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tdebug.h b/libs/taglib/taglib/tdebug.h deleted file mode 120000 index a27b5c3bc9..0000000000 --- a/libs/taglib/taglib/tdebug.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tdebug.h
\ No newline at end of file diff --git a/libs/taglib/taglib/textidentificationframe.h b/libs/taglib/taglib/textidentificationframe.h deleted file mode 120000 index 4b775ee038..0000000000 --- a/libs/taglib/taglib/textidentificationframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/textidentificationframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tfile.h b/libs/taglib/taglib/tfile.h deleted file mode 120000 index 09d3e52a3a..0000000000 --- a/libs/taglib/taglib/tfile.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tlist.h b/libs/taglib/taglib/tlist.h deleted file mode 120000 index ce60095443..0000000000 --- a/libs/taglib/taglib/tlist.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tlist.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tlist.tcc b/libs/taglib/taglib/tlist.tcc deleted file mode 120000 index 03b9a96362..0000000000 --- a/libs/taglib/taglib/tlist.tcc +++ /dev/null @@ -1 +0,0 @@ -toolkit/tlist.tcc
\ No newline at end of file diff --git a/libs/taglib/taglib/tmap.h b/libs/taglib/taglib/tmap.h deleted file mode 120000 index 7a59378e13..0000000000 --- a/libs/taglib/taglib/tmap.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tmap.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tmap.tcc b/libs/taglib/taglib/tmap.tcc deleted file mode 120000 index c9d4591d7d..0000000000 --- a/libs/taglib/taglib/tmap.tcc +++ /dev/null @@ -1 +0,0 @@ -toolkit/tmap.tcc
\ No newline at end of file diff --git a/libs/taglib/taglib/trueaudiofile.h b/libs/taglib/taglib/trueaudiofile.h deleted file mode 120000 index 7a677f17fd..0000000000 --- a/libs/taglib/taglib/trueaudiofile.h +++ /dev/null @@ -1 +0,0 @@ -./trueaudio/trueaudiofile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/trueaudioproperties.h b/libs/taglib/taglib/trueaudioproperties.h deleted file mode 120000 index 5e7f7d6c37..0000000000 --- a/libs/taglib/taglib/trueaudioproperties.h +++ /dev/null @@ -1 +0,0 @@ -./trueaudio/trueaudioproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tstring.h b/libs/taglib/taglib/tstring.h deleted file mode 120000 index acbe0c80be..0000000000 --- a/libs/taglib/taglib/tstring.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tstring.h
\ No newline at end of file diff --git a/libs/taglib/taglib/tstringlist.h b/libs/taglib/taglib/tstringlist.h deleted file mode 120000 index 918658c425..0000000000 --- a/libs/taglib/taglib/tstringlist.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/tstringlist.h
\ No newline at end of file diff --git a/libs/taglib/taglib/unicode.h b/libs/taglib/taglib/unicode.h deleted file mode 120000 index 30009297b5..0000000000 --- a/libs/taglib/taglib/unicode.h +++ /dev/null @@ -1 +0,0 @@ -./toolkit/unicode.h
\ No newline at end of file diff --git a/libs/taglib/taglib/uniquefileidentifierframe.h b/libs/taglib/taglib/uniquefileidentifierframe.h deleted file mode 120000 index 55b9305b66..0000000000 --- a/libs/taglib/taglib/uniquefileidentifierframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/uniquefileidentifierframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/unknownframe.h b/libs/taglib/taglib/unknownframe.h deleted file mode 120000 index e46996ab13..0000000000 --- a/libs/taglib/taglib/unknownframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/unknownframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/unsynchronizedlyricsframe.h b/libs/taglib/taglib/unsynchronizedlyricsframe.h deleted file mode 120000 index 162a88d26f..0000000000 --- a/libs/taglib/taglib/unsynchronizedlyricsframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/unsynchronizedlyricsframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/urllinkframe.h b/libs/taglib/taglib/urllinkframe.h deleted file mode 120000 index 1e1aa15219..0000000000 --- a/libs/taglib/taglib/urllinkframe.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/id3v2/frames/urllinkframe.h
\ No newline at end of file diff --git a/libs/taglib/taglib/vorbisfile.h b/libs/taglib/taglib/vorbisfile.h deleted file mode 120000 index d5d372bf03..0000000000 --- a/libs/taglib/taglib/vorbisfile.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/vorbis/vorbisfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/vorbisproperties.h b/libs/taglib/taglib/vorbisproperties.h deleted file mode 120000 index e1d36a3f23..0000000000 --- a/libs/taglib/taglib/vorbisproperties.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/vorbis/vorbisproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/wavpackfile.h b/libs/taglib/taglib/wavpackfile.h deleted file mode 120000 index c88dd7c45d..0000000000 --- a/libs/taglib/taglib/wavpackfile.h +++ /dev/null @@ -1 +0,0 @@ -./wavpack/wavpackfile.h
\ No newline at end of file diff --git a/libs/taglib/taglib/wavpackproperties.h b/libs/taglib/taglib/wavpackproperties.h deleted file mode 120000 index 089b5b713e..0000000000 --- a/libs/taglib/taglib/wavpackproperties.h +++ /dev/null @@ -1 +0,0 @@ -./wavpack/wavpackproperties.h
\ No newline at end of file diff --git a/libs/taglib/taglib/xingheader.h b/libs/taglib/taglib/xingheader.h deleted file mode 120000 index a2711031ab..0000000000 --- a/libs/taglib/taglib/xingheader.h +++ /dev/null @@ -1 +0,0 @@ -./mpeg/xingheader.h
\ No newline at end of file diff --git a/libs/taglib/taglib/xiphcomment.h b/libs/taglib/taglib/xiphcomment.h deleted file mode 120000 index 96e9483222..0000000000 --- a/libs/taglib/taglib/xiphcomment.h +++ /dev/null @@ -1 +0,0 @@ -./ogg/xiphcomment.h
\ No newline at end of file diff --git a/libs/taglib/wscript b/libs/taglib/wscript index 8e2805c709..8c1f1fdd1e 100644 --- a/libs/taglib/wscript +++ b/libs/taglib/wscript @@ -71,6 +71,7 @@ def build(bld): '''.split() obj.export_includes = ['.', 'taglib', 'taglib/toolkit'] obj.includes = include_dirs + obj.defines = ['MAKE_TAGLIB_LIB'] obj.name = 'libtaglib' obj.target = 'taglib' obj.vnum = LIBTAGLIB_LIB_VERSION diff --git a/libs/vamp-plugins/Onset.cpp b/libs/vamp-plugins/Onset.cpp index d475b11be9..4a58bf9fa5 100644 --- a/libs/vamp-plugins/Onset.cpp +++ b/libs/vamp-plugins/Onset.cpp @@ -14,6 +14,9 @@ */ +#ifdef COMPILER_MSVC +#include <ardourext/float_cast.h> +#endif #include <math.h> #include "Onset.h" diff --git a/libs/vamp-plugins/OnsetDetect.cpp b/libs/vamp-plugins/OnsetDetect.cpp index 614eb4c943..714eee3647 100644 --- a/libs/vamp-plugins/OnsetDetect.cpp +++ b/libs/vamp-plugins/OnsetDetect.cpp @@ -12,6 +12,9 @@ COPYING included with this distribution for more information. */ +#ifdef COMPILER_MSVC +#include <ardourext/float_cast.h> +#endif #include "OnsetDetect.h" #include "dsp/onsets/DetectionFunction.h" diff --git a/libs/vamp-plugins/PercussionOnsetDetector.cpp b/libs/vamp-plugins/PercussionOnsetDetector.cpp index 447eb19a28..623b89b6a0 100644 --- a/libs/vamp-plugins/PercussionOnsetDetector.cpp +++ b/libs/vamp-plugins/PercussionOnsetDetector.cpp @@ -34,6 +34,9 @@ authorization. */ +#ifdef COMPILER_MSVC +#include <ardourext/float_cast.h> +#endif #include "PercussionOnsetDetector.h" using std::string; diff --git a/libs/vamp-plugins/SpectralCentroid.cpp b/libs/vamp-plugins/SpectralCentroid.cpp index 82d80b8100..f93fdcaa32 100644 --- a/libs/vamp-plugins/SpectralCentroid.cpp +++ b/libs/vamp-plugins/SpectralCentroid.cpp @@ -34,6 +34,19 @@ authorization. */ +#include <cmath> + +#ifdef COMPILER_MSVC +#include <float.h> + +// 'std::isinf()' and 'std::isnan()' are not available in MSVC. +#define isinf(val) !((bool)_finite((double)val)) +#define isnan(val) (bool)_isnan((double)val) +#else +using std::isnan; +using std::isinf; +#endif + #include "SpectralCentroid.h" using std::string; @@ -41,8 +54,6 @@ using std::vector; using std::cerr; using std::endl; -#include <cmath> - SpectralCentroid::SpectralCentroid(float inputSampleRate) : Plugin(inputSampleRate), @@ -165,13 +176,13 @@ SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime) Feature feature; feature.hasTimestamp = false; - if (!std::isnan(centroidLog) && !std::isinf(centroidLog)) { + if (!isnan(centroidLog) && !isinf(centroidLog)) { feature.values.push_back(centroidLog); } returnFeatures[0].push_back(feature); feature.values.clear(); - if (!std::isnan(centroidLin) && !std::isinf(centroidLin)) { + if (!isnan(centroidLin) && !isinf(centroidLin)) { feature.values.push_back(centroidLin); } returnFeatures[1].push_back(feature); |