├── .gitignore ├── README.md ├── appveyor.yml ├── foo_input_spotify.sln ├── foo_input_spotify ├── SpotifyPlusPlus.h ├── SpotifySession.cpp ├── SpotifySession.h ├── album_art_spotify.cpp ├── boost │ └── noncopyable.hpp ├── cred_prompt.cpp ├── cred_prompt.h ├── foo_input_spotify.vcxproj ├── foo_input_spotify.vcxproj.filters ├── input_spotify.cpp ├── key-930.c ├── pch.cpp ├── pch.h ├── targetver.h ├── util.cpp └── util.h ├── foobar-sdk ├── foobar2000 │ ├── ATLHelpers │ │ ├── ATLHelpers.h │ │ ├── AutoComplete.cpp │ │ ├── AutoComplete.h │ │ ├── BumpableElem.h │ │ ├── CDialogResizeHelper.cpp │ │ ├── CDialogResizeHelper.h │ │ ├── GDIUtils.h │ │ ├── WTL-PP.h │ │ ├── WindowPositionUtils.h │ │ ├── foobar2000_ATL_helpers.vcxproj │ │ ├── foobar2000_ATL_helpers.vcxproj.filters │ │ ├── inplace_edit.cpp │ │ ├── inplace_edit.h │ │ ├── inplace_edit_v2.cpp │ │ ├── inplace_edit_v2.h │ │ ├── misc.cpp │ │ ├── misc.h │ │ ├── stdafx.cpp │ │ └── stdafx.h │ ├── SDK │ │ ├── abort_callback.cpp │ │ ├── abort_callback.h │ │ ├── advconfig.cpp │ │ ├── advconfig.h │ │ ├── album_art.cpp │ │ ├── album_art.h │ │ ├── album_art_helpers.h │ │ ├── app_close_blocker.cpp │ │ ├── app_close_blocker.h │ │ ├── audio_chunk.cpp │ │ ├── audio_chunk.h │ │ ├── audio_chunk_channel_config.cpp │ │ ├── audio_postprocessor.h │ │ ├── autoplaylist.h │ │ ├── cfg_var.cpp │ │ ├── cfg_var.h │ │ ├── chapterizer.cpp │ │ ├── chapterizer.h │ │ ├── commandline.cpp │ │ ├── commandline.h │ │ ├── completion_notify.cpp │ │ ├── completion_notify.h │ │ ├── component.h │ │ ├── component_client.h │ │ ├── components_menu.h │ │ ├── componentversion.cpp │ │ ├── componentversion.h │ │ ├── config_io_callback.h │ │ ├── config_object.cpp │ │ ├── config_object.h │ │ ├── config_object_impl.h │ │ ├── console.cpp │ │ ├── console.h │ │ ├── contextmenu.h │ │ ├── contextmenu_manager.h │ │ ├── core_api.h │ │ ├── coreversion.h │ │ ├── decode_postprocessor.h │ │ ├── dsp.cpp │ │ ├── dsp.h │ │ ├── dsp_manager.cpp │ │ ├── dsp_manager.h │ │ ├── event_logger.h │ │ ├── exceptions.h │ │ ├── file_cached_impl.cpp │ │ ├── file_info.cpp │ │ ├── file_info.h │ │ ├── file_info_impl.cpp │ │ ├── file_info_impl.h │ │ ├── file_info_merge.cpp │ │ ├── file_operation_callback.cpp │ │ ├── file_operation_callback.h │ │ ├── filesystem.cpp │ │ ├── filesystem.h │ │ ├── filesystem_helper.cpp │ │ ├── filesystem_helper.h │ │ ├── foobar2000.h │ │ ├── foobar2000_SDK.vcxproj │ │ ├── foobar2000_SDK.vcxproj.filters │ │ ├── genrand.h │ │ ├── guids.cpp │ │ ├── hasher_md5.cpp │ │ ├── hasher_md5.h │ │ ├── http_client.h │ │ ├── icon_remap.h │ │ ├── info_lookup_handler.h │ │ ├── initquit.h │ │ ├── input.cpp │ │ ├── input.h │ │ ├── input_file_type.cpp │ │ ├── input_file_type.h │ │ ├── input_impl.h │ │ ├── library_manager.h │ │ ├── link_resolver.cpp │ │ ├── link_resolver.h │ │ ├── main_thread_callback.cpp │ │ ├── main_thread_callback.h │ │ ├── mainmenu.cpp │ │ ├── mem_block_container.cpp │ │ ├── mem_block_container.h │ │ ├── menu.h │ │ ├── menu_helpers.cpp │ │ ├── menu_helpers.h │ │ ├── menu_item.cpp │ │ ├── menu_manager.cpp │ │ ├── message_loop.h │ │ ├── metadb.cpp │ │ ├── metadb.h │ │ ├── metadb_handle.cpp │ │ ├── metadb_handle.h │ │ ├── metadb_handle_list.cpp │ │ ├── modeless_dialog.h │ │ ├── ole_interaction.h │ │ ├── output.cpp │ │ ├── output.h │ │ ├── packet_decoder.cpp │ │ ├── packet_decoder.h │ │ ├── play_callback.h │ │ ├── playable_location.cpp │ │ ├── playable_location.h │ │ ├── playback_control.cpp │ │ ├── playback_control.h │ │ ├── playback_stream_capture.h │ │ ├── playlist.cpp │ │ ├── playlist.h │ │ ├── playlist_loader.cpp │ │ ├── playlist_loader.h │ │ ├── popup_message.cpp │ │ ├── popup_message.h │ │ ├── preferences_page.cpp │ │ ├── preferences_page.h │ │ ├── progress_meter.h │ │ ├── replaygain.cpp │ │ ├── replaygain.h │ │ ├── replaygain_info.cpp │ │ ├── replaygain_scanner.h │ │ ├── resampler.h │ │ ├── search_tools.cpp │ │ ├── search_tools.h │ │ ├── service.cpp │ │ ├── service.h │ │ ├── service_impl.h │ │ ├── shortcut_actions.h │ │ ├── stdafx.cpp │ │ ├── system_time_keeper.h │ │ ├── tag_processor.cpp │ │ ├── tag_processor.h │ │ ├── tag_processor_id3v2.cpp │ │ ├── threaded_process.cpp │ │ ├── threaded_process.h │ │ ├── titleformat.cpp │ │ ├── titleformat.h │ │ ├── track_property.h │ │ ├── ui.cpp │ │ ├── ui.h │ │ ├── ui_edit_context.h │ │ ├── ui_element.cpp │ │ ├── ui_element.h │ │ ├── unpack.h │ │ └── vis.h │ ├── foo_input_validator │ │ ├── foo_input_validator.dll │ │ └── readme.txt │ ├── foo_sample │ │ ├── PCH.cpp │ │ ├── contextmenu.cpp │ │ ├── decode.cpp │ │ ├── dsp.cpp │ │ ├── foo_sample.rc │ │ ├── foo_sample.sln │ │ ├── foo_sample.vcxproj │ │ ├── foo_sample.vcxproj.filters │ │ ├── initquit.cpp │ │ ├── input_raw.cpp │ │ ├── main.cpp │ │ ├── mainmenu.cpp │ │ ├── playback_state.cpp │ │ ├── preferences.cpp │ │ ├── readme.txt │ │ ├── resource.h │ │ ├── stdafx.h │ │ └── ui_element.cpp │ ├── foobar2000_component_client │ │ ├── component_client.cpp │ │ └── foobar2000_component_client.vcxproj │ ├── helpers │ │ ├── COM_utils.h │ │ ├── CPowerRequest.cpp │ │ ├── CPowerRequest.h │ │ ├── CallForwarder.h │ │ ├── IDataObjectUtils.cpp │ │ ├── IDataObjectUtils.h │ │ ├── ProcessUtils.h │ │ ├── ProfileCache.h │ │ ├── StdAfx.cpp │ │ ├── StdAfx.h │ │ ├── ThreadUtils.h │ │ ├── VisUtils.cpp │ │ ├── VisUtils.h │ │ ├── bitreader_helper.h │ │ ├── cfg_guidlist.h │ │ ├── clipboard.cpp │ │ ├── clipboard.h │ │ ├── create_directory_helper.cpp │ │ ├── create_directory_helper.h │ │ ├── cue_creator.cpp │ │ ├── cue_creator.h │ │ ├── cue_parser.cpp │ │ ├── cue_parser.h │ │ ├── cue_parser_embedding.cpp │ │ ├── cuesheet_index_list.cpp │ │ ├── cuesheet_index_list.h │ │ ├── dialog_resize_helper.cpp │ │ ├── dialog_resize_helper.h │ │ ├── dropdown_helper.cpp │ │ ├── dropdown_helper.h │ │ ├── dynamic_bitrate_helper.cpp │ │ ├── dynamic_bitrate_helper.h │ │ ├── fb2k_threads.h │ │ ├── file_cached.h │ │ ├── file_info_const_impl.cpp │ │ ├── file_info_const_impl.h │ │ ├── file_list_helper.cpp │ │ ├── file_list_helper.h │ │ ├── file_move_helper.cpp │ │ ├── file_move_helper.h │ │ ├── file_win32_wrapper.cpp │ │ ├── file_win32_wrapper.h │ │ ├── filetimetools.cpp │ │ ├── filetimetools.h │ │ ├── foobar2000_sdk_helpers.vcxproj │ │ ├── foobar2000_sdk_helpers.vcxproj.filters │ │ ├── fullFileBuffer.h │ │ ├── helpers.h │ │ ├── icon_remapping_wildcard.h │ │ ├── input_helpers.cpp │ │ ├── input_helpers.h │ │ ├── listview_helper.cpp │ │ ├── listview_helper.h │ │ ├── meta_table_builder.h │ │ ├── metadb_io_hintlist.cpp │ │ ├── metadb_io_hintlist.h │ │ ├── mp3_utils.cpp │ │ ├── mp3_utils.h │ │ ├── playlist_position_reference_tracker.h │ │ ├── seekabilizer.cpp │ │ ├── seekabilizer.h │ │ ├── stream_buffer_helper.cpp │ │ ├── stream_buffer_helper.h │ │ ├── string_filter.h │ │ ├── text_file_loader.cpp │ │ ├── text_file_loader.h │ │ ├── win32_dialog.cpp │ │ ├── win32_dialog.h │ │ ├── win32_misc.cpp │ │ ├── win32_misc.h │ │ ├── window_placement_helper.cpp │ │ ├── window_placement_helper.h │ │ ├── writer_wav.cpp │ │ └── writer_wav.h │ └── shared │ │ ├── audio_math.h │ │ ├── fb2kdebug.h │ │ ├── filedialogs.h │ │ ├── shared.h │ │ ├── shared.lib │ │ └── win32_misc.h ├── pfc │ ├── Android.mk │ ├── alloc.h │ ├── array.h │ ├── audio_math.cpp │ ├── audio_sample.cpp │ ├── audio_sample.h │ ├── avltree.h │ ├── base64.cpp │ ├── base64.h │ ├── binary_search.h │ ├── bit_array.cpp │ ├── bit_array.h │ ├── bit_array_impl.h │ ├── bit_array_impl_part2.h │ ├── bsearch.cpp │ ├── bsearch.h │ ├── bsearch_inline.h │ ├── byte_order_helper.h │ ├── chain_list_v2.h │ ├── com_ptr_t.h │ ├── cpuid.cpp │ ├── cpuid.h │ ├── event.h │ ├── filehandle.cpp │ ├── filehandle.h │ ├── guid.cpp │ ├── guid.h │ ├── instance_tracker.h │ ├── int_types.h │ ├── iterators.h │ ├── list.h │ ├── makefile │ ├── map.h │ ├── mem_block_mgr.h │ ├── memalign.h │ ├── nix-objects.cpp │ ├── nix-objects.h │ ├── obj-c.mm │ ├── order_helper.h │ ├── other.cpp │ ├── other.h │ ├── pathUtils.cpp │ ├── pathUtils.h │ ├── pfc-license.txt │ ├── pfc-readme.txt │ ├── pfc.h │ ├── pfc.vcxproj │ ├── pfc.vcxproj.filters │ ├── pp-gettickcount.h │ ├── pp-winapi.h │ ├── primitives.h │ ├── primitives_part2.h │ ├── printf.cpp │ ├── ptr_list.h │ ├── rcptr.h │ ├── ref_counter.h │ ├── selftest.cpp │ ├── sort.cpp │ ├── sort.h │ ├── stdafx.cpp │ ├── string8_impl.h │ ├── stringNew.cpp │ ├── stringNew.h │ ├── string_base.cpp │ ├── string_base.h │ ├── string_conv.cpp │ ├── string_conv.h │ ├── string_list.h │ ├── syncd_storage.h │ ├── synchro_nix.cpp │ ├── synchro_nix.h │ ├── synchro_win.h │ ├── threads.cpp │ ├── threads.h │ ├── timers.cpp │ ├── timers.h │ ├── traits.h │ ├── utf8.cpp │ ├── wildcard.cpp │ ├── wildcard.h │ ├── win-objects.cpp │ └── win-objects.h ├── sdk-license.txt ├── sdk-readme.css └── sdk-readme.html └── libspotify ├── ChangeLog ├── LICENSE ├── README ├── docs └── images │ ├── spotify-core-logo-128x128.png │ └── spotify-core.txt ├── examples ├── Makefile ├── Randomify │ ├── English.lproj │ │ ├── InfoPlist.strings │ │ └── MainMenu.xib │ ├── Randomify-Info.plist │ ├── Randomify.xcodeproj │ │ └── project.pbxproj │ ├── RandomifyAppDelegate.h │ ├── RandomifyAppDelegate.m │ ├── Randomify_Prefix.pch │ ├── SpotifyPlaylist.h │ ├── SpotifyPlaylist.m │ ├── SpotifySession.h │ ├── SpotifySession.m │ ├── SpotifyTrack.h │ ├── SpotifyTrack.m │ └── main.m ├── appkey.c ├── common.mk ├── jukebox │ ├── Makefile │ ├── alsa-audio.c │ ├── audio.c │ ├── audio.h │ ├── dummy-audio.c │ ├── jukebox.c │ ├── openal-audio.c │ ├── osx-audio.c │ ├── osx │ │ └── jukebox.xcodeproj │ │ │ └── project.pbxproj │ ├── playtrack.c │ └── queue.h ├── localfiles │ ├── Makefile │ ├── main.c │ └── main.h ├── spshell │ ├── Makefile │ ├── browse.c │ ├── cmd.c │ ├── cmd.h │ ├── inbox.c │ ├── osx │ │ └── spshell.xcodeproj │ │ │ └── project.pbxproj │ ├── playlist.c │ ├── scrobbling.c │ ├── search.c │ ├── spshell.c │ ├── spshell.h │ ├── spshell_posix.c │ ├── spshell_win32.c │ ├── star.c │ ├── test.c │ ├── toplist.c │ └── win32 │ │ ├── spshell.vcproj │ │ ├── spshell.vcxproj │ │ └── spshell.vcxproj.filters └── stub │ ├── Makefile │ ├── main.c │ └── main.h ├── include └── libspotify │ └── api.h ├── lib ├── libspotify.dll └── libspotify.lib └── licenses.xhtml /.gitignore: -------------------------------------------------------------------------------- 1 | *.opensdf 2 | *.sdf 3 | *.suo 4 | *.vcxproj.user 5 | Debug 6 | Release 7 | /foobar2000 8 | ipch 9 | package 10 | *.db 11 | *.opendb 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # foo_input_spotify 2 | 3 | Spotify support for foobar2000. Requires a Spotify premium account. 4 | 5 | ![build status](https://ci.appveyor.com/api/projects/status/github/stengerh/foo_input_spotify?branch=master&svg=true) 6 | 7 | Last successful build: [foo_input_spotify.fb2k-component](https://ci.appveyor.com/api/projects/stengerh/foo-input-spotify/artifacts/Release%2ffoo_input_spotify.fb2k-component) ([debug symbols](https://ci.appveyor.com/api/projects/stengerh/foo-input-spotify/artifacts/Release%2ffoo_input_spotify-pdb.7z)) 8 | 9 | Wiki: https://github.com/FauxFaux/foo_input_spotify/wiki 10 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.0.4.{build} 2 | configuration: Release 3 | build: 4 | project: foo_input_spotify.sln 5 | verbosity: minimal 6 | before_package: 7 | - cmd: >- 8 | cd %configuration% 9 | 10 | cp ..\libspotify\lib\libspotify.dll . 11 | 12 | 7z a -tzip foo_input_spotify.fb2k-component *.dll 13 | 14 | 7z a foo_input_spotify-pdb.7z *.pdb 15 | artifacts: 16 | - path: $(configuration)/foo_input_spotify.fb2k-component 17 | name: foo_input_spotify 18 | - path: $(configuration)/foo_input_spotify-pdb.7z 19 | name: foo_input_spotify-pdb 20 | -------------------------------------------------------------------------------- /foo_input_spotify/SpotifySession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util.h" 4 | #include 5 | 6 | struct SpotifyThreadData { 7 | SpotifyThreadData(CriticalSection &cs) : cs(cs) { 8 | } 9 | 10 | HANDLE processEventsEvent; 11 | CriticalSection &cs; 12 | sp_session *sess; 13 | }; 14 | 15 | #if defined(_MSC_VER) 16 | #if _MSC_VER < 1900 17 | #define POINTER_ALIGN __declspec(align(__alignof(PVOID))) 18 | #else 19 | #define POINTER_ALIGN alignas(alignof(PVOID)) 20 | #endif 21 | #else 22 | #error PORTME 23 | #endif 24 | 25 | class SpotifySession { 26 | sp_session *sp; 27 | SpotifyThreadData threadData; 28 | CriticalSection spotifyCS; 29 | HANDLE processEventsEvent; 30 | POINTER_ALIGN volatile PVOID decoderOwner; 31 | CriticalSection loginCS; 32 | ConditionVariable loginCondVar; 33 | bool loggingIn; 34 | bool loggedIn; 35 | 36 | SpotifySession(); 37 | ~SpotifySession(); 38 | 39 | public: 40 | static SpotifySession & instance(); 41 | 42 | Buffer buf; 43 | 44 | sp_session *getAnyway(); 45 | 46 | sp_session *get(abort_callback & p_abort); 47 | 48 | CriticalSection &getSpotifyCS(); 49 | 50 | void showLoginUI(sp_error last_login_result = SP_ERROR_OK); 51 | void requireLoggedIn(); 52 | void waitForLogin(abort_callback & p_abort); 53 | 54 | void onLoggedIn(sp_error err); 55 | void onLoggedOut(); 56 | 57 | void processEvents(); 58 | 59 | void takeDecoder(void *owner); 60 | void ensureDecoder(void *owner); 61 | void releaseDecoder(void *owner); 62 | bool hasDecoder(void *owner); 63 | }; 64 | 65 | void assertSucceeds(pfc::string8 msg, sp_error err); 66 | -------------------------------------------------------------------------------- /foo_input_spotify/boost/noncopyable.hpp: -------------------------------------------------------------------------------- 1 | // Boost noncopyable.hpp header file --------------------------------------// 2 | 3 | // (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost 4 | // Software License, Version 1.0. (See accompanying file 5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // See http://www.boost.org/libs/utility for documentation. 8 | 9 | #ifndef BOOST_NONCOPYABLE_HPP_INCLUDED 10 | #define BOOST_NONCOPYABLE_HPP_INCLUDED 11 | 12 | namespace boost { 13 | 14 | // Private copy constructor and copy assignment ensure classes derived from 15 | // class noncopyable cannot be copied. 16 | 17 | // Contributed by Dave Abrahams 18 | 19 | namespace noncopyable_ // protection from unintended ADL 20 | { 21 | class noncopyable 22 | { 23 | protected: 24 | noncopyable() {} 25 | ~noncopyable() {} 26 | private: // emphasize the following members are private 27 | noncopyable( const noncopyable& ); 28 | const noncopyable& operator=( const noncopyable& ); 29 | }; 30 | } 31 | 32 | typedef noncopyable_::noncopyable noncopyable; 33 | 34 | } // namespace boost 35 | 36 | #endif // BOOST_NONCOPYABLE_HPP_INCLUDED 37 | -------------------------------------------------------------------------------- /foo_input_spotify/cred_prompt.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "util.h" 4 | #include "cred_prompt.h" 5 | 6 | #include 7 | #include 8 | 9 | std::vector previousUsername; 10 | 11 | std::auto_ptr credPrompt(const char * msg) { 12 | std::auto_ptr cpr(new CredPromptResult()); 13 | 14 | CREDUI_INFOW cui; 15 | WCHAR pszMessageText[CREDUI_MAX_MESSAGE_LENGTH]; 16 | WCHAR pszName[CREDUI_MAX_USERNAME_LENGTH + 1]; 17 | WCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH + 1]; 18 | BOOL fSave; 19 | 20 | if (msg != nullptr) { 21 | wcscpy_s(pszMessageText, pfc::stringcvt::string_wide_from_utf8(msg)); 22 | } 23 | else { 24 | wcscpy_s(pszMessageText, L"Please enter your Spotify username and password."); 25 | } 26 | 27 | cui.cbSize = sizeof(CREDUI_INFO); 28 | cui.hwndParent = core_api::get_main_window(); 29 | // Ensure that MessageText and CaptionText identify what credentials 30 | // to use and which application requires them. 31 | cui.pszMessageText = pszMessageText; 32 | cui.pszCaptionText = L"Sign in to Spotify"; 33 | cui.hbmBanner = NULL; 34 | fSave = FALSE; 35 | SecureZeroMemory(pszName, sizeof(pszName)); 36 | SecureZeroMemory(pszPwd, sizeof(pszPwd)); 37 | const DWORD dwErr = CredUIPromptForCredentialsW( 38 | &cui, // CREDUI_INFO structure 39 | TEXT("foo_input_spotify"), // Target for credentials 40 | NULL, // Reserved 41 | 0, // Reason 42 | pszName, // User name 43 | CREDUI_MAX_USERNAME_LENGTH + 1, // Max number of char for user name 44 | pszPwd, // Password 45 | CREDUI_MAX_PASSWORD_LENGTH + 1, // Max number of char for password 46 | &fSave, // State of save check box 47 | CREDUI_FLAGS_GENERIC_CREDENTIALS | // flags 48 | CREDUI_FLAGS_ALWAYS_SHOW_UI | 49 | CREDUI_FLAGS_DO_NOT_PERSIST); 50 | 51 | if (dwErr == NO_ERROR) 52 | { 53 | pfc::stringcvt::convert_wide_to_utf8(cpr->un.data(), CRED_BUF_SIZE, pszName, sizeof(pszName)); 54 | pfc::stringcvt::convert_wide_to_utf8(cpr->pw.data(), CRED_BUF_SIZE, pszPwd, sizeof(pszPwd)); 55 | cpr->save = (fSave != FALSE); 56 | 57 | SecureZeroMemory(pszName, sizeof(pszName)); 58 | SecureZeroMemory(pszPwd, sizeof(pszPwd)); 59 | } 60 | else if (dwErr == ERROR_CANCELLED) 61 | { 62 | cpr->cancelled = true; 63 | } 64 | return cpr; 65 | } -------------------------------------------------------------------------------- /foo_input_spotify/cred_prompt.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../pfc/pfc.h" 3 | 4 | const size_t CRED_BUF_SIZE = 0xff; 5 | 6 | struct CredPromptResult : boost::noncopyable { 7 | CredPromptResult() : 8 | un(std::vector(CRED_BUF_SIZE)), 9 | pw(std::vector(CRED_BUF_SIZE)), 10 | save(false), 11 | cancelled(false) { 12 | } 13 | 14 | ~CredPromptResult() { 15 | SecureZeroMemory(pw.data(), pw.size()); 16 | } 17 | 18 | std::vector un, pw; 19 | bool save; 20 | bool cancelled; 21 | }; 22 | 23 | std::auto_ptr credPrompt(const char * msg); 24 | -------------------------------------------------------------------------------- /foo_input_spotify/foo_input_spotify.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /foo_input_spotify/key-930.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | const uint8_t g_appkey[] = { 4 | 0x01, 0xF8, 0x35, 0x9D, 0x45, 0x52, 0xD7, 0xA5, 0xC2, 0x91, 0xC0, 0x94, 0x18, 0x52, 0x81, 0x28, 5 | 0x6A, 0xA4, 0xAE, 0x77, 0x4B, 0xE9, 0x87, 0xC9, 0x05, 0x2D, 0x72, 0x11, 0xC2, 0x59, 0x18, 0x6F, 6 | 0xB3, 0x91, 0x4E, 0x63, 0xCE, 0x6E, 0xDA, 0xF5, 0xE3, 0xC7, 0xC6, 0xC9, 0x3B, 0x88, 0x37, 0x31, 7 | 0x3C, 0xDA, 0x71, 0xF1, 0x4C, 0x68, 0x03, 0x1B, 0xF8, 0xC0, 0x4A, 0xBA, 0x20, 0x0B, 0xBE, 0xC4, 8 | 0x2F, 0x49, 0x7A, 0xC5, 0x5C, 0xC4, 0x36, 0xF1, 0x94, 0xF7, 0xC6, 0x4F, 0x27, 0xFB, 0x5E, 0x31, 9 | 0x00, 0x31, 0x53, 0x52, 0x74, 0x0B, 0x64, 0x16, 0x4B, 0x70, 0xA6, 0x71, 0x6D, 0xC0, 0x71, 0x7F, 10 | 0x6B, 0xFD, 0xE5, 0xA4, 0x57, 0x99, 0x4A, 0x11, 0xB0, 0x0B, 0xBA, 0xC4, 0xF2, 0x9A, 0xB9, 0x33, 11 | 0xC7, 0x5F, 0x70, 0x6D, 0x73, 0xEA, 0xAB, 0x88, 0xD2, 0x83, 0xAC, 0x33, 0xA7, 0xFE, 0xDA, 0xD7, 12 | 0xF2, 0xAC, 0x04, 0x41, 0xAC, 0x7D, 0xEF, 0x88, 0x5A, 0x21, 0xEC, 0xD8, 0x02, 0x40, 0xB7, 0x0C, 13 | 0x3A, 0x42, 0x2C, 0x26, 0x17, 0x9D, 0x82, 0x43, 0x50, 0x07, 0x1F, 0x2E, 0xAF, 0x72, 0x88, 0x65, 14 | 0xDB, 0xA7, 0x83, 0xA6, 0x44, 0x06, 0x2E, 0x55, 0x08, 0xF2, 0x4C, 0x4A, 0x96, 0xF7, 0xD5, 0xFC, 15 | 0x57, 0x75, 0x5F, 0x1C, 0x1D, 0xB1, 0x35, 0x5A, 0x48, 0x83, 0x1F, 0x60, 0x65, 0xBD, 0x40, 0xDD, 16 | 0x03, 0x1D, 0x3A, 0x4E, 0xD6, 0xA8, 0xB8, 0x5E, 0xFC, 0x60, 0x59, 0xE0, 0xB3, 0xC5, 0x64, 0xD0, 17 | 0x2A, 0x20, 0x48, 0x24, 0x5E, 0x9B, 0xE4, 0xF0, 0x45, 0xAA, 0x30, 0xCE, 0xB3, 0x11, 0x45, 0xB0, 18 | 0x01, 0xDA, 0x82, 0x58, 0xFE, 0x4F, 0x97, 0xF2, 0x40, 0x4D, 0x8C, 0x83, 0x17, 0x8C, 0x97, 0xCF, 19 | 0x40, 0x17, 0xDB, 0xC7, 0x19, 0xEC, 0xFA, 0x01, 0x4F, 0xE6, 0x78, 0x3A, 0x54, 0x3F, 0xE9, 0x62, 20 | 0xA3, 0xF2, 0xDD, 0x0A, 0xDD, 0x90, 0xE4, 0x24, 0xE7, 0x57, 0x8C, 0x30, 0x18, 0x13, 0xA6, 0x9C, 21 | 0x52, 0x7D, 0xBE, 0x0B, 0x10, 0xEA, 0x0C, 0x53, 0x87, 0x9B, 0x26, 0xBA, 0xA7, 0x70, 0xAE, 0x88, 22 | 0x8A, 0xAA, 0x5E, 0x7C, 0x73, 0xC3, 0x08, 0x92, 0x29, 0xDC, 0xEA, 0x22, 0x25, 0x16, 0xB5, 0xF0, 23 | 0x89, 0xF0, 0x88, 0xBE, 0xAB, 0x84, 0x6C, 0xFE, 0xF1, 0xBE, 0x8A, 0x81, 0x19, 0x0A, 0xE7, 0x64, 24 | 0xC4, 25 | }; 26 | const size_t g_appkey_size = sizeof(g_appkey); -------------------------------------------------------------------------------- /foo_input_spotify/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /foo_input_spotify/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "targetver.h" 4 | 5 | #define STRICT 6 | #include 7 | 8 | #include 9 | #include 10 | -------------------------------------------------------------------------------- /foo_input_spotify/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | 10 | #define _WIN32_WINNT 0x0600 11 | 12 | #include 13 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/ATLHelpers.h: -------------------------------------------------------------------------------- 1 | #ifndef _8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 2 | #define _8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 3 | 4 | #define _SECURE_ATL 1 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "../SDK/foobar2000.h" 16 | #include "../helpers/helpers.h" 17 | 18 | #include "WTL-PP.h" 19 | #include "misc.h" 20 | #include "GDIUtils.h" 21 | 22 | #include "WindowPositionUtils.h" 23 | #include "CDialogResizeHelper.h" 24 | 25 | #include "BumpableElem.h" 26 | 27 | #include "inplace_edit.h" 28 | #include "inplace_edit_v2.h" 29 | 30 | #include "AutoComplete.h" 31 | 32 | #endif //_8251B63D_2C1C_4e9d_9320_4E12E46331CB_ 33 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/AutoComplete.h: -------------------------------------------------------------------------------- 1 | HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt & var, const char * initVal); 2 | HRESULT InitializeEditAC(HWND edit, const char * values, DWORD opts = ACO_AUTOAPPEND|ACO_AUTOSUGGEST); 3 | HRESULT InitializeEditAC(HWND edit, pfc::const_iterator valueEnum, DWORD opts = ACO_AUTOAPPEND|ACO_AUTOSUGGEST); 4 | HRESULT InitializeSimpleAC(HWND edit, IUnknown * vals, DWORD opts); 5 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 6 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 7 | pfc::com_ptr_t CreateACList(pfc::const_iterator valueEnum); 8 | pfc::com_ptr_t CreateACList(); 9 | void CreateACList_AddItem(IUnknown * theList, const char * item); 10 | 11 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/BumpableElem.h: -------------------------------------------------------------------------------- 1 | template 2 | class ImplementBumpableElem : public TClass { 3 | private: 4 | typedef ImplementBumpableElem TSelf; 5 | public: 6 | TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(ImplementBumpableElem, TClass, {_init();} ) 7 | 8 | BEGIN_MSG_MAP_EX(ImplementBumpableElem) 9 | MSG_WM_DESTROY(OnDestroy) 10 | CHAIN_MSG_MAP(__super) 11 | END_MSG_MAP_HOOK() 12 | 13 | void notify(const GUID & p_what, t_size p_param1, const void * p_param2, t_size p_param2size) { 14 | if (p_what == ui_element_notify_visibility_changed && p_param2 == 0 && m_flash.m_hWnd != NULL) m_flash.Deactivate(); 15 | __super::notify(p_what, p_param1, p_param2, p_param2size); 16 | } 17 | 18 | static bool Bump() { 19 | for(pfc::const_iterator walk = instances.first(); walk.is_valid(); ++walk) { 20 | if ((*walk)->_bump()) return true; 21 | } 22 | return false; 23 | } 24 | ~ImplementBumpableElem() throw() { 25 | PFC_ASSERT(core_api::is_main_thread()); 26 | instances -= this; 27 | } 28 | private: 29 | void OnDestroy() throw() { 30 | m_selfDestruct = true; 31 | m_flash.CleanUp(); 32 | SetMsgHandled(FALSE); 33 | } 34 | bool _bump() { 35 | if (m_selfDestruct || m_hWnd == NULL) return false; 36 | //PROBLEM: This assumes we're implementing service_base methods at this point. Explodes if called during constructors/destructors. 37 | if (!this->m_callback->request_activation(this)) return false; 38 | m_flash.Activate(*this); 39 | this->set_default_focus(); 40 | return true; 41 | } 42 | void _init() { 43 | m_selfDestruct = false; 44 | PFC_ASSERT(core_api::is_main_thread()); 45 | instances += this; 46 | } 47 | static pfc::avltree_t instances; 48 | bool m_selfDestruct; 49 | CFlashWindow m_flash; 50 | }; 51 | 52 | template 53 | pfc::avltree_t *> ImplementBumpableElem::instances; 54 | 55 | 56 | template class ui_element_impl_withpopup : public ui_element_impl, TInterface> { 57 | public: 58 | t_uint32 get_flags() {return KFlagHavePopupCommand | KFlagSupportsBump;} 59 | bool bump() {return ImplementBumpableElem::Bump();} 60 | }; 61 | 62 | template class ui_element_impl_visualisation : public ui_element_impl, TInterface> { 63 | public: 64 | t_uint32 get_flags() {return KFlagsVisualisation | KFlagSupportsBump;} 65 | bool bump() {return ImplementBumpableElem::Bump();} 66 | }; 67 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/CDialogResizeHelper.h: -------------------------------------------------------------------------------- 1 | class CDialogResizeHelper { 2 | public: 3 | typedef dialog_resize_helper::param ParamOld; 4 | 5 | struct Param { 6 | t_uint32 id; 7 | float snapLeft, snapTop, snapRight, snapBottom; 8 | }; 9 | private: 10 | void AddSizeGrip(); 11 | public: 12 | inline void set_min_size(unsigned x,unsigned y) {min_x = x; min_y = y;} 13 | inline void set_max_size(unsigned x,unsigned y) {max_x = x; max_y = y;} 14 | 15 | 16 | BEGIN_MSG_MAP_EX(CDialogResizeHelper) 17 | if (uMsg == WM_INITDIALOG) OnInitDialog(hWnd); 18 | MSG_WM_SIZE(OnSize) 19 | MSG_WM_DESTROY(OnDestroy) 20 | MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo) 21 | END_MSG_MAP() 22 | 23 | template CDialogResizeHelper(const TParam (& src)[paramCount],CRect const& minMaxRange = CRect(0,0,0,0)) { 24 | InitTable(src, paramCount); 25 | InitMinMax(minMaxRange); 26 | } 27 | 28 | void InitTable(const Param* table, t_size tableSize); 29 | void InitTable(const ParamOld * table, t_size tableSize); 30 | void InitMinMax(const CRect & range); 31 | 32 | bool EvalRect(UINT id, CRect & out) const; 33 | 34 | private: 35 | bool _EvalRect(t_size index, CSize wndSize, CRect & out) const; 36 | void OnGetMinMaxInfo(LPMINMAXINFO lpMMI) const; 37 | void OnSize(UINT nType, CSize size); 38 | void OnInitDialog(CWindow thisWnd); 39 | void OnDestroy(); 40 | 41 | pfc::array_t m_table; 42 | pfc::map_t m_origRects; 43 | CRect m_rcOrigClient; 44 | CWindow m_thisWnd, m_sizeGrip; 45 | unsigned min_x,min_y,max_x,max_y; 46 | }; 47 | 48 | template class CDialogResizeHelperTracking : public CDialogResizeHelper { 49 | public: 50 | template CDialogResizeHelperTracking(const TParam (& src)[paramCount],CRect const& minMaxRange, TCfgVar & cfgVar) : CDialogResizeHelper(src, minMaxRange), m_tracker(cfgVar) {} 51 | 52 | BEGIN_MSG_MAP_EX(CDialogResizeHelperST) 53 | CHAIN_MSG_MAP(CDialogResizeHelper) 54 | CHAIN_MSG_MAP_MEMBER(m_tracker) 55 | END_MSG_MAP() 56 | 57 | private: 58 | TTracker m_tracker; 59 | }; 60 | 61 | typedef CDialogResizeHelperTracking CDialogResizeHelperST; 62 | typedef CDialogResizeHelperTracking CDialogResizeHelperPT; 63 | 64 | #define REDRAW_DIALOG_ON_RESIZE() if (uMsg == WM_SIZE) RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); 65 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/misc.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | void PaintSeparatorControl(CWindow wnd) { 4 | CPaintDC dc(wnd); 5 | TCHAR buffer[512] = {}; 6 | wnd.GetWindowText(buffer, _countof(buffer)); 7 | const int txLen = pfc::strlen_max_t(buffer, _countof(buffer)); 8 | CRect contentRect; 9 | WIN32_OP_D( wnd.GetClientRect(contentRect) ); 10 | 11 | dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); 12 | dc.SetBkMode(TRANSPARENT); 13 | 14 | { 15 | CBrushHandle brush = (HBRUSH) wnd.GetParent().SendMessage(WM_CTLCOLORSTATIC, (WPARAM) (HDC) dc, (LPARAM) wnd.m_hWnd); 16 | if (brush != NULL) dc.FillRect(contentRect, brush); 17 | } 18 | SelectObjectScope scopeFont(dc, wnd.GetFont()); 19 | 20 | if (txLen > 0) { 21 | CRect rcText(contentRect); 22 | WIN32_OP_D( dc.DrawText(buffer,txLen,rcText,DT_NOPREFIX | DT_END_ELLIPSIS | DT_SINGLELINE | DT_VCENTER | DT_LEFT ) > 0); 23 | } 24 | 25 | SIZE txSize, probeSize; 26 | const TCHAR probe[] = _T("#"); 27 | if (dc.GetTextExtent(buffer,txLen,&txSize) && dc.GetTextExtent(probe, _countof(probe), &probeSize)) { 28 | int spacing = txSize.cx > 0 ? (probeSize.cx / 4) : 0; 29 | if (txSize.cx + spacing < contentRect.Width()) { 30 | const CPoint center = contentRect.CenterPoint(); 31 | CRect rcEdge(contentRect.left + txSize.cx + spacing, center.y, contentRect.right, contentRect.bottom); 32 | WIN32_OP_D( dc.DrawEdge(rcEdge, EDGE_ETCHED, BF_TOP) ); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // foobar2000_ATL_helpers.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/ATLHelpers/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. 9 | #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. 10 | #endif 11 | 12 | 13 | // TODO: reference additional headers your program requires here 14 | 15 | #include "ATLHelpers.h" 16 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/abort_callback.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void abort_callback::check() const { 4 | if (is_aborting()) throw exception_aborted(); 5 | } 6 | 7 | void abort_callback::sleep(double p_timeout_seconds) const { 8 | if (!sleep_ex(p_timeout_seconds)) throw exception_aborted(); 9 | } 10 | 11 | bool abort_callback::sleep_ex(double p_timeout_seconds) const { 12 | // return true IF NOT SET (timeout), false if set 13 | return !pfc::event::g_wait_for(get_abort_event(),p_timeout_seconds); 14 | } 15 | 16 | bool abort_callback::waitForEvent( pfc::eventHandle_t evtHandle, double timeOut ) { 17 | int status = pfc::event::g_twoEventWait( this->get_abort_event(), evtHandle, timeOut ); 18 | switch(status) { 19 | case 1: throw exception_aborted(); 20 | case 2: return true; 21 | case 0: return false; 22 | default: uBugCheck(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/advconfig.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | 4 | t_uint32 advconfig_entry::get_preferences_flags_() { 5 | { 6 | advconfig_entry_string_v2::ptr ex; 7 | if (service_query_t(ex)) return ex->get_preferences_flags(); 8 | } 9 | { 10 | advconfig_entry_checkbox_v2::ptr ex; 11 | if (service_query_t(ex)) return ex->get_preferences_flags(); 12 | } 13 | return 0; 14 | } 15 | 16 | bool advconfig_entry_checkbox::get_default_state_() { 17 | { 18 | advconfig_entry_checkbox_v2::ptr ex; 19 | if (service_query_t(ex)) return ex->get_default_state(); 20 | } 21 | 22 | bool backup = get_state(); 23 | reset(); 24 | bool rv = get_state(); 25 | set_state(backup); 26 | return rv; 27 | } 28 | 29 | void advconfig_entry_string::get_default_state_(pfc::string_base & out) { 30 | { 31 | advconfig_entry_string_v2::ptr ex; 32 | if (service_query_t(ex)) {ex->get_default_state(out); return;} 33 | } 34 | pfc::string8 backup; 35 | get_state(backup); 36 | reset(); 37 | get_state(out); 38 | set_state(backup); 39 | } 40 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/album_art.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool album_art_editor::g_get_interface(service_ptr_t & out,const char * path) { 4 | service_enum_t e; ptr ptr; 5 | pfc::string_extension ext(path); 6 | while(e.next(ptr)) { 7 | if (ptr->is_our_path(path,ext)) { out = ptr; return true; } 8 | } 9 | return false; 10 | } 11 | 12 | bool album_art_editor::g_is_supported_path(const char * path) { 13 | ptr ptr; return g_get_interface(ptr,path); 14 | } 15 | 16 | album_art_editor_instance_ptr album_art_editor::g_open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) { 17 | album_art_editor::ptr obj; 18 | if (!g_get_interface(obj, p_path)) throw exception_album_art_unsupported_format(); 19 | return obj->open(p_filehint, p_path, p_abort); 20 | } 21 | 22 | 23 | bool album_art_extractor::g_get_interface(service_ptr_t & out,const char * path) { 24 | service_enum_t e; ptr ptr; 25 | pfc::string_extension ext(path); 26 | while(e.next(ptr)) { 27 | if (ptr->is_our_path(path,ext)) { out = ptr; return true; } 28 | } 29 | return false; 30 | } 31 | 32 | bool album_art_extractor::g_is_supported_path(const char * path) { 33 | ptr ptr; return g_get_interface(ptr,path); 34 | } 35 | album_art_extractor_instance_ptr album_art_extractor::g_open(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) { 36 | album_art_extractor::ptr obj; 37 | if (!g_get_interface(obj, p_path)) throw exception_album_art_unsupported_format(); 38 | return obj->open(p_filehint, p_path, p_abort); 39 | } 40 | 41 | 42 | album_art_extractor_instance_ptr album_art_extractor::g_open_allowempty(file_ptr p_filehint,const char * p_path,abort_callback & p_abort) { 43 | try { 44 | return g_open(p_filehint, p_path, p_abort); 45 | } catch(exception_album_art_not_found) { 46 | return new service_impl_t(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/app_close_blocker.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool app_close_blocker::g_query() 4 | { 5 | service_ptr_t ptr; 6 | service_enum_t e; 7 | while(e.next(ptr)) 8 | { 9 | if (!ptr->query()) return false; 10 | } 11 | return true; 12 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/audio_postprocessor.h: -------------------------------------------------------------------------------- 1 | //! This class handles conversion of audio data (audio_chunk) to various linear PCM types, with optional dithering. 2 | 3 | class NOVTABLE audio_postprocessor : public service_base 4 | { 5 | public: 6 | //! Processes one chunk of audio data. 7 | //! @param p_chunk Chunk of audio data to process. 8 | //! @param p_output Receives output linear signed PCM data. 9 | //! @param p_out_bps Desired bit depth of output. 10 | //! @param p_out_bps_physical Desired physical word width of output. Must be either 8, 16, 24 or 32, greater or equal to p_out_bps. This is typically set to same value as p_out_bps. 11 | //! @param p_dither Indicates whether dithering should be used. Note that dithering is CPU-heavy. 12 | //! @param p_prescale Value to scale all audio samples by when converting. Set to 1.0 to do nothing. 13 | 14 | virtual void run(const audio_chunk & p_chunk, 15 | mem_block_container & p_output, 16 | t_uint32 p_out_bps, 17 | t_uint32 p_out_bps_physical, 18 | bool p_dither, 19 | audio_sample p_prescale 20 | ) = 0; 21 | 22 | 23 | 24 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(audio_postprocessor); 25 | }; 26 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/cfg_var.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | cfg_var_reader * cfg_var_reader::g_list = NULL; 4 | cfg_var_writer * cfg_var_writer::g_list = NULL; 5 | 6 | void cfg_var_reader::config_read_file(stream_reader * p_stream,abort_callback & p_abort) 7 | { 8 | pfc::map_t vars; 9 | for(cfg_var_reader * walk = g_list; walk != NULL; walk = walk->m_next) { 10 | vars.set(walk->m_guid,walk); 11 | } 12 | for(;;) { 13 | 14 | GUID guid; 15 | t_uint32 size; 16 | 17 | if (p_stream->read(&guid,sizeof(guid),p_abort) != sizeof(guid)) break; 18 | guid = pfc::byteswap_if_be_t(guid); 19 | p_stream->read_lendian_t(size,p_abort); 20 | 21 | cfg_var_reader * var; 22 | if (vars.query(guid,var)) { 23 | stream_reader_limited_ref wrapper(p_stream,size); 24 | try { 25 | var->set_data_raw(&wrapper,size,p_abort); 26 | } catch(exception_io_data) {} 27 | wrapper.flush_remaining(p_abort); 28 | } else { 29 | p_stream->skip_object(size,p_abort); 30 | } 31 | } 32 | } 33 | 34 | void cfg_var_writer::config_write_file(stream_writer * p_stream,abort_callback & p_abort) { 35 | cfg_var_writer * ptr; 36 | pfc::array_t temp; 37 | for(ptr = g_list; ptr; ptr = ptr->m_next) { 38 | temp.set_size(0); 39 | { 40 | stream_writer_buffer_append_ref_t > stream(temp); 41 | ptr->get_data_raw(&stream,p_abort); 42 | } 43 | p_stream->write_lendian_t(ptr->m_guid,p_abort); 44 | p_stream->write_lendian_t(pfc::downcast_guarded(temp.get_size()),p_abort); 45 | if (temp.get_size() > 0) { 46 | p_stream->write_object(temp.get_ptr(),temp.get_size(),p_abort); 47 | } 48 | } 49 | } 50 | 51 | 52 | void cfg_string::get_data_raw(stream_writer * p_stream,abort_callback & p_abort) { 53 | p_stream->write_object(get_ptr(),length(),p_abort); 54 | } 55 | 56 | void cfg_string::set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) { 57 | pfc::string8_fastalloc temp; 58 | p_stream->read_string_raw(temp,p_abort); 59 | set_string(temp); 60 | } 61 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/commandline.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void commandline_handler_metadb_handle::on_file(const char * url) { 4 | metadb_handle_list handles; 5 | try { 6 | static_api_ptr_t()->path_to_handles_simple(url, handles); 7 | } catch(std::exception const & e) { 8 | console::complain("Path evaluation failure", e); 9 | return; 10 | } 11 | for(t_size walk = 0; walk < handles.get_size(); ++walk) on_file(handles[walk]); 12 | } 13 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/commandline.h: -------------------------------------------------------------------------------- 1 | class NOVTABLE commandline_handler : public service_base 2 | { 3 | public: 4 | enum result 5 | { 6 | RESULT_NOT_OURS,//not our command 7 | RESULT_PROCESSED,//command processed 8 | RESULT_PROCESSED_EXPECT_FILES,//command processed, we want to takeover file urls after this command 9 | }; 10 | virtual result on_token(const char * token)=0; 11 | virtual void on_file(const char * url) {};//optional 12 | virtual void on_files_done() {};//optional 13 | virtual bool want_directories() {return false;} 14 | 15 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(commandline_handler); 16 | }; 17 | 18 | class commandline_handler_metadb_handle : public commandline_handler//helper 19 | { 20 | protected: 21 | virtual void on_file(const char * url); 22 | virtual bool want_directories() {return true;} 23 | public: 24 | virtual result on_token(const char * token)=0; 25 | virtual void on_files_done() {}; 26 | 27 | virtual void on_file(const metadb_handle_ptr & ptr)=0; 28 | }; 29 | 30 | /* 31 | 32 | how commandline_handler is used: 33 | 34 | scenario #1: 35 | creation => on_token() => deletion 36 | scenario #2: 37 | creation => on_token() returning RESULT_PROCESSED_EXPECT_FILES => on_file(), on_file().... => on_files_done() => deletion 38 | */ 39 | 40 | template 41 | class commandline_handler_factory_t : public service_factory_t {}; 42 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/component.h: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | // This is a helper class that gets reliably static-instantiated in all components so any special code that must be executed on startup can be shoved into its constructor. 4 | class foobar2000_component_globals { 5 | public: 6 | foobar2000_component_globals() { 7 | #ifdef _MSC_VER 8 | #ifndef _DEBUG 9 | ::OverrideCrtAbort(); 10 | #endif 11 | #endif 12 | } 13 | }; 14 | 15 | class NOVTABLE foobar2000_client 16 | { 17 | public: 18 | typedef service_factory_base* pservice_factory_base; 19 | 20 | enum { 21 | FOOBAR2000_CLIENT_VERSION_COMPATIBLE = 72, 22 | FOOBAR2000_CLIENT_VERSION = FOOBAR2000_TARGET_VERSION, 23 | }; 24 | virtual t_uint32 get_version() = 0; 25 | virtual pservice_factory_base get_service_list() = 0; 26 | 27 | virtual void get_config(stream_writer * p_stream,abort_callback & p_abort) = 0; 28 | virtual void set_config(stream_reader * p_stream,abort_callback & p_abort) = 0; 29 | virtual void set_library_path(const char * path,const char * name) = 0; 30 | virtual void services_init(bool val) = 0; 31 | virtual bool is_debug() = 0; 32 | protected: 33 | foobar2000_client() {} 34 | ~foobar2000_client() {} 35 | }; 36 | 37 | class NOVTABLE foobar2000_api { 38 | public: 39 | virtual service_class_ref service_enum_find_class(const GUID & p_guid) = 0; 40 | virtual bool service_enum_create(service_ptr_t & p_out,service_class_ref p_class,t_size p_index) = 0; 41 | virtual t_size service_enum_get_count(service_class_ref p_class) = 0; 42 | virtual HWND get_main_window()=0; 43 | virtual bool assert_main_thread()=0; 44 | virtual bool is_main_thread()=0; 45 | virtual bool is_shutting_down()=0; 46 | virtual const char * get_profile_path()=0; 47 | virtual bool is_initializing() = 0; 48 | 49 | //New in 0.9.6 50 | virtual bool is_portable_mode_enabled() = 0; 51 | virtual bool is_quiet_mode_enabled() = 0; 52 | protected: 53 | foobar2000_api() {} 54 | ~foobar2000_api() {} 55 | }; 56 | 57 | extern foobar2000_api * g_foobar2000_api; 58 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/component_client.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPONENT_CLIENT_H_ 2 | #define _COMPONENT_CLIENT_H_ 3 | 4 | 5 | 6 | #endif //_COMPONENT_CLIENT_H_ -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/components_menu.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPONENTS_MENU_H_ 2 | #define _COMPONENTS_MENU_H_ 3 | 4 | #error deprecated, see menu_item.h 5 | 6 | 7 | #endif -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/componentversion.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool component_installation_validator::test_my_name(const char * fn) { 4 | const char * path = core_api::get_my_full_path(); 5 | path += pfc::scan_filename(path); 6 | bool retVal = ( strcmp(path, fn) == 0 ); 7 | PFC_ASSERT( retVal ); 8 | return retVal; 9 | } 10 | bool component_installation_validator::have_other_file(const char * fn) { 11 | for(int retry = 0;;) { 12 | pfc::string_formatter path = core_api::get_my_full_path(); 13 | path.truncate(path.scan_filename()); 14 | path << fn; 15 | try { 16 | try { 17 | abort_callback_dummy aborter; 18 | bool v = filesystem::g_exists(path, aborter); 19 | PFC_ASSERT( v ); 20 | return v; 21 | } catch(std::exception const & e) { 22 | FB2K_console_formatter() << "Component integrity check error: " << e << " (on: " << fn << ")"; 23 | throw; 24 | } 25 | } catch(exception_io_denied) { 26 | continue; 27 | } catch(exception_io_sharing_violation) { 28 | continue; 29 | } catch(exception_io_file_corrupted) { // happens 30 | return false; 31 | } catch(...) { 32 | uBugCheck(); 33 | } 34 | if (++retry == 10) uBugCheck(); 35 | Sleep(100); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/config_io_callback.h: -------------------------------------------------------------------------------- 1 | //! Implementing this interface lets you maintain your own configuration files rather than depending on the cfg_var system. \n 2 | //! Note that you must not make assumptions about what happens first: config_io_callback::on_read(), initialization of cfg_var values or config_io_callback::on_read() in other components. Order of these things is undefined and will change with each run. \n 3 | //! Use service_factory_single_t to register your implementations. Do not call other people's implementations, core is responsible for doing that when appropriate. 4 | class NOVTABLE config_io_callback : public service_base { 5 | public: 6 | //! Called on startup. You can read your configuration file from here. \n 7 | //! Hint: use core_api::get_profile_path() to retrieve the path of the folder where foobar2000 configuration files are stored. 8 | virtual void on_read() = 0; 9 | //! Called typically on shutdown but you should expect a call at any point after on_read(). You can write your configuration file from here. 10 | //! Hint: use core_api::get_profile_path() to retrieve the path of the folder where foobar2000 configuration files are stored. 11 | //! @param reset If set to true, our configuration is being reset, so you should wipe your files rather than rewrite them with current configuration. 12 | virtual void on_write(bool reset) = 0; 13 | 14 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(config_io_callback); 15 | }; 16 | 17 | //! \since 1.0 18 | class NOVTABLE config_io_callback_v2 : public config_io_callback { 19 | FB2K_MAKE_SERVICE_INTERFACE(config_io_callback_v2, config_io_callback) 20 | public: 21 | //! Implement optionally. Called to quickly flush recent configuration changes. If your instance of config_io_callback needs to perform timeconsuming tasks when saving, you should skip implementing this method entirely. 22 | virtual void on_quicksave() = 0; 23 | }; 24 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/console.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | 4 | void console::info(const char * p_message) {print(p_message);} 5 | void console::error(const char * p_message) {complain("Error", p_message);} 6 | void console::warning(const char * p_message) {complain("Warning", p_message);} 7 | 8 | void console::info_location(const playable_location & src) {print_location(src);} 9 | void console::info_location(const metadb_handle_ptr & src) {print_location(src);} 10 | 11 | void console::print_location(const metadb_handle_ptr & src) 12 | { 13 | print_location(src->get_location()); 14 | } 15 | 16 | void console::print_location(const playable_location & src) 17 | { 18 | FB2K_console_formatter() << src; 19 | } 20 | 21 | void console::complain(const char * what, const char * msg) { 22 | FB2K_console_formatter() << what << ": " << msg; 23 | } 24 | void console::complain(const char * what, std::exception const & e) { 25 | complain(what, e.what()); 26 | } 27 | 28 | void console::print(const char* p_message) 29 | { 30 | if (core_api::are_services_available()) { 31 | service_ptr_t ptr; 32 | service_enum_t e; 33 | while(e.next(ptr)) ptr->print(p_message,~0); 34 | } 35 | } 36 | 37 | void console::printf(const char* p_format,...) 38 | { 39 | va_list list; 40 | va_start(list,p_format); 41 | printfv(p_format,list); 42 | va_end(list); 43 | } 44 | 45 | void console::printfv(const char* p_format,va_list p_arglist) 46 | { 47 | pfc::string8_fastalloc temp; 48 | uPrintfV(temp,p_format,p_arglist); 49 | print(temp); 50 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/console.h: -------------------------------------------------------------------------------- 1 | //! Namespace with functions for sending text to console. All functions are fully multi-thread safe, though they must not be called during dll initialization or deinitialization (e.g. static object constructors or destructors) when service system is not available. 2 | namespace console 3 | { 4 | void info(const char * p_message); 5 | void error(const char * p_message); 6 | void warning(const char * p_message); 7 | void info_location(const playable_location & src); 8 | void info_location(const metadb_handle_ptr & src); 9 | void print_location(const playable_location & src); 10 | void print_location(const metadb_handle_ptr & src); 11 | 12 | void print(const char*); 13 | void printf(const char*,...); 14 | void printfv(const char*,va_list p_arglist); 15 | 16 | //! Usage: console::formatter() << "blah " << somenumber << " asdf" << somestring; 17 | class formatter : public pfc::string_formatter { 18 | public: 19 | ~formatter() {if (!is_empty()) console::print(get_ptr());} 20 | }; 21 | #define FB2K_console_formatter() ::console::formatter()._formatter() 22 | 23 | void complain(const char * what, const char * msg); 24 | void complain(const char * what, std::exception const & e); 25 | 26 | class timer_scope { 27 | public: 28 | timer_scope(const char * name) : m_name(name) {m_timer.start();} 29 | ~timer_scope() { 30 | try { 31 | FB2K_console_formatter() << m_name << ": " << pfc::format_time_ex(m_timer.query(), 6); 32 | } catch(...) {} 33 | } 34 | private: 35 | pfc::hires_timer m_timer; 36 | const char * const m_name; 37 | }; 38 | }; 39 | 40 | //! Interface receiving console output. Do not call directly; use console namespace functions instead. 41 | class NOVTABLE console_receiver : public service_base { 42 | public: 43 | virtual void print(const char * p_message,t_size p_message_length) = 0; 44 | 45 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(console_receiver); 46 | }; 47 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/core_api.h: -------------------------------------------------------------------------------- 1 | #ifndef _FB2K_CORE_API_H_ 2 | #define _FB2K_CORE_API_H_ 3 | 4 | namespace core_api { 5 | 6 | //! Retrieves HINSTANCE of calling DLL. 7 | HINSTANCE get_my_instance(); 8 | //! Retrieves filename of calling dll, excluding extension, e.g. "foo_asdf" 9 | const char * get_my_file_name(); 10 | //! Retrieves full path of calling dll, e.g. file://c:\blah\foobar2000\foo_asdf.dll 11 | const char * get_my_full_path(); 12 | //! Retrieves main app window. WARNING: this is provided for parent of dialog windows and such only; using it for anything else (such as hooking windowproc to alter app behaviors) is absolutely illegal. 13 | HWND get_main_window(); 14 | //! Tests whether services are available at this time. They are not available only during DLL startup or shutdown (e.g. inside static object constructors or destructors). 15 | bool are_services_available(); 16 | //! Tests whether calling thread is main app thread, and shows diagnostic message in debugger output if it's not. 17 | bool assert_main_thread(); 18 | //! Triggers a bug check if the calling thread is not the main app thread. 19 | void ensure_main_thread(); 20 | //! Returns true if calling thread is main app thread, false otherwise. 21 | bool is_main_thread(); 22 | //! Returns whether the app is currently shutting down. 23 | bool is_shutting_down(); 24 | //! Returns whether the app is currently initializing. 25 | bool is_initializing(); 26 | //! Returns filesystem path to directory with user settings, e.g. file://c:\documents_and_settings\username\blah\foobar2000 27 | const char * get_profile_path(); 28 | 29 | //! Returns a path to in fb2k profile folder. 30 | inline pfc::string8 pathInProfile(const char * fileName) { pfc::string8 p( core_api::get_profile_path() ); p.add_filename( fileName ); return std::move(p); } 31 | 32 | //! Returns whether foobar2000 has been installed in "portable" mode. 33 | bool is_portable_mode_enabled(); 34 | 35 | //! Returns whether foobar2000 is currently running in quiet mode. \n 36 | //! Quiet mode bypasses all GUI features, disables Media Library and does not save any changes to app configuration. \n 37 | //! Your component should not display any forms of user interface when running in quiet mode, as well as avoid saving configuration on its own (no need to worry if you only rely on cfg_vars or config_io_callback, they will simply be ignored on shutdown). 38 | bool is_quiet_mode_enabled(); 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/coreversion.h: -------------------------------------------------------------------------------- 1 | class NOVTABLE core_version_info : public service_base { 2 | public: 3 | virtual const char * get_version_string() = 0; 4 | static const char * g_get_version_string() {return static_api_ptr_t()->get_version_string();} 5 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(core_version_info); 6 | }; 7 | 8 | struct t_core_version_data { 9 | t_uint32 m_major, m_minor1, m_minor2, m_minor3; 10 | }; 11 | 12 | //! New (0.9.4.2) 13 | class NOVTABLE core_version_info_v2 : public core_version_info { 14 | public: 15 | virtual const char * get_name() = 0;//"foobar2000" 16 | virtual const char * get_version_as_text() = 0;//"N.N.N.N" 17 | virtual t_core_version_data get_version() = 0; 18 | 19 | //! Determine whether running foobar2000 version is newer or equal to the specified version, eg. test_version(0,9,5,0) for 0.9.5. 20 | bool test_version(t_uint32 major, t_uint32 minor1, t_uint32 minor2, t_uint32 minor3) { 21 | const t_core_version_data v = get_version(); 22 | if (v.m_major < major) return false; 23 | else if (v.m_major > major) return true; 24 | // major version matches 25 | else if (v.m_minor1 < minor1) return false; 26 | else if (v.m_minor1 > minor1) return true; 27 | // minor1 version matches 28 | else if (v.m_minor2 < minor2) return false; 29 | else if (v.m_minor2 > minor2) return true; 30 | // minor2 version matches 31 | else if (v.m_minor3 < minor3) return false; 32 | else return true; 33 | } 34 | 35 | FB2K_MAKE_SERVICE_INTERFACE(core_version_info_v2, core_version_info); 36 | }; 37 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/event_logger.h: -------------------------------------------------------------------------------- 1 | class NOVTABLE event_logger : public service_base { 2 | FB2K_MAKE_SERVICE_INTERFACE(event_logger, service_base); 3 | public: 4 | enum { 5 | severity_status, 6 | severity_warning, 7 | severity_error 8 | }; 9 | void log_status(const char * line) {log_entry(line, severity_status);} 10 | void log_warning(const char * line) {log_entry(line, severity_warning);} 11 | void log_error(const char * line) {log_entry(line, severity_error);} 12 | 13 | virtual void log_entry(const char * line, unsigned severity) = 0; 14 | }; 15 | 16 | class event_logger_fallback : public event_logger { 17 | public: 18 | void log_entry(const char * line, unsigned) {console::print(line);} 19 | }; 20 | 21 | class NOVTABLE event_logger_recorder : public event_logger { 22 | FB2K_MAKE_SERVICE_INTERFACE( event_logger_recorder , event_logger ); 23 | public: 24 | virtual void playback( event_logger::ptr playTo ) = 0; 25 | }; 26 | 27 | class event_logger_recorder_impl : public event_logger_recorder { 28 | public: 29 | void playback( event_logger::ptr playTo ) { 30 | for(auto i = m_entries.first(); i.is_valid(); ++i ) { 31 | playTo->log_entry( i->line.get_ptr(), i->severity ); 32 | } 33 | } 34 | 35 | void log_entry( const char * line, unsigned severity ) { 36 | auto rec = m_entries.insert_last(); 37 | rec->line = line; 38 | rec->severity = severity; 39 | } 40 | private: 41 | 42 | struct entry_t { 43 | pfc::string_simple line; 44 | unsigned severity; 45 | }; 46 | pfc::chain_list_v2_t< entry_t > m_entries; 47 | }; -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/exceptions.h: -------------------------------------------------------------------------------- 1 | 2 | //! Base class for exceptions that should show a human readable message when caught in app entrypoint function rather than crash and send a crash report. 3 | PFC_DECLARE_EXCEPTION(exception_messagebox,pfc::exception,"Internal Error"); 4 | 5 | //! Base class for exceptions that should result in a quiet app shutdown. 6 | PFC_DECLARE_EXCEPTION(exception_shutdownrequest,pfc::exception,"Shutdown Request"); 7 | 8 | 9 | PFC_DECLARE_EXCEPTION(exception_installdamaged, exception_messagebox, "Internal error - one or more of the installed components have been damaged."); 10 | PFC_DECLARE_EXCEPTION(exception_osfailure, exception_messagebox, "Internal error - broken Windows installation?"); 11 | PFC_DECLARE_EXCEPTION(exception_out_of_resources, exception_messagebox, "Not enough system resources available."); 12 | 13 | PFC_DECLARE_EXCEPTION(exception_configdamaged, exception_messagebox, "Internal error - configuration files are unreadable."); 14 | 15 | PFC_DECLARE_EXCEPTION(exception_profileaccess, exception_messagebox, "Internal error - cannot access configuration folder."); 16 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/genrand.h: -------------------------------------------------------------------------------- 1 | //! PRNG service. Implemented by the core, do not reimplement. Use g_create() helper function to instantiate. 2 | class NOVTABLE genrand_service : public service_base 3 | { 4 | public: 5 | //! Seeds the PRNG with specified value. 6 | virtual void seed(unsigned val) = 0; 7 | //! Returns random value N, where 0 <= N < range. 8 | virtual unsigned genrand(unsigned range)=0; 9 | 10 | double genrand_f() { return (double)genrand(0xFFFFFFFF) / (double)0xFFFFFFFF; } 11 | 12 | static service_ptr_t g_create() {return standard_api_create_t();} 13 | 14 | void generate_random_order(t_size * out, t_size count) { 15 | unsigned genrandMax = (unsigned) pfc::min_t(count, 0xFFFFFFFF); 16 | t_size n; 17 | for(n=0;n(¶m); 7 | byte_order::order_le_to_native_t(temp); 8 | return temp; 9 | } 10 | 11 | hasher_md5_result hasher_md5::process_single(const void * p_buffer,t_size p_bytes) 12 | { 13 | hasher_md5_state state; 14 | initialize(state); 15 | process(state,p_buffer,p_bytes); 16 | return get_result(state); 17 | } 18 | 19 | GUID hasher_md5::process_single_guid(const void * p_buffer,t_size p_bytes) 20 | { 21 | return guid_from_result(process_single(p_buffer,p_bytes)); 22 | } 23 | 24 | t_uint64 hasher_md5_result::xorHalve() const { 25 | #if PFC_BYTE_ORDER_IS_BIG_ENDIAN 26 | t_uint64 ret = 0; 27 | for(int walk = 0; walk < 8; ++walk) { 28 | ret |= (t_uint64)((t_uint8)m_data[walk] ^ (t_uint8)m_data[walk+8]) << (walk * 8); 29 | } 30 | return ret; 31 | #else 32 | const t_uint64 * v = reinterpret_cast(&m_data); 33 | return v[0] ^ v[1]; 34 | #endif 35 | } 36 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/icon_remap.h: -------------------------------------------------------------------------------- 1 | //! New in 0.9.5; allows your file format to use another icon than .ico when registering the file type with Windows shell. \n 2 | //! Implementation: use icon_remapping_impl, or simply: static service_factory_single_t myicon("ext","iconname.ico"); 3 | class icon_remapping : public service_base { 4 | public: 5 | //! @param p_extension File type extension being queried. 6 | //! @param p_iconname Receives the icon name to use, including the .ico extension. 7 | //! @returns True when p_iconname has been set, false if we don't recognize the specified extension. 8 | virtual bool query(const char * p_extension,pfc::string_base & p_iconname) = 0; 9 | 10 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(icon_remapping); 11 | }; 12 | 13 | //! Standard implementation of icon_remapping. 14 | class icon_remapping_impl : public icon_remapping { 15 | public: 16 | icon_remapping_impl(const char * p_extension,const char * p_iconname) : m_extension(p_extension), m_iconname(p_iconname) {} 17 | bool query(const char * p_extension,pfc::string_base & p_iconname) { 18 | if (pfc::stricmp_ascii(p_extension,m_extension) == 0) { 19 | p_iconname = m_iconname; return true; 20 | } else { 21 | return false; 22 | } 23 | } 24 | private: 25 | pfc::string8 m_extension,m_iconname; 26 | }; 27 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/info_lookup_handler.h: -------------------------------------------------------------------------------- 1 | //! Service used to access various external (online) track info lookup services, such as freedb, to update file tags with info retrieved from those services. 2 | class NOVTABLE info_lookup_handler : public service_base { 3 | public: 4 | enum { 5 | flag_album_lookup = 1 << 0, 6 | flag_track_lookup = 1 << 1, 7 | }; 8 | 9 | //! Retrieves human-readable name of the lookup handler to display in user interface. 10 | virtual void get_name(pfc::string_base & p_out) = 0; 11 | 12 | //! Returns one or more of flag_track_lookup, and flag_album_lookup. 13 | virtual t_uint32 get_flags() = 0; 14 | 15 | virtual HICON get_icon(int p_width, int p_height) = 0; 16 | 17 | //! Performs a lookup. Creates a modeless dialog and returns immediately. 18 | //! @param p_items Items to look up. 19 | //! @param p_notify Callback to notify caller when the operation has completed. Call on_completion with status code 0 to signal failure/abort, or with code 1 to signal success / new infos in metadb. 20 | //! @param p_parent Parent window for the lookup dialog. Caller will typically disable the window while lookup is in progress and enable it back when completion is signaled. 21 | virtual void lookup(metadb_handle_list_cref items,completion_notify::ptr notify,HWND parent) = 0; 22 | 23 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(info_lookup_handler); 24 | }; 25 | 26 | 27 | class NOVTABLE info_lookup_handler_v2 : public info_lookup_handler { 28 | FB2K_MAKE_SERVICE_INTERFACE(info_lookup_handler_v2, info_lookup_handler); 29 | public: 30 | virtual double merit() {return 0;} 31 | virtual void lookup_noninteractive(metadb_handle_list_cref items, completion_notify::ptr notify, HWND parent) = 0; 32 | }; 33 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/initquit.h: -------------------------------------------------------------------------------- 1 | //! Basic callback startup/shutdown callback, on_init is called after the main window has been created, on_quit is called before the main window is destroyed. \n 2 | //! To register: static initquit_factory_t myclass_factory; \n 3 | //! Note that you should be careful with calling other components during on_init/on_quit or \n 4 | //! initializing services that are possibly used by other components by on_init/on_quit - \n 5 | //! initialization order of components is undefined. 6 | //! If some other service that you publish is not properly functional before you receive an on_init() call, \n 7 | //! someone else might call this service before >your< on_init is invoked. 8 | class NOVTABLE initquit : public service_base { 9 | public: 10 | virtual void on_init() {} 11 | virtual void on_quit() {} 12 | 13 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(initquit); 14 | }; 15 | 16 | template 17 | class initquit_factory_t : public service_factory_single_t {}; 18 | 19 | 20 | //! \since 1.1 21 | namespace init_stages { 22 | enum { 23 | before_config_read = 10, 24 | after_config_read = 20, 25 | before_library_init = 30, 26 | after_library_init = 40, 27 | before_ui_init = 50, 28 | after_ui_init = 60, 29 | }; 30 | }; 31 | 32 | //! \since 1.1 33 | class NOVTABLE init_stage_callback : public service_base { 34 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(init_stage_callback) 35 | public: 36 | virtual void on_init_stage(t_uint32 stage) = 0; 37 | 38 | static void dispatch(t_uint32 stage) {FB2K_FOR_EACH_SERVICE(init_stage_callback, on_init_stage(stage));} 39 | }; 40 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/link_resolver.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool link_resolver::g_find(service_ptr_t & p_out,const char * p_path) 4 | { 5 | service_enum_t e; 6 | service_ptr_t ptr; 7 | pfc::string_extension ext(p_path); 8 | while(e.next(ptr)) 9 | { 10 | if (ptr->is_our_path(p_path,ext)) 11 | { 12 | p_out = ptr; 13 | return true; 14 | } 15 | } 16 | return false; 17 | } 18 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/link_resolver.h: -------------------------------------------------------------------------------- 1 | #ifndef _foobar2000_sdk_link_resolver_h_ 2 | #define _foobar2000_sdk_link_resolver_h_ 3 | 4 | //! Interface for resolving different sorts of link files. 5 | //! Utilized by mechanisms that convert filesystem path into list of playable locations. 6 | //! For security reasons, link may only point to playable object path, not to a playlist or another link. 7 | 8 | class NOVTABLE link_resolver : public service_base 9 | { 10 | public: 11 | 12 | //! Tests whether specified file is supported by this link_resolver service. 13 | //! @param p_path Path of file being queried. 14 | //! @param p_extension Extension of file being queried. This is provided for performance reasons, path already includes it. 15 | virtual bool is_our_path(const char * p_path,const char * p_extension) = 0; 16 | 17 | //! Resolves a link file. Before this is called, path must be accepted by is_our_path(). 18 | //! @param p_filehint Optional file interface to use. If null/empty, implementation should open file by itself. 19 | //! @param p_path Path of link file to resolve. 20 | //! @param p_out Receives path the link is pointing to. 21 | //! @param p_abort abort_callback object signaling user aborting the operation. 22 | virtual void resolve(service_ptr_t p_filehint,const char * p_path,pfc::string_base & p_out,abort_callback & p_abort) = 0; 23 | 24 | //! Helper function; finds link_resolver interface that supports specified link file. 25 | //! @param p_out Receives link_resolver interface on success. 26 | //! @param p_path Path of file to query. 27 | //! @returns True on success, false on failure (no interface that supports specified path could be found). 28 | static bool g_find(service_ptr_t & p_out,const char * p_path); 29 | 30 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(link_resolver); 31 | }; 32 | 33 | #endif //_foobar2000_sdk_link_resolver_h_ 34 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/main_thread_callback.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | 4 | void main_thread_callback::callback_enqueue() { 5 | static_api_ptr_t< main_thread_callback_manager >()->add_callback( this ); 6 | } 7 | 8 | void main_thread_callback_add(main_thread_callback::ptr ptr) { 9 | static_api_ptr_t()->add_callback(ptr); 10 | } 11 | 12 | namespace { 13 | typedef std::function func_t; 14 | class mtcallback_func : public main_thread_callback { 15 | public: 16 | mtcallback_func(func_t const & f) : m_f(f) {} 17 | 18 | void callback_run() { 19 | m_f(); 20 | } 21 | 22 | private: 23 | func_t m_f; 24 | }; 25 | } 26 | 27 | void fb2k::inMainThread( std::function f ) { 28 | main_thread_callback_add( new service_impl_t(f)); 29 | } 30 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/mainmenu.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool mainmenu_commands::g_execute_dynamic(const GUID & p_guid, const GUID & p_subGuid,service_ptr_t p_callback) { 4 | mainmenu_commands::ptr ptr; t_uint32 index; 5 | if (!menu_item_resolver::g_resolve_main_command(p_guid, ptr, index)) return false; 6 | mainmenu_commands_v2::ptr v2; 7 | if (!ptr->service_query_t(v2)) return false; 8 | if (!v2->is_command_dynamic(index)) return false; 9 | return v2->dynamic_execute(index, p_subGuid, p_callback); 10 | } 11 | bool mainmenu_commands::g_execute(const GUID & p_guid,service_ptr_t p_callback) { 12 | mainmenu_commands::ptr ptr; t_uint32 index; 13 | if (!menu_item_resolver::g_resolve_main_command(p_guid, ptr, index)) return false; 14 | ptr->execute(index, p_callback); 15 | return true; 16 | } 17 | 18 | bool mainmenu_commands::g_find_by_name(const char * p_name,GUID & p_guid) { 19 | service_enum_t e; 20 | service_ptr_t ptr; 21 | pfc::string8_fastalloc temp; 22 | while(e.next(ptr)) { 23 | const t_uint32 count = ptr->get_command_count(); 24 | for(t_uint32 n=0;nget_name(n,temp); 26 | if (stricmp_utf8(temp,p_name) == 0) { 27 | p_guid = ptr->get_command(n); 28 | return true; 29 | } 30 | } 31 | } 32 | return false; 33 | 34 | } 35 | 36 | 37 | static bool dynamic_execute_recur(mainmenu_node::ptr node, const GUID & subID, service_ptr_t callback) { 38 | switch(node->get_type()) { 39 | case mainmenu_node::type_command: 40 | if (subID == node->get_guid()) { 41 | node->execute(callback); return true; 42 | } 43 | break; 44 | case mainmenu_node::type_group: 45 | { 46 | const t_size total = node->get_children_count(); 47 | for(t_size walk = 0; walk < total; ++walk) { 48 | if (dynamic_execute_recur(node->get_child(walk), subID, callback)) return true; 49 | } 50 | } 51 | break; 52 | } 53 | return false; 54 | } 55 | bool mainmenu_commands_v2::dynamic_execute(t_uint32 index, const GUID & subID, service_ptr_t callback) { 56 | return dynamic_execute_recur(dynamic_instantiate(index), subID, callback); 57 | } 58 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/mem_block_container.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void mem_block_container::from_stream(stream_reader * p_stream,t_size p_bytes,abort_callback & p_abort) { 4 | if (p_bytes == 0) {set_size(0);} 5 | set_size(p_bytes); 6 | p_stream->read_object(get_ptr(),p_bytes,p_abort); 7 | } 8 | 9 | void mem_block_container::set(const void * p_buffer,t_size p_size) { 10 | set_size(p_size); 11 | memcpy(get_ptr(),p_buffer,p_size); 12 | } 13 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/menu_item.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | 4 | 5 | bool contextmenu_item::item_get_display_data_root(pfc::string_base & p_out,unsigned & p_displayflags,unsigned p_index,const pfc::list_base_const_t & p_data,const GUID & p_caller) 6 | { 7 | bool status = false; 8 | pfc::ptrholder_t root ( instantiate_item(p_index,p_data,p_caller) ); 9 | if (root.is_valid()) status = root->get_display_data(p_out,p_displayflags,p_data,p_caller); 10 | return status; 11 | } 12 | 13 | 14 | static contextmenu_item_node * g_find_node(const GUID & p_guid,contextmenu_item_node * p_parent) 15 | { 16 | if (p_parent->get_guid() == p_guid) return p_parent; 17 | else if (p_parent->get_type() == contextmenu_item_node::TYPE_POPUP) 18 | { 19 | t_size n, m = p_parent->get_children_count(); 20 | for(n=0;nget_child(n)); 23 | if (temp) return temp; 24 | } 25 | return 0; 26 | } 27 | else return 0; 28 | } 29 | 30 | bool contextmenu_item::item_get_display_data(pfc::string_base & p_out,unsigned & p_displayflags,unsigned p_index,const GUID & p_node,const pfc::list_base_const_t & p_data,const GUID & p_caller) 31 | { 32 | bool status = false; 33 | pfc::ptrholder_t root ( instantiate_item(p_index,p_data,p_caller) ); 34 | if (root.is_valid()) 35 | { 36 | contextmenu_item_node * node = g_find_node(p_node,root.get_ptr()); 37 | if (node) status = node->get_display_data(p_out,p_displayflags,p_data,p_caller); 38 | } 39 | return status; 40 | } 41 | 42 | 43 | GUID contextmenu_item::get_parent_fallback() { 44 | unsigned total = get_num_items(); 45 | if (total < 1) return pfc::guid_null; // hide the item 46 | pfc::string_formatter path, base; this->get_item_default_path(0, base); 47 | for(unsigned walk = 1; walk < total; ++walk) { 48 | this->get_item_default_path(walk, path); 49 | if (strcmp(path, base) != 0) return contextmenu_groups::legacy; 50 | } 51 | return static_api_ptr_t()->path_to_group(base); 52 | } 53 | 54 | GUID contextmenu_item::get_parent_() { 55 | contextmenu_item_v2::ptr v2; 56 | if (service_query_t(v2)) { 57 | return v2->get_parent(); 58 | } else { 59 | return get_parent_fallback(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/modeless_dialog.h: -------------------------------------------------------------------------------- 1 | //! Service for plugging your nonmodal dialog windows into main app loop to receive IsDialogMessage()-translated messages.\n 2 | //! Note that all methods are valid from main app thread only.\n 3 | //! Usage: static_api_ptr_t or modeless_dialog_manager::g_add / modeless_dialog_manager::g_remove. 4 | class NOVTABLE modeless_dialog_manager : public service_base { 5 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(modeless_dialog_manager); 6 | public: 7 | //! Adds specified window to global list of windows to receive IsDialogMessage(). 8 | virtual void add(HWND p_wnd) = 0; 9 | //! Removes specified window from global list of windows to receive IsDialogMessage(). 10 | virtual void remove(HWND p_wnd) = 0; 11 | 12 | //! Static helper; see add(). 13 | static void g_add(HWND p_wnd) {static_api_ptr_t()->add(p_wnd);} 14 | //! Static helper; see remove(). 15 | static void g_remove(HWND p_wnd) {static_api_ptr_t()->remove(p_wnd);} 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/packet_decoder.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void packet_decoder::g_open(service_ptr_t & p_out,bool p_decode,const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size,abort_callback & p_abort) 4 | { 5 | service_enum_t e; 6 | service_ptr_t ptr; 7 | while(e.next(ptr)) { 8 | p_abort.check(); 9 | if (ptr->is_our_setup(p_owner,p_param1,p_param2,p_param2size)) { 10 | ptr->open(p_out,p_decode,p_owner,p_param1,p_param2,p_param2size,p_abort); 11 | return; 12 | } 13 | } 14 | throw exception_io_data(); 15 | } 16 | 17 | size_t packet_decoder::initPadding() { 18 | size_t v = this->set_stream_property(property_bufferpadding, 0, NULL, 0); 19 | if (v > 0) { 20 | this->set_stream_property(property_bufferpadding, v, NULL, 0); 21 | } 22 | return v; 23 | } 24 | 25 | void packet_decoder::setEventLogger(event_logger::ptr logger) { 26 | this->set_stream_property(property_eventlogger, 0, logger.get_ptr(), 0); 27 | } 28 | 29 | void packet_decoder::setCheckingIntegrity(bool checkingIntegrity) { 30 | this->set_stream_property(property_checkingintegrity, checkingIntegrity ? 1 : 0, NULL, 0); 31 | } 32 | 33 | void packet_decoder::setAllowDelayed( bool bAllow ) { 34 | this->set_stream_property( property_allow_delayed_output, bAllow ? 1 : 0, NULL, 0); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/playback_control.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | static double parseFraction(const char * fraction) { 4 | unsigned v = 0, d = 1; 5 | while(pfc::char_is_numeric( *fraction) ) { 6 | d *= 10; 7 | v *= 10; 8 | v += (unsigned) ( *fraction - '0' ); 9 | ++fraction; 10 | } 11 | PFC_ASSERT( *fraction == 0 ); 12 | return (double)v / (double)d; 13 | } 14 | 15 | static double parse_time(const char * time) { 16 | unsigned vTotal = 0, vCur = 0; 17 | for(;;) { 18 | char c = *time++; 19 | if (c == 0) return (double) (vTotal + vCur); 20 | else if (pfc::char_is_numeric( c ) ) { 21 | vCur = vCur * 10 + (unsigned)(c-'0'); 22 | } else if (c == ':') { 23 | if (vCur >= 60) {PFC_ASSERT(!"Invalid input"); return 0; } 24 | vTotal += vCur; vCur = 0; vTotal *= 60; 25 | } else if (c == '.') { 26 | return (double) (vTotal + vCur) + parseFraction(time); 27 | } else { 28 | PFC_ASSERT(!"Invalid input"); return 0; 29 | } 30 | } 31 | } 32 | 33 | double playback_control::playback_get_length() 34 | { 35 | double rv = 0; 36 | metadb_handle_ptr ptr; 37 | if (get_now_playing(ptr)) 38 | { 39 | rv = ptr->get_length(); 40 | } 41 | return rv; 42 | } 43 | 44 | double playback_control::playback_get_length_ex() { 45 | double rv = 0; 46 | metadb_handle_ptr ptr; 47 | if (get_now_playing(ptr)) 48 | { 49 | rv = ptr->get_length(); 50 | if (rv <= 0) { 51 | pfc::string8 temp; 52 | titleformat_object::ptr script; 53 | static_api_ptr_t()->compile_force(script, "[%length_ex%]"); 54 | this->playback_format_title(NULL, temp, script, NULL, display_level_titles); 55 | if (temp.length() > 0) rv = parse_time(temp); 56 | } 57 | } 58 | return rv; 59 | } 60 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/playback_stream_capture.h: -------------------------------------------------------------------------------- 1 | //! \since 1.0 2 | class NOVTABLE playback_stream_capture_callback { 3 | public: 4 | //! Delivers a real-time chunk of audio data. \n 5 | //! Audio is roughly synchronized with what can currently be heard. This API is provided for utility purposes such as streaming; if you want to implement a visualisation, use the visualisation_manager API instead. \n 6 | //! Called only from the main thread. 7 | virtual void on_chunk(const audio_chunk &) = 0; 8 | protected: 9 | playback_stream_capture_callback() {} 10 | ~playback_stream_capture_callback() {} 11 | }; 12 | 13 | //! \since 1.0 14 | class NOVTABLE playback_stream_capture : public service_base { 15 | public: 16 | //! Possible to call only from the main thread. 17 | virtual void add_callback(playback_stream_capture_callback * ) = 0; 18 | //! Possible to call only from the main thread. 19 | virtual void remove_callback(playback_stream_capture_callback * ) = 0; 20 | 21 | 22 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(playback_stream_capture) 23 | }; 24 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/popup_message.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void popup_message::g_show_ex(const char * p_msg,unsigned p_msg_length,const char * p_title,unsigned p_title_length,t_icon p_icon) 4 | { 5 | // Do not force instantiate, not all platforms have this 6 | service_enum_t< popup_message > e; 7 | service_ptr_t< popup_message > m; 8 | if (e.first( m ) ) { 9 | m->show_ex( p_msg, p_msg_length, p_title, p_title_length, p_icon ); 10 | } 11 | } 12 | 13 | 14 | void popup_message::g_complain(const char * what) { 15 | g_show(what, "Information", icon_error); 16 | } 17 | 18 | void popup_message::g_complain(const char * p_whatFailed, const std::exception & p_exception) { 19 | g_complain(p_whatFailed,p_exception.what()); 20 | } 21 | void popup_message::g_complain(const char * p_whatFailed, const char * msg) { 22 | g_complain( PFC_string_formatter() << p_whatFailed << ": " << msg ); 23 | } 24 | 25 | void popup_message_v2::g_show(HWND parent, const char * msg, const char * title) { 26 | service_enum_t< popup_message_v2 > e; 27 | service_ptr_t< popup_message_v2 > m; 28 | if (e.first( m )) { 29 | m->show(parent, msg, title); 30 | } else { 31 | popup_message::g_show( msg, title ); 32 | } 33 | } 34 | void popup_message_v2::g_complain(HWND parent, const char * whatFailed, const char * msg) { 35 | g_show(parent, PFC_string_formatter() << whatFailed << ": " << msg); 36 | } 37 | void popup_message_v2::g_complain(HWND parent, const char * whatFailed, const std::exception & e) { 38 | g_complain(parent, whatFailed, e.what()); 39 | } 40 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/preferences_page.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void preferences_page::get_help_url_helper(pfc::string_base & out, const char * category, const GUID & id, const char * name) { 4 | out.reset(); 5 | out << "http://help.foobar2000.org/" << core_version_info::g_get_version_string() << "/" << category << "/" << pfc::print_guid(id) << "/" << name; 6 | } 7 | bool preferences_page::get_help_url(pfc::string_base & p_out) { 8 | get_help_url_helper(p_out,"preferences",get_guid(), get_name()); 9 | return true; 10 | } 11 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/progress_meter.h: -------------------------------------------------------------------------------- 1 | //! Interface for setting current operation progress state to be visible on Windows 7 taskbar. Use static_api_ptr_t()->acquire() to instantiate. 2 | class NOVTABLE progress_meter_instance : public service_base { 3 | FB2K_MAKE_SERVICE_INTERFACE(progress_meter_instance, service_base); 4 | public: 5 | //! Sets the current progress state. 6 | //! @param value Progress state, in 0..1 range. 7 | virtual void set_progress(float value) = 0; 8 | //! Toggles paused state. 9 | virtual void set_pause(bool isPaused) = 0; 10 | }; 11 | 12 | //! Entrypoint interface for instantiating progress_meter_instance objects. 13 | class NOVTABLE progress_meter : public service_base { 14 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(progress_meter); 15 | public: 16 | //! Creates a progress_meter_instance object. 17 | virtual progress_meter_instance::ptr acquire() = 0; 18 | }; 19 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/resampler.h: -------------------------------------------------------------------------------- 1 | class NOVTABLE resampler_entry : public dsp_entry 2 | { 3 | public: 4 | virtual bool is_conversion_supported(unsigned p_srate_from,unsigned p_srate_to) = 0; 5 | virtual bool create_preset(dsp_preset & p_out,unsigned p_target_srate,float p_qualityscale) = 0;//p_qualityscale is 0...1 6 | virtual float get_priority() = 0;//value is 0...1, where high-quality (SSRC etc) has 1 7 | 8 | static bool g_get_interface(service_ptr_t & p_out,unsigned p_srate_from,unsigned p_srate_to); 9 | static bool g_create(service_ptr_t & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale); 10 | static bool g_create_preset(dsp_preset & p_out,unsigned p_srate_from,unsigned p_srate_to,float p_qualityscale); 11 | 12 | FB2K_MAKE_SERVICE_INTERFACE(resampler_entry,dsp_entry); 13 | }; 14 | 15 | template 16 | class resampler_entry_impl_t : public dsp_entry_impl_t 17 | { 18 | public: 19 | bool is_conversion_supported(unsigned p_srate_from,unsigned p_srate_to) {return T::g_is_conversion_supported(p_srate_from,p_srate_to);} 20 | bool create_preset(dsp_preset & p_out,unsigned p_target_srate,float p_qualityscale) {return T::g_create_preset(p_out,p_target_srate,p_qualityscale);} 21 | float get_priority() {return T::g_get_priority();} 22 | }; 23 | 24 | template 25 | class resampler_factory_t : public service_factory_single_t > {}; 26 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/search_tools.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void search_filter_manager::show_manual() { 4 | pfc::string8 temp; 5 | get_manual(temp); 6 | popup_message::g_show(temp,"Search Expression Reference"); 7 | } 8 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/service.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | #include "component.h" 3 | 4 | foobar2000_api * g_foobar2000_api = NULL; 5 | 6 | service_class_ref service_factory_base::enum_find_class(const GUID & p_guid) 7 | { 8 | PFC_ASSERT(core_api::are_services_available() && g_foobar2000_api); 9 | return g_foobar2000_api->service_enum_find_class(p_guid); 10 | } 11 | 12 | bool service_factory_base::enum_create(service_ptr_t & p_out,service_class_ref p_class,t_size p_index) 13 | { 14 | PFC_ASSERT(core_api::are_services_available() && g_foobar2000_api); 15 | return g_foobar2000_api->service_enum_create(p_out,p_class,p_index); 16 | } 17 | 18 | t_size service_factory_base::enum_get_count(service_class_ref p_class) 19 | { 20 | PFC_ASSERT(core_api::are_services_available() && g_foobar2000_api); 21 | return g_foobar2000_api->service_enum_get_count(p_class); 22 | } 23 | 24 | service_factory_base * service_factory_base::__internal__list = NULL; 25 | 26 | 27 | 28 | 29 | 30 | namespace { 31 | class main_thread_callback_release_object : public main_thread_callback { 32 | public: 33 | main_thread_callback_release_object(service_ptr obj) : m_object(obj) {} 34 | void callback_run() { 35 | try { m_object.release(); } catch(...) {} 36 | } 37 | private: 38 | service_ptr m_object; 39 | }; 40 | } 41 | namespace service_impl_helper { 42 | void release_object_delayed(service_ptr obj) { 43 | static_api_ptr_t()->add_callback(new service_impl_t(obj)); 44 | } 45 | }; 46 | 47 | 48 | void _standard_api_create_internal(service_ptr & out, const GUID & classID) { 49 | service_class_ref c = service_factory_base::enum_find_class(classID); 50 | switch(service_factory_base::enum_get_count(c)) { 51 | case 0: 52 | throw exception_service_not_found(); 53 | case 1: 54 | PFC_ASSERT_SUCCESS( service_factory_base::enum_create(out, c, 0) ); 55 | break; 56 | default: 57 | throw exception_service_duplicated(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/service_impl.h: -------------------------------------------------------------------------------- 1 | //! Template implementing reference-counting features of service_base. Intended for dynamic instantiation: "new service_impl_t(param1,param2);"; should not be instantiated otherwise (no local/static/member objects) because it does a "delete this;" when reference count reaches zero.\n 2 | //! Note that some constructor parameters such as NULL will need explicit typecasts to ensure correctly guessed types for constructor function template (null string needs to be (const char*)NULL rather than just NULL, etc). 3 | template 4 | class service_impl_t : public T 5 | { 6 | public: 7 | int service_release() throw() { 8 | int ret = (int) --m_counter; 9 | if (ret == 0) { 10 | PFC_ASSERT_NO_EXCEPTION( delete this ); 11 | } 12 | return ret; 13 | } 14 | int service_add_ref() throw() {return (int) ++m_counter;} 15 | 16 | TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_impl_t,T) 17 | private: 18 | pfc::refcounter m_counter; 19 | }; 20 | 21 | //! Alternate version of service_impl_t<> - calls this->service_shutdown() instead of delete this. \n 22 | //! For special cases where selfdestruct on zero refcount is undesired. 23 | template 24 | class service_impl_explicitshutdown_t : public class_t { 25 | public: 26 | int service_release() throw() { 27 | int ret = --m_counter; 28 | if (ret == 0) { 29 | this->service_shutdown(); 30 | } else { 31 | return ret; 32 | } 33 | } 34 | int service_add_ref() throw() {return ++m_counter;} 35 | 36 | TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_impl_explicitshutdown_t,class_t) 37 | private: 38 | pfc::refcounter m_counter; 39 | }; 40 | 41 | //! Template implementing dummy version of reference-counting features of service_base. Intended for static/local/member instantiation: "static service_impl_single_t myvar(params);". Because reference counting features are disabled (dummy reference counter), code instantiating it is responsible for deleting it as well as ensuring that no references are active when the object gets deleted.\n 42 | //! Note that some constructor parameters such as NULL will need explicit typecasts to ensure correctly guessed types for constructor function template (null string needs to be (const char*)NULL rather than just NULL, etc). 43 | template 44 | class service_impl_single_t : public T 45 | { 46 | public: 47 | int service_release() throw() {return 1;} 48 | int service_add_ref() throw() {return 1;} 49 | 50 | TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_impl_single_t,T) 51 | }; 52 | 53 | 54 | namespace service_impl_helper { 55 | void release_object_delayed(service_ptr obj); 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/shortcut_actions.h: -------------------------------------------------------------------------------- 1 | #error DEPRECATED 2 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //cpp used to generate precompiled header 2 | #include "foobar2000.h" -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/system_time_keeper.h: -------------------------------------------------------------------------------- 1 | namespace system_time_periods { 2 | static const t_filetimestamp second = filetimestamp_1second_increment; 3 | static const t_filetimestamp minute = second * 60; 4 | static const t_filetimestamp hour = minute * 60; 5 | static const t_filetimestamp day = hour * 24; 6 | static const t_filetimestamp week = day * 7; 7 | }; 8 | class system_time_callback { 9 | public: 10 | virtual void on_time_changed(t_filetimestamp newVal) = 0; 11 | }; 12 | //! \since 0.9.6 13 | class system_time_keeper : public service_base { 14 | public: 15 | //! The callback object receives an on_changed() call with the current time inside the register_callback() call. 16 | virtual void register_callback(system_time_callback * callback, t_filetimestamp resolution) = 0; 17 | 18 | virtual void unregister_callback(system_time_callback * callback) = 0; 19 | 20 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(system_time_keeper) 21 | }; 22 | 23 | class system_time_callback_impl : public system_time_callback { 24 | public: 25 | system_time_callback_impl() : m_registered() {} 26 | ~system_time_callback_impl() {stop_timer();} 27 | 28 | void stop_timer() { 29 | if (m_registered) { 30 | static_api_ptr_t()->unregister_callback(this); 31 | m_registered = false; 32 | } 33 | } 34 | //! You get a on_changed() call inside the initialize_timer() call. 35 | void initialize_timer(t_filetimestamp period) { 36 | stop_timer(); 37 | static_api_ptr_t()->register_callback(this, period); 38 | m_registered = true; 39 | } 40 | 41 | void on_time_changed(t_filetimestamp newVal) {} 42 | 43 | PFC_CLASS_NOT_COPYABLE_EX(system_time_callback_impl) 44 | private: 45 | bool m_registered; 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/threaded_process.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | void threaded_process_status::set_progress(t_size p_state,t_size p_max) 4 | { 5 | set_progress( progress_min + MulDiv_Size(p_state,progress_max-progress_min,p_max) ); 6 | } 7 | 8 | void threaded_process_status::set_progress_secondary(t_size p_state,t_size p_max) 9 | { 10 | set_progress_secondary( progress_min + MulDiv_Size(p_state,progress_max-progress_min,p_max) ); 11 | } 12 | 13 | void threaded_process_status::set_progress_float(double p_state) 14 | { 15 | if (p_state < 0.0) set_progress(progress_min); 16 | else if (p_state < 1.0) set_progress( progress_min + (t_size)(p_state * (progress_max - progress_min))); 17 | else set_progress(progress_max); 18 | } 19 | 20 | void threaded_process_status::set_progress_secondary_float(double p_state) 21 | { 22 | if (p_state < 0.0) set_progress_secondary(progress_min); 23 | else if (p_state < 1.0) set_progress_secondary( progress_min + (t_size)(p_state * (progress_max - progress_min))); 24 | else set_progress_secondary(progress_max); 25 | } 26 | 27 | 28 | bool threaded_process::g_run_modal(service_ptr_t p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len) 29 | { 30 | return static_api_ptr_t()->run_modal(p_callback,p_flags,p_parent,p_title,p_title_len); 31 | } 32 | 33 | bool threaded_process::g_run_modeless(service_ptr_t p_callback,unsigned p_flags,HWND p_parent,const char * p_title,t_size p_title_len) 34 | { 35 | return static_api_ptr_t()->run_modeless(p_callback,p_flags,p_parent,p_title,p_title_len); 36 | } 37 | 38 | bool threaded_process::g_query_preventStandby() { 39 | static const GUID guid_preventStandby = { 0x7aafeffb, 0x5f11, 0x483f, { 0xac, 0x65, 0x61, 0xec, 0x9c, 0x70, 0x37, 0x4e } }; 40 | advconfig_entry_checkbox::ptr obj; 41 | if (advconfig_entry::g_find_t(obj, guid_preventStandby)) { 42 | return obj->get_state(); 43 | } else { 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/ui.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar2000.h" 2 | 3 | bool ui_drop_item_callback::g_on_drop(interface IDataObject * pDataObject) 4 | { 5 | service_enum_t e; 6 | service_ptr_t ptr; 7 | if (e.first(ptr)) do { 8 | if (ptr->on_drop(pDataObject)) return true; 9 | } while(e.next(ptr)); 10 | return false; 11 | } 12 | 13 | bool ui_drop_item_callback::g_is_accepted_type(interface IDataObject * pDataObject, DWORD * p_effect) 14 | { 15 | service_enum_t e; 16 | service_ptr_t ptr; 17 | if (e.first(ptr)) do { 18 | if (ptr->is_accepted_type(pDataObject,p_effect)) return true; 19 | } while(e.next(ptr)); 20 | return false; 21 | } 22 | 23 | bool user_interface::g_find(service_ptr_t & p_out,const GUID & p_guid) 24 | { 25 | service_enum_t e; 26 | service_ptr_t ptr; 27 | if (e.first(ptr)) do { 28 | if (ptr->get_guid() == p_guid) 29 | { 30 | p_out = ptr; 31 | return true; 32 | } 33 | } while(e.next(ptr)); 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/SDK/unpack.h: -------------------------------------------------------------------------------- 1 | //! Service providing "unpacker" functionality - processes "packed" file (such as a zip file containing a single media file inside) to allow its contents to be accessed transparently.\n 2 | //! To access existing unpacker implementations, use unpacker::g_open helper function.\n 3 | //! To register your own implementation, use unpacker_factory_t template. 4 | class NOVTABLE unpacker : public service_base { 5 | public: 6 | //! Attempts to open specified file for unpacking, creates interface to virtual file with uncompressed data on success. When examined file doesn't appear to be one of formats supported by this unpacker implementation, throws exception_io_data. 7 | //! @param p_out Receives interface to virtual file with uncompressed data on success. 8 | //! @param p_source Source file to process. 9 | //! @param p_abort abort_callback object signaling user aborting the operation. 10 | virtual void open(service_ptr_t & p_out,const service_ptr_t & p_source,abort_callback & p_abort) = 0; 11 | 12 | //! Static helper querying existing unpacker implementations until one that successfully opens specified file is found. Attempts to open specified file for unpacking, creates interface to virtual file with uncompressed data on success. When examined file doesn't appear to be one of formats supported by registered unpacker implementations, throws exception_io_data. 13 | //! @param p_out Receives interface to virtual file with uncompressed data on success. 14 | //! @param p_source Source file to process. 15 | //! @param p_abort abort_callback object signaling user aborting the operation. 16 | static void g_open(service_ptr_t & p_out,const service_ptr_t & p_source,abort_callback & p_abort); 17 | 18 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(unpacker); 19 | }; 20 | 21 | template 22 | class unpacker_factory_t : public service_factory_single_t {}; 23 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_input_validator/foo_input_validator.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/foobar-sdk/foobar2000/foo_input_validator/foo_input_validator.dll -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/PCH.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | // This is a dummy source code file that just generates the precompiled header (PCH) file for use when compiling the rest of the source code, to speed compilation up. -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/foo_sample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | 61 | 62 | Resource Files 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/initquit.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | // Sample initquit implementation. See also: initquit class documentation in relevant header. 4 | 5 | class myinitquit : public initquit { 6 | public: 7 | void on_init() { 8 | console::print("Sample component: on_init()"); 9 | } 10 | void on_quit() { 11 | console::print("Sample component: on_quit()"); 12 | } 13 | }; 14 | 15 | static initquit_factory_t g_myinitquit_factory; 16 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | // Declaration of your component's version information 4 | // Since foobar2000 v1.0 having at least one of these in your DLL is mandatory to let the troubleshooter tell different versions of your component apart. 5 | // Note that it is possible to declare multiple components within one DLL, but it's strongly recommended to keep only one declaration per DLL. 6 | // As for 1.1, the version numbers are used by the component update finder to find updates; for that to work, you must have ONLY ONE declaration per DLL. If there are multiple declarations, the component is assumed to be outdated and a version number of "0" is assumed, to overwrite the component with whatever is currently on the site assuming that it comes with proper version numbers. 7 | DECLARE_COMPONENT_VERSION("Sample Component","1.0","about message goes here"); 8 | 9 | 10 | // This will prevent users from renaming your component around (important for proper troubleshooter behaviors) or loading multiple instances of it. 11 | VALIDATE_COMPONENT_FILENAME("foo_sample.dll"); 12 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/mainmenu.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | static const GUID g_mainmenu_group_id = { 0x44963e7a, 0x4b2a, 0x4588, { 0xb0, 0x17, 0xa8, 0x69, 0x18, 0xcb, 0x8a, 0xa5 } }; 4 | 5 | static mainmenu_group_popup_factory g_mainmenu_group(g_mainmenu_group_id, mainmenu_groups::file, mainmenu_commands::sort_priority_dontcare, "Sample component"); 6 | 7 | void RunPlaybackStateDemo(); //playback_state.cpp 8 | 9 | class mainmenu_commands_sample : public mainmenu_commands { 10 | public: 11 | enum { 12 | cmd_test = 0, 13 | cmd_playbackstate, 14 | cmd_total 15 | }; 16 | t_uint32 get_command_count() { 17 | return cmd_total; 18 | } 19 | GUID get_command(t_uint32 p_index) { 20 | static const GUID guid_test = { 0x7c4726df, 0x3b2d, 0x4c7c, { 0xad, 0xe8, 0x43, 0xd8, 0x46, 0xbe, 0xce, 0xa8 } }; 21 | static const GUID guid_playbackstate = { 0xbd880c51, 0xf0cc, 0x473f, { 0x9d, 0x14, 0xa6, 0x6e, 0x8c, 0xed, 0x25, 0xae } }; 22 | switch(p_index) { 23 | case cmd_test: return guid_test; 24 | case cmd_playbackstate: return guid_playbackstate; 25 | default: uBugCheck(); // should never happen unless somebody called us with invalid parameters - bail 26 | } 27 | } 28 | void get_name(t_uint32 p_index,pfc::string_base & p_out) { 29 | switch(p_index) { 30 | case cmd_test: p_out = "Test command"; break; 31 | case cmd_playbackstate: p_out = "Playback state demo"; break; 32 | default: uBugCheck(); // should never happen unless somebody called us with invalid parameters - bail 33 | } 34 | } 35 | bool get_description(t_uint32 p_index,pfc::string_base & p_out) { 36 | switch(p_index) { 37 | case cmd_test: p_out = "This is a sample menu command."; return true; 38 | case cmd_playbackstate: p_out = "Opens the playback state demo dialog."; return true; 39 | default: uBugCheck(); // should never happen unless somebody called us with invalid parameters - bail 40 | } 41 | } 42 | GUID get_parent() { 43 | return g_mainmenu_group_id; 44 | } 45 | void execute(t_uint32 p_index,service_ptr_t p_callback) { 46 | switch(p_index) { 47 | case cmd_test: 48 | popup_message::g_show("This is a sample menu command.", "Blah"); 49 | break; 50 | case cmd_playbackstate: 51 | RunPlaybackStateDemo(); 52 | break; 53 | default: 54 | uBugCheck(); // should never happen unless somebody called us with invalid parameters - bail 55 | } 56 | } 57 | }; 58 | 59 | static mainmenu_commands_factory_t g_mainmenu_commands_sample_factory; 60 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/readme.txt: -------------------------------------------------------------------------------- 1 | This component demonstrates: 2 | * main.cpp : 3 | * Declaring your component's version information. 4 | * input_raw.cpp : 5 | * Declaring your own "input" classes for decoding additional audio file formats. 6 | * Calling file system services. 7 | * preferences.cpp : 8 | * Declaring your configuration variables. 9 | * Creating preferences pages using simple WTL dialogs. 10 | * Declaring advanced preferences entries. 11 | * initquit.cpp : 12 | * Sample initialization/shutdown callback service. 13 | * dsp.cpp : 14 | * Sample DSP. 15 | * contextmenu.cpp : 16 | * Sample context menu command. 17 | * decode.cpp : 18 | * Getting PCM data from arbitrary audio files. 19 | * Use of the threaded_process API to easily run time-consuming tasks in worker threads with progress dialogs. 20 | * mainmenu.cpp : 21 | * Sample main menu command 22 | * playback_state.cpp : 23 | * Use of playback callbacks. 24 | * Use of playback control. 25 | * ui_element.cpp : 26 | * Simple UI Element implementation. -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_sample.rc 4 | // 5 | #define IDD_PLAYBACK_STATE 101 6 | #define IDD_DSP 102 7 | #define IDD_MYPREFERENCES 148 8 | #define IDC_BOGO1 1001 9 | #define IDC_BOGO2 1002 10 | #define IDC_PATTERN 1002 11 | #define IDC_STATE 1003 12 | #define IDC_PLAY 1004 13 | #define IDC_PAUSE 1005 14 | #define IDC_STOP 1006 15 | #define IDC_PREV 1007 16 | #define IDC_NEXT 1008 17 | #define IDC_RAND 1009 18 | #define IDC_CONTEXTMENU 1010 19 | #define IDC_SLIDER1 1012 20 | #define IDC_SLIDER 1012 21 | #define IDC_SLIDER_LABEL 1013 22 | 23 | // Next default values for new objects 24 | // 25 | #ifdef APSTUDIO_INVOKED 26 | #ifndef APSTUDIO_READONLY_SYMBOLS 27 | #define _APS_NEXT_RESOURCE_VALUE 103 28 | #define _APS_NEXT_COMMAND_VALUE 40001 29 | #define _APS_NEXT_CONTROL_VALUE 1014 30 | #define _APS_NEXT_SYMED_VALUE 101 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/foo_sample/stdafx.h: -------------------------------------------------------------------------------- 1 | #include "../ATLHelpers/ATLHelpers.h" 2 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/COM_utils.h: -------------------------------------------------------------------------------- 1 | #define FB2K_COM_CATCH catch(exception_com const & e) {return e.get_code();} catch(std::bad_alloc) {return E_OUTOFMEMORY;} catch(pfc::exception_invalid_params) {return E_INVALIDARG;} catch(...) {return E_UNEXPECTED;} 2 | 3 | #define COM_QI_BEGIN() HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,void ** ppvObject) { if (ppvObject == NULL) return E_INVALIDARG; 4 | #define COM_QI_ENTRY(IWhat) { if (iid == __uuidof(IWhat)) {IWhat * temp = this; temp->AddRef(); * ppvObject = temp; return S_OK;} } 5 | #define COM_QI_ENTRY_(IWhat, IID) { if (iid == IID) {IWhat * temp = this; temp->AddRef(); * ppvObject = temp; return S_OK;} } 6 | #define COM_QI_END() * ppvObject = NULL; return E_NOINTERFACE; } 7 | 8 | #define COM_QI_CHAIN(Parent) { HRESULT status = Parent::QueryInterface(iid, ppvObject); if (SUCCEEDED(status)) return status; } 9 | 10 | #define COM_QI_SIMPLE(IWhat) COM_QI_BEGIN() COM_QI_ENTRY(IUnknown) COM_QI_ENTRY(IWhat) COM_QI_END() -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/CallForwarder.h: -------------------------------------------------------------------------------- 1 | namespace CF { 2 | template class _inMainThread : public main_thread_callback { 3 | public: 4 | _inMainThread(obj_t const & obj, const arg_t & arg) : m_obj(obj), m_arg(arg) {} 5 | 6 | void callback_run() { 7 | if (m_obj.IsValid()) callInMainThread::callThis(&*m_obj, m_arg); 8 | } 9 | private: 10 | obj_t m_obj; 11 | arg_t m_arg; 12 | }; 13 | 14 | template class CallForwarder { 15 | public: 16 | CallForwarder(TWhat * ptr) { m_ptr.new_t(ptr); } 17 | 18 | void Orphan() {*m_ptr = NULL;} 19 | bool IsValid() const { return *m_ptr != NULL; } 20 | bool IsEmpty() const { return !IsValid(); } 21 | 22 | TWhat * operator->() const { 23 | PFC_ASSERT( IsValid() ); 24 | return *m_ptr; 25 | } 26 | 27 | TWhat & operator*() const { 28 | PFC_ASSERT( IsValid() ); 29 | return **m_ptr; 30 | } 31 | 32 | template 33 | void callInMainThread(const arg_t & arg) { 34 | main_thread_callback_add( new service_impl_t<_inMainThread< CallForwarder, arg_t> >(*this, arg) ); 35 | } 36 | private: 37 | pfc::rcptr_t m_ptr; 38 | }; 39 | 40 | template class CallForwarderMaster : public CallForwarder { 41 | public: 42 | CallForwarderMaster(TWhat * ptr) : CallForwarder(ptr) {} 43 | ~CallForwarderMaster() { this->Orphan(); } 44 | 45 | PFC_CLASS_NOT_COPYABLE(CallForwarderMaster, CallForwarderMaster); 46 | }; 47 | 48 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/ProfileCache.h: -------------------------------------------------------------------------------- 1 | namespace ProfileCache { 2 | inline file::ptr FetchFile(const char * context, const char * name, const char * webURL, t_filetimestamp acceptableAge, abort_callback & abort) { 3 | const double timeoutVal = 5; 4 | 5 | pfc::string_formatter path ( core_api::get_profile_path() ); 6 | path.fix_dir_separator('\\'); 7 | path << context; 8 | try { 9 | filesystem::g_create_directory(path, abort); 10 | } catch(exception_io_already_exists) {} 11 | path << "\\" << name; 12 | 13 | bool fetch = false; 14 | file::ptr fLocal; 15 | 16 | try { 17 | filesystem::g_open_timeout(fLocal, path, filesystem::open_mode_write_existing, timeoutVal, abort); 18 | fetch = fLocal->get_timestamp(abort) < filetimestamp_from_system_timer() - acceptableAge; 19 | } catch(exception_io_not_found) { 20 | filesystem::g_open_timeout(fLocal, path, filesystem::open_mode_write_new, timeoutVal, abort); 21 | fetch = true; 22 | } 23 | if (fetch) { 24 | fLocal->resize(0, abort); 25 | file::ptr fRemote; 26 | try { 27 | filesystem::g_open(fRemote, webURL, filesystem::open_mode_read, abort); 28 | } catch(exception_io_not_found) { 29 | fLocal.release(); 30 | try { filesystem::g_remove_timeout(path, timeoutVal, abort); } catch(...) {} 31 | throw; 32 | } 33 | pfc::array_t buffer; buffer.set_size(64*1024); 34 | for(;;) { 35 | t_size delta = buffer.get_size(); 36 | delta = fRemote->read(buffer.get_ptr(), delta, abort); 37 | fLocal->write(buffer.get_ptr(), delta, abort); 38 | if (delta < buffer.get_size()) break; 39 | } 40 | fLocal->seek(0, abort); 41 | } 42 | return fLocal; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/StdAfx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // foobar2000_sdk_helpers.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/StdAfx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #if !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_) 7 | #define AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_ 8 | 9 | #if _MSC_VER > 1000 10 | #pragma once 11 | #endif // _MSC_VER > 1000 12 | 13 | 14 | #include "../SDK/foobar2000.h" 15 | #include "helpers.h" 16 | 17 | // TODO: reference additional headers your program requires here 18 | 19 | //{{AFX_INSERT_LOCATION}} 20 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 21 | 22 | #endif // !defined(AFX_STDAFX_H__6356EC2B_6DD1_4BE8_935C_87ECBA8697E4__INCLUDED_) 23 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/VisUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | namespace VisUtils { 4 | void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset) { 5 | const t_uint32 channels = source.get_channel_count(); 6 | const t_uint32 sampleRate = source.get_sample_rate(); 7 | FB2K_DYNAMIC_ASSERT( sampleRate > 0 ); 8 | out.set_channels(channels, source.get_channel_config()); 9 | out.set_sample_rate(sampleRate); 10 | const t_size inSize = source.get_sample_count(); 11 | const t_size fftSize = MatchFFTSize(inSize); 12 | out.set_sample_count(fftSize); 13 | out.set_data_size(fftSize * channels); 14 | if (fftSize >= inSize) { //rare case with *REALLY* small input 15 | pfc::memcpy_t( out.get_data(), source.get_data(), inSize * channels ); 16 | pfc::memset_null_t( out.get_data() + inSize * channels, (fftSize - inSize) * channels ); 17 | } else { //inSize > fftSize, we're using a subset of source chunk for the job, pick a subset around centerOffset. 18 | const double baseOffset = pfc::max_t(0, centerOffset - 0.5 * (double)fftSize / (double)sampleRate); 19 | const t_size baseSample = pfc::min_t( (t_size) audio_math::time_to_samples(baseOffset, sampleRate), inSize - fftSize); 20 | pfc::memcpy_t( out.get_data(), source.get_data() + baseSample * channels, fftSize * channels); 21 | } 22 | } 23 | 24 | bool IsValidFFTSize(t_size p_size) { 25 | return p_size >= 2 && (p_size & (p_size - 1)) == 0; 26 | } 27 | 28 | t_size MatchFFTSize(t_size samples) { 29 | if (samples <= 2) return 2; 30 | t_size mask = 1; 31 | while(!IsValidFFTSize(samples)) { 32 | samples &= ~mask; mask <<= 1; 33 | } 34 | return samples; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/VisUtils.h: -------------------------------------------------------------------------------- 1 | namespace VisUtils { 2 | //! Turns an arbitrary audio_chunk into a valid chunk to run FFT on, with proper sample count etc. 3 | //! @param centerOffset Time offset (in seconds) inside the source chunk to center the output on, in case the FFT window is smaller than input data. 4 | void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset); 5 | 6 | bool IsValidFFTSize(t_size size); 7 | t_size MatchFFTSize(t_size samples); 8 | }; 9 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/cfg_guidlist.h: -------------------------------------------------------------------------------- 1 | class cfg_guidlist : public cfg_var, public pfc::list_t 2 | { 3 | public: 4 | void get_data_raw(stream_writer * p_stream,abort_callback & p_abort) { 5 | t_uint32 n, m = pfc::downcast_guarded(get_count()); 6 | p_stream->write_lendian_t(m,p_abort); 7 | for(n=0;nwrite_lendian_t(get_item(n),p_abort); 8 | } 9 | void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort) { 10 | t_uint32 n,count; 11 | p_stream->read_lendian_t(count,p_abort); 12 | m_buffer.set_size(count); 13 | for(n=0;nread_lendian_t(m_buffer[n],p_abort); 16 | } catch(...) {m_buffer.set_size(0); throw;} 17 | } 18 | } 19 | 20 | void sort() {sort_t(pfc::guid_compare);} 21 | 22 | bool have_item_bsearch(const GUID & p_item) { 23 | t_size dummy; 24 | return bsearch_t(pfc::guid_compare,p_item,dummy); 25 | } 26 | 27 | public: 28 | cfg_guidlist(const GUID & p_guid) : cfg_var(p_guid) {} 29 | }; 30 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/clipboard.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #ifdef _WIN32 4 | 5 | #ifdef UNICODE 6 | #define CF_TCHAR CF_UNICODETEXT 7 | #else 8 | #define CF_TCHAR CF_TEXT 9 | #endif 10 | 11 | namespace ClipboardHelper { 12 | void SetRaw(UINT format,const void * data, t_size size) { 13 | HANDLE buffer = GlobalAlloc(GMEM_DDESHARE,size); 14 | if (buffer == NULL) throw std::bad_alloc(); 15 | try { 16 | CGlobalLockScope lock(buffer); 17 | PFC_ASSERT(lock.GetSize() == size); 18 | memcpy(lock.GetPtr(),data,size); 19 | } catch(...) { 20 | GlobalFree(buffer); throw; 21 | } 22 | 23 | WIN32_OP(SetClipboardData(format,buffer) != NULL); 24 | } 25 | void SetString(const char * in) { 26 | pfc::stringcvt::string_os_from_utf8 temp(in); 27 | SetRaw(CF_TCHAR,temp.get_ptr(),(temp.length() + 1) * sizeof(TCHAR)); 28 | } 29 | 30 | bool GetString(pfc::string_base & out) { 31 | pfc::array_t temp; 32 | if (!GetRaw(CF_TCHAR,temp)) return false; 33 | out = pfc::stringcvt::string_utf8_from_os(reinterpret_cast(temp.get_ptr()),temp.get_size() / sizeof(TCHAR)); 34 | return true; 35 | } 36 | bool IsTextAvailable() { 37 | return IsClipboardFormatAvailable(CF_TCHAR) == TRUE; 38 | } 39 | } 40 | 41 | #endif // _WIN32 42 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/clipboard.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | namespace ClipboardHelper { 3 | 4 | class OpenScope { 5 | public: 6 | OpenScope() : m_open(false) {} 7 | ~OpenScope() {Close();} 8 | void Open(HWND p_owner) { 9 | Close(); 10 | WIN32_OP(OpenClipboard(p_owner)); 11 | m_open = true; 12 | } 13 | void Close() { 14 | if (m_open) { 15 | m_open = false; 16 | CloseClipboard(); 17 | } 18 | } 19 | private: 20 | bool m_open; 21 | 22 | PFC_CLASS_NOT_COPYABLE_EX(OpenScope) 23 | }; 24 | 25 | void SetRaw(UINT format,const void * buffer, t_size size); 26 | void SetString(const char * in); 27 | 28 | bool GetString(pfc::string_base & out); 29 | 30 | template 31 | bool GetRaw(UINT format,TArray & out) { 32 | pfc::assert_byte_type(); 33 | HANDLE data = GetClipboardData(format); 34 | if (data == NULL) return false; 35 | CGlobalLockScope lock(data); 36 | out.set_size( lock.GetSize() ); 37 | memcpy(out.get_ptr(), lock.GetPtr(), lock.GetSize() ); 38 | return true; 39 | } 40 | bool IsTextAvailable(); 41 | }; 42 | #endif // _WIN32 43 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/create_directory_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef _CREATE_DIRECTORY_HELPER_H_ 2 | #define _CREATE_DIRECTORY_HELPER_H_ 3 | 4 | namespace create_directory_helper { 5 | void create_path(const char * p_path,abort_callback & p_abort); 6 | void make_path(const char * parent,const char * filename,const char * extension,bool allow_new_dirs,pfc::string8 & out,bool b_really_create_dirs,abort_callback & p_dir_create_abort); 7 | void format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,const char * spec,pfc::string_base & out); 8 | void format_filename(const metadb_handle_ptr & handle,titleformat_hook * p_hook,titleformat_object::ptr spec,pfc::string_base & out); 9 | void format_filename_ex(const metadb_handle_ptr & handle,titleformat_hook * p_hook,titleformat_object::ptr spec,const char * suffix, pfc::string_base & out); 10 | 11 | pfc::string sanitize_formatted_path(pfc::stringp str, bool allowWC = false); 12 | 13 | class titleformat_text_filter_myimpl : public titleformat_text_filter { 14 | public: 15 | void write(const GUID & p_inputType,pfc::string_receiver & p_out,const char * p_data,t_size p_dataLength); 16 | }; 17 | 18 | }; 19 | 20 | #endif//_CREATE_DIRECTORY_HELPER_H_ -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/cue_creator.h: -------------------------------------------------------------------------------- 1 | namespace cue_creator 2 | { 3 | struct t_entry 4 | { 5 | file_info_impl m_infos; 6 | pfc::string8 m_file,m_flags; 7 | unsigned m_track_number; 8 | 9 | t_cuesheet_index_list m_index_list; 10 | 11 | void set_simple_index(double p_time); 12 | void set_index01(double index0, double index1); 13 | }; 14 | 15 | typedef pfc::chain_list_v2_t t_entry_list; 16 | 17 | void create(pfc::string_formatter & p_out,const t_entry_list & p_list); 18 | }; -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/cuesheet_index_list.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #ifndef _MSC_VER 4 | #define sprintf_s sprintf 5 | #endif 6 | 7 | bool t_cuesheet_index_list::is_valid() const { 8 | if (m_positions[1] < m_positions[0]) return false; 9 | for(t_size n = 2; n < count && m_positions[n] > 0; n++) { 10 | if (m_positions[n] < m_positions[n-1]) return false; 11 | } 12 | return true; 13 | } 14 | 15 | void t_cuesheet_index_list::to_infos(file_info & p_out) const 16 | { 17 | double base = m_positions[1]; 18 | 19 | if (base > 0) { 20 | p_out.info_set("referenced_offset",cuesheet_format_index_time(base)); 21 | } 22 | 23 | if (m_positions[0] < base) 24 | p_out.info_set("pregap",cuesheet_format_index_time(base - m_positions[0])); 25 | else 26 | p_out.info_remove("pregap"); 27 | 28 | p_out.info_remove("index 00"); 29 | p_out.info_remove("index 01"); 30 | 31 | for(unsigned n=2;n 0) 37 | p_out.info_set(namebuffer,cuesheet_format_index_time(position)); 38 | else 39 | p_out.info_remove(namebuffer); 40 | } 41 | } 42 | 43 | static bool parse_value(const char * p_name,double & p_out) 44 | { 45 | if (p_name == NULL) return false; 46 | try { 47 | p_out = cuesheet_parse_index_time_e(p_name,strlen(p_name)); 48 | } catch(std::exception const &) {return false;} 49 | return true; 50 | } 51 | 52 | bool t_cuesheet_index_list::from_infos(file_info const & p_in,double p_base) 53 | { 54 | double pregap; 55 | bool found = false; 56 | if (!parse_value(p_in.info_get("pregap"),pregap)) pregap = 0; 57 | else found = true; 58 | m_positions[0] = p_base - pregap; 59 | m_positions[1] = p_base; 60 | for(unsigned n=2;n rects; 11 | RECT orig_client; 12 | HWND parent; 13 | HWND sizegrip; 14 | unsigned min_x,min_y,max_x,max_y; 15 | 16 | public: 17 | struct param { 18 | unsigned short id; 19 | unsigned short flags; 20 | }; 21 | private: 22 | pfc::array_t m_table; 23 | 24 | void set_parent(HWND wnd); 25 | void reset(); 26 | void on_wm_size(); 27 | public: 28 | inline void set_min_size(unsigned x,unsigned y) {min_x = x; min_y = y;} 29 | inline void set_max_size(unsigned x,unsigned y) {max_x = x; max_y = y;} 30 | void add_sizegrip(); 31 | 32 | enum { 33 | X_MOVE = 1, X_SIZE = 2, Y_MOVE = 4, Y_SIZE = 8, 34 | XY_MOVE = X_MOVE|Y_MOVE, XY_SIZE = X_SIZE|Y_SIZE, 35 | X_MOVE_Y_SIZE = X_MOVE|Y_SIZE, X_SIZE_Y_MOVE = X_SIZE|Y_MOVE, 36 | }; 37 | //the old way 38 | bool process_message(HWND wnd,UINT msg,WPARAM wp,LPARAM lp); 39 | 40 | //ATL-compatible 41 | BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult); 42 | 43 | dialog_resize_helper(const param * src,unsigned count,unsigned p_min_x,unsigned p_min_y,unsigned p_max_x,unsigned p_max_y); 44 | 45 | ~dialog_resize_helper(); 46 | 47 | PFC_CLASS_NOT_COPYABLE_EX(dialog_resize_helper); 48 | }; 49 | 50 | #endif // _DIALOG_RESIZE_HELPER_H_ 51 | 52 | #endif // _WIN32 -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/dropdown_helper.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | 3 | #ifndef _DROPDOWN_HELPER_H_ 4 | #define _DROPDOWN_HELPER_H_ 5 | 6 | class _cfg_dropdown_history_base 7 | { 8 | const unsigned m_max; 9 | void build_list(pfc::ptr_list_t & out); 10 | void parse_list(const pfc::ptr_list_t & src); 11 | public: 12 | enum {separator = '\n'}; 13 | virtual void set_state(const char * val) = 0; 14 | virtual void get_state(pfc::string_base & out) const = 0; 15 | _cfg_dropdown_history_base(unsigned p_max) : m_max(p_max) {} 16 | void on_init(HWND ctrl, const char * initVal) { 17 | add_item(initVal); setup_dropdown(ctrl); uSetWindowText(ctrl, initVal); 18 | } 19 | void setup_dropdown(HWND wnd); 20 | void setup_dropdown(HWND wnd,UINT id) {setup_dropdown(GetDlgItem(wnd,id));} 21 | bool add_item(const char * item); //returns true when the content has changed, false when not (the item was already on the list) 22 | bool add_item(const char * item, HWND combobox); //immediately adds the item to the combobox 23 | bool is_empty(); 24 | bool on_context(HWND wnd,LPARAM coords); //returns true when the content has changed 25 | }; 26 | 27 | class cfg_dropdown_history : public _cfg_dropdown_history_base { 28 | public: 29 | cfg_dropdown_history(const GUID & p_guid,unsigned p_max = 10,const char * init_vals = "") : _cfg_dropdown_history_base(p_max), m_state(p_guid, init_vals) {} 30 | void set_state(const char * val) {m_state = val;} 31 | void get_state(pfc::string_base & out) const {out = m_state;} 32 | private: 33 | cfg_string m_state; 34 | }; 35 | 36 | class cfg_dropdown_history_mt : public _cfg_dropdown_history_base { 37 | public: 38 | cfg_dropdown_history_mt(const GUID & p_guid,unsigned p_max = 10,const char * init_vals = "") : _cfg_dropdown_history_base(p_max), m_state(p_guid, init_vals) {} 39 | void set_state(const char * val) {m_state.set(val);} 40 | void get_state(pfc::string_base & out) const {m_state.get(out);} 41 | private: 42 | cfg_string_mt m_state; 43 | }; 44 | 45 | // ATL-compatible message map entry macro for installing dropdown list context menus. 46 | #define DROPDOWN_HISTORY_HANDLER(ctrlID,var) \ 47 | if(uMsg == WM_CONTEXTMENU) { \ 48 | const HWND source = (HWND) wParam; \ 49 | if (source != NULL && source == CWindow(hWnd).GetDlgItem(ctrlID)) { \ 50 | var.on_context(source,lParam); \ 51 | lResult = 0; \ 52 | return TRUE; \ 53 | } \ 54 | } 55 | 56 | #endif //_DROPDOWN_HELPER_H_ 57 | 58 | #endif // _WIN32 -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/dynamic_bitrate_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | static unsigned g_query_settings() 4 | { 5 | t_int32 temp; 6 | try { 7 | config_object::g_get_data_int32(standard_config_objects::int32_dynamic_bitrate_display_rate,temp); 8 | } catch(std::exception const &) {return 9;} 9 | if (temp < 0) return 0; 10 | return (unsigned) temp; 11 | } 12 | 13 | dynamic_bitrate_helper::dynamic_bitrate_helper() 14 | { 15 | reset(); 16 | } 17 | 18 | void dynamic_bitrate_helper::init() 19 | { 20 | if (!m_inited) 21 | { 22 | m_inited = true; 23 | unsigned temp = g_query_settings(); 24 | if (temp > 0) {m_enabled = true; m_update_interval = 1.0 / (double) temp; } 25 | else {m_enabled = false; m_update_interval = 0; } 26 | m_last_duration = 0; 27 | m_update_bits = 0; 28 | m_update_time = 0; 29 | 30 | } 31 | } 32 | 33 | void dynamic_bitrate_helper::on_frame(double p_duration,t_size p_bits) 34 | { 35 | init(); 36 | m_last_duration = p_duration; 37 | m_update_time += p_duration; 38 | m_update_bits += p_bits; 39 | } 40 | 41 | bool dynamic_bitrate_helper::on_update(file_info & p_out, double & p_timestamp_delta) 42 | { 43 | init(); 44 | 45 | bool ret = false; 46 | if (m_enabled) 47 | { 48 | if (m_update_time > m_update_interval) 49 | { 50 | int val = (int) ( ((double)m_update_bits / m_update_time + 500.0) / 1000.0 ); 51 | if (val != p_out.info_get_bitrate_vbr()) 52 | { 53 | p_timestamp_delta = - (m_update_time - m_last_duration); //relative to last frame beginning; 54 | p_out.info_set_bitrate_vbr(val); 55 | ret = true; 56 | } 57 | m_update_bits = 0; 58 | m_update_time = 0; 59 | } 60 | } 61 | else 62 | { 63 | m_update_bits = 0; 64 | m_update_time = 0; 65 | } 66 | 67 | return ret; 68 | 69 | } 70 | 71 | void dynamic_bitrate_helper::reset() 72 | { 73 | m_inited = false; 74 | } 75 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/dynamic_bitrate_helper.h: -------------------------------------------------------------------------------- 1 | class dynamic_bitrate_helper 2 | { 3 | public: 4 | dynamic_bitrate_helper(); 5 | void on_frame(double p_duration,t_size p_bits); 6 | bool on_update(file_info & p_out, double & p_timestamp_delta); 7 | void reset(); 8 | private: 9 | void init(); 10 | double m_last_duration; 11 | t_size m_update_bits; 12 | double m_update_time; 13 | double m_update_interval; 14 | bool m_inited, m_enabled; 15 | }; -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/file_cached.h: -------------------------------------------------------------------------------- 1 | // obsolete, moved to SDK -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/file_list_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #ifndef _MSC_VER 4 | #define _strdup strdup 5 | #endif 6 | 7 | static void file_list_remove_duplicates(pfc::ptr_list_t & out) 8 | { 9 | t_size n, m = out.get_count(); 10 | out.sort_t(metadb::path_compare); 11 | bit_array_bittable mask(m); 12 | t_size duplicates = 0; 13 | for(n=1;n0) { 17 | out.free_mask(mask); 18 | } 19 | } 20 | 21 | 22 | namespace file_list_helper 23 | { 24 | t_size file_list_from_metadb_handle_list::g_get_count(metadb_handle_list_cref data, t_size max) { 25 | pfc::avltree_t content; 26 | const t_size inCount = data.get_size(); 27 | for(t_size walk = 0; walk < inCount && content.get_count() < max; ++walk) { 28 | content += data[walk]->get_path(); 29 | } 30 | return content.get_count(); 31 | } 32 | void file_list_from_metadb_handle_list::__add(const char * p_what) { 33 | char * temp = _strdup(p_what); 34 | if (temp == NULL) throw std::bad_alloc(); 35 | try {m_data.add_item(temp); } catch(...) {free(temp); throw;} 36 | } 37 | 38 | void file_list_from_metadb_handle_list::init_from_list(const list_base_const_t & p_list) 39 | { 40 | m_data.free_all(); 41 | 42 | t_size n, m = p_list.get_count(); 43 | for(n=0;nget_path() ); 45 | } 46 | file_list_remove_duplicates(m_data); 47 | } 48 | 49 | void file_list_from_metadb_handle_list::init_from_list_display(const list_base_const_t & p_list) 50 | { 51 | m_data.free_all(); 52 | 53 | pfc::string8_fastalloc temp; 54 | 55 | t_size n, m = p_list.get_count(); 56 | for(n=0;nget_path(),temp); 59 | __add(temp); 60 | } 61 | file_list_remove_duplicates(m_data); 62 | 63 | 64 | } 65 | 66 | t_size file_list_from_metadb_handle_list::get_count() const {return m_data.get_count();} 67 | void file_list_from_metadb_handle_list::get_item_ex(const char * & p_out,t_size n) const {p_out = m_data.get_item(n);} 68 | 69 | file_list_from_metadb_handle_list::~file_list_from_metadb_handle_list() 70 | { 71 | m_data.free_all(); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/file_list_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef _foobar2000_helpers_file_list_helper_ 2 | #define _foobar2000_helpers_file_list_helper_ 3 | 4 | 5 | namespace file_list_helper 6 | { 7 | //list guaranteed to be sorted by metadb::path_compare 8 | class file_list_from_metadb_handle_list : public pfc::list_base_const_t { 9 | public: 10 | 11 | static t_size g_get_count(const list_base_const_t & p_list, t_size max = ~0); 12 | 13 | void init_from_list(const list_base_const_t & p_list); 14 | void init_from_list_display(const list_base_const_t & p_list); 15 | 16 | t_size get_count() const; 17 | void get_item_ex(const char * & p_out,t_size n) const; 18 | 19 | ~file_list_from_metadb_handle_list(); 20 | 21 | private: 22 | void __add(const char * p_what); 23 | pfc::ptr_list_t m_data; 24 | }; 25 | 26 | 27 | }; 28 | 29 | 30 | #endif //_foobar2000_helpers_file_list_helper_ -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/file_move_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | bool file_move_helper::g_on_deleted(const pfc::list_base_const_t & p_files) 4 | { 5 | file_operation_callback::g_on_files_deleted(p_files); 6 | return true; 7 | } 8 | 9 | t_size file_move_helper::g_filter_dead_files_sorted_make_mask(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead,bit_array_var & p_mask) 10 | { 11 | t_size n, m = p_data.get_count(); 12 | t_size found = 0; 13 | for(n=0;nget_path(),dummy); 17 | if (dead) found++; 18 | p_mask.set(n,dead); 19 | } 20 | return found; 21 | } 22 | 23 | t_size file_move_helper::g_filter_dead_files_sorted(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead) 24 | { 25 | bit_array_bittable mask(p_data.get_count()); 26 | t_size found = g_filter_dead_files_sorted_make_mask(p_data,p_dead,mask); 27 | if (found > 0) p_data.remove_mask(mask); 28 | return found; 29 | } 30 | 31 | t_size file_move_helper::g_filter_dead_files(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead) 32 | { 33 | pfc::ptr_list_t temp; 34 | temp.add_items(p_dead); 35 | temp.sort_t(metadb::path_compare); 36 | return g_filter_dead_files_sorted(p_data,temp); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/file_move_helper.h: -------------------------------------------------------------------------------- 1 | class file_move_helper { 2 | public: 3 | static bool g_on_deleted(const pfc::list_base_const_t & p_files); 4 | 5 | static t_size g_filter_dead_files_sorted_make_mask(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead,bit_array_var & p_mask); 6 | static t_size g_filter_dead_files_sorted(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead); 7 | static t_size g_filter_dead_files(pfc::list_base_t & p_data,const pfc::list_base_const_t & p_dead); 8 | }; 9 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/filetimetools.h: -------------------------------------------------------------------------------- 1 | namespace foobar2000_io { 2 | t_filetimestamp filetimestamp_from_string(const char * date); 3 | 4 | //! Warning: this formats according to system timezone settings, created strings should be used for display only, never for storage. 5 | class format_filetimestamp { 6 | public: 7 | format_filetimestamp(t_filetimestamp p_timestamp); 8 | operator const char*() const {return m_buffer;} 9 | const char * get_ptr() const {return m_buffer;} 10 | private: 11 | pfc::string_fixed_t<32> m_buffer; 12 | }; 13 | 14 | class format_filetimestamp_utc { 15 | public: 16 | format_filetimestamp_utc(t_filetimestamp p_timestamp); 17 | operator const char*() const {return m_buffer;} 18 | const char * get_ptr() const {return m_buffer;} 19 | private: 20 | pfc::string_fixed_t<32> m_buffer; 21 | }; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/fullFileBuffer.h: -------------------------------------------------------------------------------- 1 | class fullFileBuffer { 2 | public: 3 | fullFileBuffer() { 4 | //hMutex = CreateMutex(NULL, FALSE, pfc::stringcvt::string_os_from_utf8(pfc::string_formatter() << "{3ABC4D98-2510-431C-A720-26BEB45F0278}-" << (uint32_t) GetCurrentProcessId())); 5 | } 6 | ~fullFileBuffer() { 7 | //CloseHandle(hMutex); 8 | } 9 | file::ptr open(const char * path, abort_callback & abort, file::ptr hint, t_filesize sizeMax = 1024*1024*256) { 10 | //mutexScope scope(hMutex, abort); 11 | 12 | file::ptr f; 13 | if (hint.is_valid()) f = hint; 14 | else filesystem::g_open_read( f, path, abort ); 15 | t_filesize fs = f->get_size(abort); 16 | if (fs < sizeMax) /*rejects size-unknown too*/ { 17 | try { 18 | service_ptr_t r = new service_impl_t(); 19 | r->init( f, abort ); 20 | f = r; 21 | } catch(std::bad_alloc) {} 22 | } 23 | return f; 24 | } 25 | 26 | private: 27 | fullFileBuffer(const fullFileBuffer&); 28 | void operator=(const fullFileBuffer&); 29 | 30 | //HANDLE hMutex; 31 | }; 32 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef _FOOBAR2000_SDK_HELPERS_H_ 2 | #define _FOOBAR2000_SDK_HELPERS_H_ 3 | 4 | #include "input_helpers.h" 5 | #include "create_directory_helper.h" 6 | #include "dialog_resize_helper.h" 7 | #include "dropdown_helper.h" 8 | #include "window_placement_helper.h" 9 | #include "win32_dialog.h" 10 | #include "cuesheet_index_list.h" 11 | #include "cue_creator.h" 12 | #include "cue_parser.h" 13 | #include "text_file_loader.h" 14 | #include "file_list_helper.h" 15 | #include "listview_helper.h" 16 | #include "stream_buffer_helper.h" 17 | #include "file_info_const_impl.h" 18 | #include "dynamic_bitrate_helper.h" 19 | #include "cfg_guidlist.h" 20 | #include "file_move_helper.h" 21 | #include "file_cached.h" 22 | #include "seekabilizer.h" 23 | #include "string_filter.h" 24 | #include "bitreader_helper.h" 25 | #include "mp3_utils.h" 26 | #include "win32_misc.h" 27 | #include "fb2k_threads.h" 28 | #include "COM_utils.h" 29 | #include "metadb_io_hintlist.h" 30 | #include "meta_table_builder.h" 31 | #include "icon_remapping_wildcard.h" 32 | #include "clipboard.h" 33 | #include "IDataObjectUtils.h" 34 | #include "CallForwarder.h" 35 | #include "playlist_position_reference_tracker.h" 36 | #include "ThreadUtils.h" 37 | #include "ProcessUtils.h" 38 | #include "VisUtils.h" 39 | #include "filetimetools.h" 40 | #include "ProfileCache.h" 41 | #include "file_win32_wrapper.h" 42 | #include "fullFileBuffer.h" 43 | #include "CPowerRequest.h" 44 | #include "writer_wav.h" 45 | 46 | #endif //_FOOBAR2000_SDK_HELPERS_H_ 47 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/icon_remapping_wildcard.h: -------------------------------------------------------------------------------- 1 | class icon_remapping_wildcard_impl : public icon_remapping { 2 | public: 3 | icon_remapping_wildcard_impl(const char * p_pattern,const char * p_iconname) : m_pattern(p_pattern), m_iconname(p_iconname) {} 4 | bool query(const char * p_extension,pfc::string_base & p_iconname) { 5 | if (wildcard_helper::test(p_extension,m_pattern,true)) { 6 | p_iconname = m_iconname; return true; 7 | } else { 8 | return false; 9 | } 10 | } 11 | private: 12 | pfc::string8 m_pattern,m_iconname; 13 | }; 14 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/listview_helper.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | 3 | namespace listview_helper 4 | { 5 | unsigned insert_item(HWND p_listview,unsigned p_index,const char * p_name,LPARAM p_param);//returns index of new item on success, infinite on failure 6 | 7 | unsigned insert_column(HWND p_listview,unsigned p_index,const char * p_name,unsigned p_width_dlu);//returns index of new item on success, infinite on failure 8 | 9 | bool set_item_text(HWND p_listview,unsigned p_index,unsigned p_column,const char * p_name); 10 | 11 | bool is_item_selected(HWND p_listview,unsigned p_index); 12 | 13 | void set_item_selection(HWND p_listview,unsigned p_index,bool p_state); 14 | 15 | bool select_single_item(HWND p_listview,unsigned p_index); 16 | 17 | bool ensure_visible(HWND p_listview,unsigned p_index); 18 | 19 | void get_item_text(HWND p_listview,unsigned p_index,unsigned p_column,pfc::string_base & p_out); 20 | 21 | unsigned insert_item2(HWND p_listview, unsigned p_index, const char * col0, const char * col1, LPARAM p_param = 0); 22 | unsigned insert_item3(HWND p_listview, unsigned p_index, const char * col0, const char * col1, const char * col2, LPARAM p_param = 0); 23 | 24 | 25 | }; 26 | 27 | static int ListView_GetFirstSelection(HWND p_listview) { 28 | return ListView_GetNextItem(p_listview,-1,LVNI_SELECTED); 29 | } 30 | 31 | static int ListView_GetSingleSelection(HWND p_listview) { 32 | if (ListView_GetSelectedCount(p_listview) != 1) return -1; 33 | return ListView_GetFirstSelection(p_listview); 34 | } 35 | 36 | static int ListView_GetFocusItem(HWND p_listview) { 37 | return ListView_GetNextItem(p_listview,-1,LVNI_FOCUSED); 38 | } 39 | 40 | static bool ListView_IsItemSelected(HWND p_listview,int p_index) { 41 | return ListView_GetItemState(p_listview,p_index,LVIS_SELECTED) != 0; 42 | } 43 | 44 | void ListView_GetContextMenuPoint(HWND p_list,LPARAM p_coords,POINT & p_point,int & p_selection); 45 | void ListView_GetContextMenuPoint(HWND p_list,POINT p_coords,POINT & p_point,int & p_selection); 46 | 47 | int ListView_GetColumnCount(HWND listView); 48 | 49 | #endif -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/metadb_io_hintlist.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | void metadb_io_hintlist::run() { 4 | if (m_entries.get_count() > 0) { 5 | static_api_ptr_t()->hint_multi_async( 6 | metadb_io_hintlist_wrapper_part1(m_entries), 7 | metadb_io_hintlist_wrapper_part2(m_entries), 8 | metadb_io_hintlist_wrapper_part3(m_entries), 9 | metadb_io_hintlist_wrapper_part4(m_entries) 10 | ); 11 | } 12 | m_entries.remove_all(); 13 | } 14 | 15 | void metadb_io_hintlist::add(metadb_handle_ptr const & p_handle,const file_info & p_info,t_filestats const & p_stats,bool p_fresh) { 16 | t_entry entry; 17 | entry.m_handle = p_handle; 18 | entry.m_info.new_t(p_info); 19 | entry.m_stats = p_stats; 20 | entry.m_fresh = p_fresh; 21 | m_entries.add_item(entry); 22 | } 23 | 24 | void metadb_io_hintlist::hint_reader(service_ptr_t p_reader, const char * p_path,abort_callback & p_abort) { 25 | static_api_ptr_t api; 26 | const t_uint32 subsongcount = p_reader->get_subsong_count(); 27 | t_filestats stats = p_reader->get_file_stats(p_abort); 28 | for(t_uint32 subsong = 0; subsong < subsongcount; subsong++) { 29 | t_uint32 subsong_id = p_reader->get_subsong(subsong); 30 | metadb_handle_ptr handle; 31 | api->handle_create(handle,make_playable_location(p_path,subsong_id)); 32 | if (handle->should_reload(stats,true)) { 33 | file_info_impl temp; 34 | p_reader->get_info(subsong_id,temp,p_abort); 35 | 36 | add(handle,temp,stats,true); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/metadb_io_hintlist.h: -------------------------------------------------------------------------------- 1 | 2 | class metadb_io_hintlist { 3 | public: 4 | void hint_reader(service_ptr_t p_reader, const char * p_path,abort_callback & p_abort); 5 | void add(metadb_handle_ptr const & p_handle,const file_info & p_info,t_filestats const & p_stats,bool p_fresh); 6 | void run(); 7 | t_size get_pending_count() const {return m_entries.get_count();} 8 | private: 9 | struct t_entry { 10 | metadb_handle_ptr m_handle; 11 | pfc::rcptr_t m_info; 12 | t_filestats m_stats; 13 | bool m_fresh; 14 | }; 15 | class metadb_io_hintlist_wrapper_part1 : public pfc::list_base_const_t { 16 | public: 17 | metadb_io_hintlist_wrapper_part1(const pfc::list_base_const_t & p_list) : m_list(p_list) {} 18 | t_size get_count() const {return m_list.get_count();} 19 | void get_item_ex(metadb_handle_ptr & p_out, t_size n) const {p_out = m_list[n].m_handle;} 20 | 21 | private: 22 | const pfc::list_base_const_t & m_list; 23 | }; 24 | class metadb_io_hintlist_wrapper_part2 : public pfc::list_base_const_t { 25 | public: 26 | metadb_io_hintlist_wrapper_part2(const pfc::list_base_const_t & p_list) : m_list(p_list) {} 27 | t_size get_count() const {return m_list.get_count();} 28 | void get_item_ex(const file_info* & p_out, t_size n) const {p_out = &*m_list[n].m_info;} 29 | private: 30 | const pfc::list_base_const_t & m_list; 31 | }; 32 | class metadb_io_hintlist_wrapper_part3 : public pfc::list_base_const_t { 33 | public: 34 | metadb_io_hintlist_wrapper_part3(const pfc::list_base_const_t & p_list) : m_list(p_list) {} 35 | t_size get_count() const {return m_list.get_count();} 36 | void get_item_ex(t_filestats & p_out, t_size n) const {p_out = m_list[n].m_stats;} 37 | private: 38 | const pfc::list_base_const_t & m_list; 39 | }; 40 | class metadb_io_hintlist_wrapper_part4 : public bit_array { 41 | public: 42 | metadb_io_hintlist_wrapper_part4(const pfc::list_base_const_t & p_list) : m_list(p_list) {} 43 | bool get(t_size n) const {return m_list[n].m_fresh;} 44 | private: 45 | const pfc::list_base_const_t & m_list; 46 | }; 47 | 48 | pfc::list_t m_entries; 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/mp3_utils.h: -------------------------------------------------------------------------------- 1 | namespace mp3_utils 2 | { 3 | 4 | enum { 5 | MPG_MD_STEREO=0, 6 | MPG_MD_JOINT_STEREO=1, 7 | MPG_MD_DUAL_CHANNEL=2, 8 | MPG_MD_MONO=3, 9 | }; 10 | 11 | typedef t_uint8 byte; 12 | 13 | enum {MPEG_1, MPEG_2, MPEG_25}; 14 | 15 | struct TMPEGFrameInfo 16 | { 17 | unsigned m_bytes; 18 | unsigned m_sample_rate; 19 | unsigned m_layer; 20 | unsigned m_mpegversion; 21 | unsigned m_channels; 22 | unsigned m_duration; 23 | unsigned m_channel_mode; 24 | bool m_crc; 25 | }; 26 | 27 | 28 | bool ParseMPEGFrameHeader(TMPEGFrameInfo & p_info,const t_uint8 p_header[4]); 29 | bool ValidateFrameCRC(const t_uint8 * frameData, t_size frameSize); 30 | bool ValidateFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo); 31 | 32 | //! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize). 33 | t_uint16 ExtractFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo); 34 | //! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize). 35 | t_uint16 CalculateFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo); 36 | //! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize). 37 | void RecalculateFrameCRC(t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo); 38 | 39 | unsigned QueryMPEGFrameSize(const t_uint8 p_header[4]); 40 | bool IsSameStream(TMPEGFrameInfo const & p_frame1,TMPEGFrameInfo const & p_frame2); 41 | }; 42 | 43 | class mp3header 44 | { 45 | t_uint8 bytes[4]; 46 | public: 47 | 48 | inline void copy(const mp3header & src) {memcpy(bytes,src.bytes,4);} 49 | inline void copy_raw(const void * src) {memcpy(bytes,src,4);} 50 | 51 | inline mp3header(const mp3header & src) {copy(src);} 52 | inline mp3header() {} 53 | 54 | inline const mp3header & operator=(const mp3header & src) {copy(src); return *this;} 55 | 56 | inline void get_bytes(void * out) {memcpy(out,bytes,4);} 57 | inline unsigned get_frame_size() const {return mp3_utils::QueryMPEGFrameSize(bytes);} 58 | inline bool decode(mp3_utils::TMPEGFrameInfo & p_out) {return mp3_utils::ParseMPEGFrameHeader(p_out,bytes);} 59 | 60 | unsigned get_samples_per_frame(); 61 | }; 62 | 63 | static inline mp3header mp3header_from_buffer(const void * p_buffer) 64 | { 65 | mp3header temp; 66 | temp.copy_raw(p_buffer); 67 | return temp; 68 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/seekabilizer.h: -------------------------------------------------------------------------------- 1 | class seekabilizer_backbuffer 2 | { 3 | public: 4 | void initialize(t_size p_size); 5 | void write(const void * p_buffer,t_size p_bytes); 6 | void read(t_size p_backlogdepth,void * p_buffer,t_size p_bytes) const; 7 | t_size get_depth() const; 8 | void reset(); 9 | t_size get_max_depth() const; 10 | private: 11 | pfc::array_t m_buffer; 12 | t_size m_depth,m_cursor; 13 | }; 14 | 15 | class seekabilizer : public file_readonly { 16 | public: 17 | void initialize(service_ptr_t p_base,t_size p_buffer_size,abort_callback & p_abort); 18 | 19 | static void g_seekabilize(service_ptr_t & p_reader,t_size p_buffer_size,abort_callback & p_abort); 20 | 21 | t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort); 22 | t_filesize get_size(abort_callback & p_abort); 23 | t_filesize get_position(abort_callback & p_abort); 24 | void seek(t_filesize p_position,abort_callback & p_abort); 25 | bool can_seek(); 26 | bool get_content_type(pfc::string_base & p_out); 27 | bool is_in_memory(); 28 | void on_idle(abort_callback & p_abort); 29 | t_filetimestamp get_timestamp(abort_callback & p_abort); 30 | void reopen(abort_callback & p_abort); 31 | bool is_remote(); 32 | private: 33 | service_ptr_t m_file; 34 | seekabilizer_backbuffer m_buffer; 35 | t_filesize m_size,m_position,m_position_base; 36 | }; -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/stream_buffer_helper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | stream_reader_buffered::stream_reader_buffered(stream_reader * p_base,t_size p_buffer) : m_base(p_base) 4 | { 5 | m_buffer.set_size_in_range(pfc::min_t(1024, p_buffer), p_buffer); 6 | m_bufferRemaining = 0; 7 | } 8 | 9 | t_size stream_reader_buffered::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) { 10 | if (p_bytes <= m_bufferRemaining) { 11 | memcpy( p_buffer, m_bufferPtr, p_bytes ); 12 | m_bufferRemaining -= p_bytes; 13 | m_bufferPtr += p_bytes; 14 | return p_bytes; 15 | } 16 | 17 | p_abort.check(); 18 | char * output = (char*) p_buffer; 19 | t_size output_ptr = 0; 20 | 21 | while(output_ptr < p_bytes) { 22 | { 23 | t_size delta = pfc::min_t(p_bytes - output_ptr, m_bufferRemaining); 24 | if (delta > 0) 25 | { 26 | memcpy(output + output_ptr, m_bufferPtr, delta); 27 | output_ptr += delta; 28 | m_bufferPtr += delta; 29 | m_bufferRemaining -= delta; 30 | } 31 | } 32 | 33 | if (m_bufferRemaining == 0) 34 | { 35 | t_size bytes_read; 36 | bytes_read = m_base->read(m_buffer.get_ptr(), m_buffer.get_size(), p_abort); 37 | m_bufferPtr = m_buffer.get_ptr(); 38 | m_bufferRemaining = bytes_read; 39 | 40 | if (m_bufferRemaining == 0) break; 41 | } 42 | 43 | } 44 | 45 | return output_ptr; 46 | } 47 | 48 | stream_writer_buffered::stream_writer_buffered(stream_writer * p_base,t_size p_buffer) 49 | : m_base(p_base) 50 | { 51 | m_buffer.set_size_in_range(pfc::min_t(1024, p_buffer), p_buffer); 52 | m_buffer_ptr = 0; 53 | } 54 | 55 | void stream_writer_buffered::write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) { 56 | p_abort.check_e(); 57 | const char * source = (const char*)p_buffer; 58 | t_size source_remaining = p_bytes; 59 | const t_size buffer_size = m_buffer.get_size(); 60 | if (source_remaining >= buffer_size) 61 | { 62 | flush(p_abort); 63 | m_base->write_object(source,source_remaining,p_abort); 64 | return; 65 | } 66 | 67 | if (m_buffer_ptr + source_remaining >= buffer_size) 68 | { 69 | t_size delta = buffer_size - m_buffer_ptr; 70 | memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,delta); 71 | source += delta; 72 | source_remaining -= delta; 73 | m_buffer_ptr += delta; 74 | flush(p_abort); 75 | } 76 | 77 | memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,source_remaining); 78 | m_buffer_ptr += source_remaining; 79 | } 80 | 81 | 82 | void stream_writer_buffered::flush(abort_callback & p_abort) { 83 | if (m_buffer_ptr > 0) { 84 | m_base->write_object(m_buffer.get_ptr(),m_buffer_ptr,p_abort); 85 | m_buffer_ptr = 0; 86 | } 87 | } -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/stream_buffer_helper.h: -------------------------------------------------------------------------------- 1 | class stream_reader_buffered : public stream_reader 2 | { 3 | public: 4 | stream_reader_buffered(stream_reader * p_base,t_size p_buffer); 5 | t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort); 6 | private: 7 | stream_reader * m_base; 8 | pfc::array_t m_buffer; 9 | const char * m_bufferPtr; 10 | size_t m_bufferRemaining; 11 | }; 12 | 13 | class stream_writer_buffered : public stream_writer 14 | { 15 | public: 16 | stream_writer_buffered(stream_writer * p_base,t_size p_buffer); 17 | 18 | void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort); 19 | 20 | void flush(abort_callback & p_abort); 21 | 22 | private: 23 | stream_writer * m_base; 24 | pfc::array_t m_buffer; 25 | t_size m_buffer_ptr; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/string_filter.h: -------------------------------------------------------------------------------- 1 | class string_filter_noncasesensitive { 2 | public: 3 | string_filter_noncasesensitive(const char * p_string,t_size p_string_len = ~0) { 4 | ::uStringLower(m_pattern,p_string,p_string_len); 5 | } 6 | 7 | bool test(const char * p_string,t_size p_string_len = ~0) const { 8 | ::uStringLower(m_lowercasebuffer,p_string,p_string_len); 9 | t_size walk = 0; 10 | while(m_pattern[walk] != 0) { 11 | while(m_pattern[walk] == ' ') walk++; 12 | t_size delta = 0; 13 | while(m_pattern[walk+delta] != 0 && m_pattern[walk+delta] != ' ') delta++; 14 | if (delta > 0) { 15 | if (pfc::string_find_first_ex(m_lowercasebuffer,~0,m_pattern+walk,delta) == ~0) return false; 16 | } 17 | walk += delta; 18 | } 19 | return true; 20 | } 21 | private: 22 | mutable pfc::string8_fastalloc m_lowercasebuffer; 23 | pfc::string8 m_pattern; 24 | }; 25 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/text_file_loader.h: -------------------------------------------------------------------------------- 1 | namespace text_file_loader 2 | { 3 | void write(const service_ptr_t & p_file,abort_callback & p_abort,const char * p_string,bool is_utf8); 4 | void read(const service_ptr_t & p_file,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8); 5 | 6 | void write(const char * p_path,abort_callback & p_abort,const char * p_string,bool is_utf8); 7 | void read(const char * p_path,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8); 8 | 9 | }; -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/window_placement_helper.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | 3 | #ifndef _WINDOW_PLACEMENT_HELPER_H_ 4 | #define _WINDOW_PLACEMENT_HELPER_H_ 5 | 6 | class cfg_window_placement : public cfg_var 7 | { 8 | public: 9 | bool on_window_creation(HWND window);//returns true if window position has been changed, false if not 10 | void on_window_creation_silent(HWND window); 11 | void on_window_destruction(HWND window); 12 | bool read_from_window(HWND window); 13 | void get_data_raw(stream_writer * p_stream,abort_callback & p_abort); 14 | void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort); 15 | cfg_window_placement(const GUID & p_guid); 16 | private: 17 | pfc::list_hybrid_t m_windows; 18 | WINDOWPLACEMENT m_data; 19 | }; 20 | 21 | class cfg_window_size : public cfg_var 22 | { 23 | public: 24 | bool on_window_creation(HWND window);//returns true if window position has been changed, false if not 25 | void on_window_destruction(HWND window); 26 | bool read_from_window(HWND window); 27 | void get_data_raw(stream_writer * p_stream,abort_callback & p_abort); 28 | void set_data_raw(stream_reader * p_stream,t_size p_sizehint,abort_callback & p_abort); 29 | cfg_window_size(const GUID & p_guid); 30 | private: 31 | pfc::list_hybrid_t m_windows; 32 | t_uint32 m_width,m_height; 33 | }; 34 | 35 | 36 | #endif //_WINDOW_PLACEMENT_HELPER_H_ 37 | 38 | #endif // _WIN32 -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/helpers/writer_wav.h: -------------------------------------------------------------------------------- 1 | #ifndef _foobar2000_wav_writer_h_ 2 | #define _foobar2000_wav_writer_h_ 3 | 4 | #ifdef _WIN32 5 | #include 6 | #endif 7 | 8 | struct wavWriterSetup_t 9 | { 10 | unsigned m_bps,m_bpsValid,m_samplerate,m_channels,m_channel_mask; 11 | bool m_float,m_dither, m_wave64; 12 | 13 | 14 | void initialize(const audio_chunk & p_chunk,unsigned p_bps,bool p_float,bool p_dither, bool p_wave64 = false); 15 | void initialize2(const audio_chunk & p_chunk,unsigned p_bps, unsigned p_bpsValid,bool p_float,bool p_dither, bool p_wave64 = false); 16 | void initialize3(const audio_chunk::spec_t & spec, unsigned bps, unsigned bpsValid, bool bFloat, bool bDither, bool bWave64 = false); 17 | 18 | #ifdef _WAVEFORMATEX_ 19 | void setup_wfx(WAVEFORMATEX & p_wfx); 20 | #endif 21 | #ifdef _WAVEFORMATEXTENSIBLE_ 22 | void setup_wfxe(WAVEFORMATEXTENSIBLE & p_wfx); 23 | #endif 24 | bool needWFXE() const; 25 | }; 26 | 27 | class CWavWriter 28 | { 29 | public: 30 | void open(const char * p_path, const wavWriterSetup_t & p_setup, abort_callback & p_abort); 31 | void open(service_ptr_t p_file, const wavWriterSetup_t & p_setup, abort_callback & p_abort); 32 | void write(const audio_chunk & p_chunk,abort_callback & p_abort); 33 | void finalize(abort_callback & p_abort); 34 | void close(); 35 | bool is_open() const { return m_file.is_valid(); } 36 | audio_chunk::spec_t get_spec() const; 37 | private: 38 | size_t align(abort_callback & abort); 39 | void writeSize(t_uint64 size, abort_callback & abort); 40 | bool is64() const {return m_setup.m_wave64;} 41 | t_uint32 chunkOverhead() const {return is64() ? 24 : 8;} 42 | t_uint32 idOverhead() const {return is64() ? 16 : 4;} 43 | void writeID(const GUID & id, abort_callback & abort); 44 | service_ptr_t m_file; 45 | service_ptr_t m_postprocessor; 46 | wavWriterSetup_t m_setup; 47 | bool m_wfxe; 48 | t_uint64 m_offset_fix1,m_offset_fix2,m_offset_fix1_delta,m_bytes_written; 49 | mem_block_container_aligned_incremental_impl<16> m_postprocessor_output; 50 | }; 51 | 52 | #endif //_foobar2000_wav_writer_h_ -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/shared/filedialogs.h: -------------------------------------------------------------------------------- 1 | class uGetOpenFileNameMultiResult_impl : public uGetOpenFileNameMultiResult { 2 | pfc::list_t m_data; 3 | public: 4 | void AddItem(pfc::stringp param) {m_data.add_item(param);} 5 | t_size get_count() const {return m_data.get_count();} 6 | void get_item_ex(const char * & out,t_size n) const {out = m_data[n].ptr();} 7 | }; 8 | -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/shared/shared.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/foobar-sdk/foobar2000/shared/shared.lib -------------------------------------------------------------------------------- /foobar-sdk/foobar2000/shared/win32_misc.h: -------------------------------------------------------------------------------- 1 | class uDebugLog : public pfc::string_formatter { 2 | public: 3 | ~uDebugLog() {*this << "\n"; uOutputDebugString(get_ptr());} 4 | }; 5 | 6 | #define FB2K_DebugLog() uDebugLog()._formatter() 7 | 8 | 9 | class win32_font { 10 | public: 11 | win32_font(HFONT p_initval) : m_font(p_initval) {} 12 | win32_font() : m_font(NULL) {} 13 | ~win32_font() {release();} 14 | 15 | void release() { 16 | HFONT temp = detach(); 17 | if (temp != NULL) DeleteObject(temp); 18 | } 19 | 20 | void set(HFONT p_font) {release(); m_font = p_font;} 21 | HFONT get() const {return m_font;} 22 | HFONT detach() {return pfc::replace_t(m_font,(HFONT)NULL);} 23 | 24 | void create(const t_font_description & p_desc) { 25 | SetLastError(NO_ERROR); 26 | HFONT temp = p_desc.create(); 27 | if (temp == NULL) throw exception_win32(GetLastError()); 28 | set(temp); 29 | } 30 | 31 | bool is_valid() const {return m_font != NULL;} 32 | 33 | private: 34 | win32_font(const win32_font&); 35 | const win32_font & operator=(const win32_font &); 36 | 37 | HFONT m_font; 38 | }; 39 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := pfc 6 | 7 | LOCAL_ARM_MODE := arm 8 | 9 | LOCAL_SRC_FILES := audio_math.cpp audio_sample.cpp base64.cpp bit_array.cpp bsearch.cpp cpuid.cpp filehandle.cpp guid.cpp nix-objects.cpp other.cpp pathUtils.cpp printf.cpp selftest.cpp sort.cpp stdafx.cpp stringNew.cpp string_base.cpp string_conv.cpp synchro_nix.cpp threads.cpp timers.cpp utf8.cpp wildcard.cpp win-objects.cpp 10 | 11 | LOCAL_STATIC_LIBRARIES := cpufeatures 12 | 13 | include $(BUILD_SHARED_LIBRARY) 14 | 15 | $(call import-module,android/cpufeatures) 16 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/audio_sample.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | namespace pfc { 4 | audio_sample audio_math::decodeFloat24ptr(const void * sourcePtr) { 5 | PFC_STATIC_ASSERT(pfc::byte_order_is_little_endian); 6 | union { 7 | uint8_t bytes[4]; 8 | float v; 9 | } u; 10 | const uint8_t * s = reinterpret_cast(sourcePtr); 11 | u.bytes[0] = 0; 12 | u.bytes[1] = s[0]; 13 | u.bytes[2] = s[1]; 14 | u.bytes[3] = s[2]; 15 | return u.v; 16 | } 17 | audio_sample audio_math::decodeFloat24ptrbs(const void * sourcePtr) { 18 | PFC_STATIC_ASSERT(pfc::byte_order_is_little_endian); 19 | union { 20 | uint8_t bytes[4]; 21 | float v; 22 | } u; 23 | const uint8_t * s = reinterpret_cast(sourcePtr); 24 | u.bytes[0] = 0; 25 | u.bytes[1] = s[2]; 26 | u.bytes[2] = s[1]; 27 | u.bytes[3] = s[0]; 28 | return u.v; 29 | } 30 | 31 | audio_sample audio_math::decodeFloat16(uint16_t source) { 32 | const unsigned fractionBits = 10; 33 | const unsigned widthBits = 16; 34 | typedef uint16_t source_t; 35 | 36 | /* typedef uint64_t out_t; typedef double retval_t; 37 | enum { 38 | outExponent = 11, 39 | outFraction = 52, 40 | outExponentShift = (1 << (outExponent-1))-1 41 | };*/ 42 | 43 | typedef uint32_t out_t; typedef float retval_t; 44 | enum { 45 | outExponent = 8, 46 | outFraction = 23, 47 | outExponentShift = (1 << (outExponent-1))-1 48 | }; 49 | 50 | const unsigned exponentBits = widthBits - fractionBits - 1; 51 | // 1 bit sign | exponent | fraction 52 | source_t fraction = source & (((source_t)1 << fractionBits)-1); 53 | source >>= fractionBits; 54 | int exponent = (int)( source & (((source_t)1 << exponentBits)-1) ) - (int)((1 << (exponentBits-1))-1); 55 | source >>= exponentBits; 56 | 57 | if (outExponent + outExponentShift <= 0) return 0; 58 | 59 | out_t output = (out_t)( source&1 ); 60 | output <<= outExponent; 61 | output |= (unsigned) (exponent + outExponentShift) & ( (1<> -shift); 65 | else output |= (out_t) (fraction << shift); 66 | return *(retval_t*)&output / pfc::audio_math::float16scale; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/base64.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | class string_base; 3 | void base64_encode(pfc::string_base & out, const void * in, t_size inSize); 4 | void base64_encode_append(pfc::string_base & out, const void * in, t_size inSize); 5 | t_size base64_decode_estimate(const char * text); 6 | void base64_decode(const char * text, void * out); 7 | 8 | template void base64_decode_array(t_buffer & out, const char * text) { 9 | PFC_STATIC_ASSERT( sizeof(out[0]) == 1 ); 10 | out.set_size_discard( base64_decode_estimate(text) ); 11 | base64_decode(text, out.get_ptr()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/bit_array_impl_part2.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | //! Generic variable bit array implementation. \n 3 | //! Not very efficient to handle lots of items set to true but offers fast searches for true values and accepts arbitrary indexes, contrary to bit_array_bittable. Note that searches for false values are relatively inefficient. 4 | class bit_array_var_impl : public bit_array_var { 5 | public: 6 | bit_array_var_impl( ) {} 7 | bit_array_var_impl( const bit_array & source, size_t sourceCount); 8 | bool get(t_size n) const; 9 | t_size find(bool val,t_size start,t_ssize count) const; 10 | void set(t_size n,bool val); 11 | void set(t_size n) {m_data += n;} 12 | void unset(t_size n) {m_data -= n;} 13 | t_size get_true_count() const {return m_data.get_count();} 14 | void clear() {m_data.remove_all();} 15 | private: 16 | avltree_t m_data; 17 | }; 18 | 19 | 20 | //! Specialized implementation of bit_array. \n 21 | //! Indended for scenarios where fast searching for true values in a large list is needed, combined with low footprint regardless of the amount of items. 22 | //! Call add() repeatedly with the true val indexes. If the indexes were not added in increasing order, call presort() when done with adding. 23 | class bit_array_flatIndexList : public bit_array { 24 | public: 25 | bit_array_flatIndexList(); 26 | 27 | void add( size_t n ); 28 | 29 | bool get(t_size n) const; 30 | t_size find(bool val,t_size start,t_ssize count) const; 31 | 32 | void presort(); 33 | 34 | private: 35 | bool _findNearestUp( size_t val, size_t & outIdx ) const; 36 | bool _findNearestDown( size_t val, size_t & outIdx ) const; 37 | bool _find( size_t val, size_t & outIdx ) const { 38 | return pfc::bsearch_simple_inline_t( m_content, m_content.get_size(), val, outIdx); 39 | } 40 | 41 | pfc::array_t< size_t, pfc::alloc_fast > m_content; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/bsearch.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | //deprecated 4 | 5 | /* 6 | class NOVTABLE bsearch_callback 7 | { 8 | public: 9 | virtual int test(t_size p_index) const = 0; 10 | }; 11 | */ 12 | 13 | namespace pfc { 14 | 15 | bool bsearch(t_size p_count, bsearch_callback const & p_callback,t_size & p_result) { 16 | return bsearch_inline_t(p_count,p_callback,p_result); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /foobar-sdk/pfc/bsearch_inline.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | 3 | //deprecated 4 | 5 | template 6 | inline bool bsearch_inline_t(t_size p_count, const t_callback & p_callback,t_size & p_result) 7 | { 8 | t_size max = p_count; 9 | t_size min = 0; 10 | t_size ptr; 11 | while(min> 1); 14 | int result = p_callback.test(ptr); 15 | if (result<0) min = ptr + 1; 16 | else if (result>0) max = ptr; 17 | else 18 | { 19 | p_result = ptr; 20 | return true; 21 | } 22 | } 23 | p_result = min; 24 | return false; 25 | } 26 | 27 | template 28 | inline bool bsearch_simple_inline_t(const t_buffer & p_buffer,t_size p_count,t_value const & p_value,t_size & p_result) 29 | { 30 | t_size max = p_count; 31 | t_size min = 0; 32 | t_size ptr; 33 | while(min> 1); 36 | if (p_value > p_buffer[ptr]) min = ptr + 1; 37 | else if (p_value < p_buffer[ptr]) max = ptr; 38 | else 39 | { 40 | p_result = ptr; 41 | return true; 42 | } 43 | } 44 | p_result = min; 45 | return false; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/cpuid.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | 4 | #if PFC_HAVE_CPUID 5 | 6 | namespace pfc { 7 | bool query_cpu_feature_set(unsigned p_value) { 8 | #ifdef _MSC_VER 9 | __try { 10 | #endif 11 | if (p_value & (CPU_HAVE_SSE | CPU_HAVE_SSE2 | CPU_HAVE_SSE3 | CPU_HAVE_SSSE3 | CPU_HAVE_SSE41 | CPU_HAVE_SSE42)) { 12 | int buffer[4]; 13 | __cpuid(buffer,1); 14 | if (p_value & CPU_HAVE_SSE) { 15 | if ((buffer[3]&(1<<25)) == 0) return false; 16 | } 17 | if (p_value & CPU_HAVE_SSE2) { 18 | if ((buffer[3]&(1<<26)) == 0) return false; 19 | } 20 | if (p_value & CPU_HAVE_SSE3) { 21 | if ((buffer[2]&(1<<0)) == 0) return false; 22 | } 23 | if (p_value & CPU_HAVE_SSSE3) { 24 | if ((buffer[2]&(1<<9)) == 0) return false; 25 | } 26 | if (p_value & CPU_HAVE_SSE41) { 27 | if ((buffer[2]&(1<<19)) == 0) return false; 28 | } 29 | if (p_value & CPU_HAVE_SSE42) { 30 | if ((buffer[2]&(1<<20)) == 0) return false; 31 | } 32 | } 33 | #ifdef _M_IX86 34 | if (p_value & (CPU_HAVE_3DNOW_EX | CPU_HAVE_3DNOW)) { 35 | int buffer_amd[4]; 36 | __cpuid(buffer_amd,0x80000000); 37 | if ((unsigned)buffer_amd[0] < 0x80000001) return false; 38 | __cpuid(buffer_amd,0x80000001); 39 | 40 | if (p_value & CPU_HAVE_3DNOW) { 41 | if ((buffer_amd[3]&(1<<31)) == 0) return false; 42 | } 43 | if (p_value & CPU_HAVE_3DNOW_EX) { 44 | if ((buffer_amd[3]&(1<<30)) == 0) return false; 45 | } 46 | } 47 | #endif 48 | return true; 49 | #ifdef _MSC_VER 50 | } __except(1) { 51 | return false; 52 | } 53 | #endif 54 | } 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/cpuid.h: -------------------------------------------------------------------------------- 1 | 2 | // CPUID stuff supported only on MSVC for now, irrelevant for non x86 3 | #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) 4 | #define PFC_HAVE_CPUID 1 5 | namespace pfc { 6 | enum { 7 | CPU_HAVE_3DNOW = 1 << 0, 8 | CPU_HAVE_3DNOW_EX = 1 << 1, 9 | CPU_HAVE_SSE = 1 << 2, 10 | CPU_HAVE_SSE2 = 1 << 3, 11 | CPU_HAVE_SSE3 = 1 << 4, 12 | CPU_HAVE_SSSE3 = 1 << 5, 13 | CPU_HAVE_SSE41 = 1 << 6, 14 | CPU_HAVE_SSE42 = 1 << 7, 15 | }; 16 | 17 | bool query_cpu_feature_set(unsigned p_value); 18 | }; 19 | #endif 20 | 21 | #ifndef PFC_HAVE_CPUID 22 | #define PFC_HAVE_CPUID 0 23 | #endif -------------------------------------------------------------------------------- /foobar-sdk/pfc/event.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | #ifdef _WIN32 3 | 4 | typedef HANDLE eventHandle_t; 5 | 6 | class event : public win32_event { 7 | public: 8 | event() { create(true, false); } 9 | 10 | HANDLE get_handle() const {return win32_event::get();} 11 | }; 12 | #else 13 | 14 | typedef int eventHandle_t; 15 | 16 | typedef nix_event event; 17 | 18 | #endif 19 | } 20 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/filehandle.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | #ifndef _WIN32 4 | #include 5 | #endif 6 | 7 | namespace pfc { 8 | void fileHandleClose( fileHandle_t h ) { 9 | if (h == fileHandleInvalid) return; 10 | #ifdef _WIN32 11 | CloseHandle( h ); 12 | #else 13 | close( h ); 14 | #endif 15 | } 16 | 17 | fileHandle_t fileHandleDup( fileHandle_t h ) { 18 | #ifdef _WIN32 19 | auto proc = GetCurrentProcess(); 20 | HANDLE out; 21 | if (!DuplicateHandle ( proc, h, proc, &out, 0, FALSE, DUPLICATE_SAME_ACCESS )) return fileHandleInvalid; 22 | return out; 23 | #else 24 | return dup( h ); 25 | #endif 26 | } 27 | 28 | void fileHandle::close() { 29 | fileHandleClose( h ); 30 | clear(); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /foobar-sdk/pfc/filehandle.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | #ifdef _WIN32 3 | typedef HANDLE fileHandle_t; 4 | const fileHandle_t fileHandleInvalid = INVALID_HANDLE_VALUE; 5 | #else 6 | typedef int fileHandle_t; 7 | const fileHandle_t fileHandleInvalid = -1; 8 | #endif 9 | 10 | void fileHandleClose( fileHandle_t h ); 11 | fileHandle_t fileHandleDup( fileHandle_t h ); 12 | 13 | class fileHandle { 14 | public: 15 | fileHandle( fileHandle_t val ) : h(val) {} 16 | fileHandle() : h ( fileHandleInvalid ) {} 17 | ~fileHandle() { close(); } 18 | fileHandle( fileHandle && other ) { h = other.h; other.clear(); } 19 | void operator=( fileHandle && other ) { close(); h = other.h; other.clear(); } 20 | void operator=( fileHandle_t other ) { close(); h = other; } 21 | void close(); 22 | void clear() { h = fileHandleInvalid; } 23 | bool isValid() { return h != fileHandleInvalid; } 24 | fileHandle_t h; 25 | private: 26 | fileHandle( const fileHandle & ); 27 | void operator=( const fileHandle & ); 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/guid.h: -------------------------------------------------------------------------------- 1 | #ifndef _PFC_GUID_H_ 2 | #define _PFC_GUID_H_ 3 | 4 | namespace pfc { 5 | 6 | GUID GUID_from_text(const char * text); 7 | 8 | class print_guid 9 | { 10 | public: 11 | print_guid(const GUID & p_guid); 12 | inline operator const char * () const {return m_data;} 13 | inline const char * get_ptr() {return m_data;} 14 | private: 15 | char m_data[64]; 16 | }; 17 | 18 | inline int guid_compare(const GUID & g1,const GUID & g2) {return memcmp(&g1,&g2,sizeof(GUID));} 19 | 20 | inline bool guid_equal(const GUID & g1,const GUID & g2) {return (g1 == g2) ? true : false;} 21 | template<> inline int compare_t(const GUID & p_item1,const GUID & p_item2) {return guid_compare(p_item1,p_item2);} 22 | 23 | extern const GUID guid_null; 24 | 25 | void print_hex_raw(const void * buffer,unsigned bytes,char * p_out); 26 | 27 | inline GUID makeGUID(t_uint32 Data1, t_uint16 Data2, t_uint16 Data3, t_uint8 Data4_1, t_uint8 Data4_2, t_uint8 Data4_3, t_uint8 Data4_4, t_uint8 Data4_5, t_uint8 Data4_6, t_uint8 Data4_7, t_uint8 Data4_8) { 28 | GUID guid = { Data1, Data2, Data3, {Data4_1, Data4_2, Data4_3, Data4_4, Data4_5, Data4_6, Data4_7, Data4_8 } }; 29 | return guid; 30 | } 31 | inline GUID xorGUID(const GUID & v1, const GUID & v2) { 32 | GUID temp; memxor(&temp, &v1, &v2, sizeof(GUID)); return temp; 33 | } 34 | 35 | class format_guid_cpp : public pfc::string_formatter { 36 | public: 37 | format_guid_cpp(const GUID & guid) { 38 | *this << "{0x" << pfc::format_hex(guid.Data1,8) << ", 0x" << pfc::format_hex(guid.Data2, 4) << ", 0x" << pfc::format_hex(guid.Data3,4) << ", {0x" << pfc::format_hex(guid.Data4[0],2); 39 | for(int n = 1; n < 8; ++n) { 40 | *this << ", 0x" << pfc::format_hex(guid.Data4[n],2); 41 | } 42 | *this << "}}"; 43 | } 44 | }; 45 | 46 | GUID createGUID(); 47 | } 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/instance_tracker.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | template 3 | class instance_tracker_server_t { 4 | public: 5 | void add(t_object * p_object) { 6 | m_list.add_item(p_object); 7 | } 8 | void remove(t_object * p_object) { 9 | m_list.remove_item(p_object); 10 | } 11 | 12 | t_size get_count() const {return m_list.get_count();} 13 | t_object * get_item(t_size p_index) {return m_list[p_index];} 14 | t_object * operator[](t_size p_index) {return m_list[p_index];} 15 | 16 | private: 17 | ptr_list_hybrid_t m_list; 18 | }; 19 | 20 | 21 | template & p_server> 22 | class instance_tracker_client_t { 23 | public: 24 | instance_tracker_client_t(t_object* p_ptr) : m_ptr(NULL), m_added(false) {initialize(p_ptr);} 25 | instance_tracker_client_t() : m_ptr(NULL), m_added(false) {} 26 | 27 | void initialize(t_object * p_ptr) { 28 | uninitialize(); 29 | p_server.add(p_ptr); 30 | m_ptr = p_ptr; 31 | m_added = true; 32 | } 33 | 34 | void uninitialize() { 35 | if (m_added) { 36 | p_server.remove(m_ptr); 37 | m_ptr = NULL; 38 | m_added = false; 39 | } 40 | } 41 | 42 | ~instance_tracker_client_t() { 43 | uninitialize(); 44 | } 45 | private: 46 | bool m_added; 47 | t_object * m_ptr; 48 | }; 49 | } -------------------------------------------------------------------------------- /foobar-sdk/pfc/makefile: -------------------------------------------------------------------------------- 1 | CXXFLAGS += -fPIC -std=c++11 2 | SOURCES_CPP = audio_math.cpp audio_sample.cpp base64.cpp bit_array.cpp bsearch.cpp cpuid.cpp filehandle.cpp guid.cpp nix-objects.cpp other.cpp pathUtils.cpp printf.cpp selftest.cpp sort.cpp stdafx.cpp stringNew.cpp string_base.cpp string_conv.cpp synchro_nix.cpp threads.cpp timers.cpp utf8.cpp wildcard.cpp win-objects.cpp 3 | 4 | UNAME_S := $(shell uname -s) 5 | ifeq ($(UNAME_S),Darwin) 6 | SOURCES_OBJC = obj-c.mm 7 | CXXFLAGS += -stdlib=libc++ 8 | endif 9 | 10 | OBJECTS=$(SOURCES_CPP:.cpp=.o) $(SOURCES_OBJC:.mm=.o) 11 | SOURCES=$(SOURCES_CPP) $(SOURCES_OBJC) 12 | OUTPUT=pfc.a 13 | 14 | all: $(SOURCES) $(OUTPUT) 15 | 16 | $(OUTPUT): $(OBJECTS) 17 | ar rcs $(OUTPUT) $(OBJECTS) 18 | 19 | %.o: %.mm 20 | $(CXX) $(CXXFLAGS) $< -c -o $@ 21 | 22 | clean: 23 | rm -f $(OBJECTS) $(OUTPUT) 24 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/mem_block_mgr.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_BLOCK_MGR_H_ 2 | #define _MEM_BLOCK_MGR_H_ 3 | 4 | #error DEPRECATED 5 | 6 | 7 | template 8 | class mem_block_manager 9 | { 10 | struct entry 11 | { 12 | mem_block_t block; 13 | bool used; 14 | }; 15 | ptr_list_t list; 16 | public: 17 | T * copy(const T* ptr,int size) 18 | { 19 | int n; 20 | int found_size = -1,found_index = -1; 21 | for(n=0;nused) 24 | { 25 | int block_size = list[n]->block.get_size(); 26 | if (found_size<0) 27 | { 28 | found_index=n; found_size = block_size; 29 | } 30 | else if (found_sizefound_size) 33 | { 34 | found_index=n; found_size = block_size; 35 | } 36 | } 37 | else if (found_size>size) 38 | { 39 | if (block_size>=size && block_size=0) 49 | { 50 | list[found_index]->used = true; 51 | return list[found_index]->block.copy(ptr,size); 52 | } 53 | entry * new_entry = new entry; 54 | new_entry->used = true; 55 | list.add_item(new_entry); 56 | return new_entry->block.copy(ptr,size); 57 | } 58 | 59 | void mark_as_free() 60 | { 61 | int n; 62 | for(n=0;nused = false; 65 | } 66 | } 67 | 68 | ~mem_block_manager() {list.delete_all();} 69 | }; 70 | 71 | #endif -------------------------------------------------------------------------------- /foobar-sdk/pfc/obj-c.mm: -------------------------------------------------------------------------------- 1 | // 2 | // PFC-ObjC.m 3 | // pfc-test 4 | // 5 | // Created by PEPE on 28/07/14. 6 | // Copyright (c) 2014 PEPE. All rights reserved. 7 | // 8 | #ifdef __APPLE__ 9 | #import 10 | 11 | 12 | #include 13 | 14 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 15 | #import 16 | #endif 17 | 18 | #include "pfc.h" 19 | 20 | 21 | namespace pfc { 22 | void * thread::g_entry(void * arg) { 23 | @autoreleasepool { 24 | reinterpret_cast(arg)->entry(); 25 | } 26 | return NULL; 27 | } 28 | void thread::appleStartThreadPrologue() { 29 | if (![NSThread isMultiThreaded]) [[[NSThread alloc] init] start]; 30 | } 31 | 32 | bool isShiftKeyPressed() { 33 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 34 | return ( [NSEvent modifierFlags] & NSShiftKeyMask ) != 0; 35 | #else 36 | return false; 37 | #endif 38 | } 39 | bool isCtrlKeyPressed() { 40 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 41 | return ( [NSEvent modifierFlags] & NSControlKeyMask ) != 0; 42 | #else 43 | return false; 44 | #endif 45 | } 46 | bool isAltKeyPressed() { 47 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 48 | return ( [NSEvent modifierFlags] & NSAlternateKeyMask ) != 0; 49 | #else 50 | return false; 51 | #endif 52 | } 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/pathUtils.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | namespace io { 3 | namespace path { 4 | #ifdef _WINDOWS 5 | typedef string::comparatorCaseInsensitive comparator; 6 | #else 7 | typedef string::comparatorCaseSensitive comparator; // wild assumption 8 | #endif 9 | 10 | 11 | string getFileName(string path); 12 | string getFileNameWithoutExtension(string path); 13 | string getFileExtension(string path); 14 | string getParent(string filePath); 15 | string getDirectory(string filePath);//same as getParent() 16 | string combine(string basePath,string fileName); 17 | char getDefaultSeparator(); 18 | string getSeparators(); 19 | bool isSeparator(char c); 20 | string getIllegalNameChars(bool allowWC = false); 21 | string replaceIllegalNameChars(string fn, bool allowWC = false); 22 | string replaceIllegalPathChars(string fn); 23 | bool isInsideDirectory(pfc::string directory, pfc::string inside); 24 | bool isDirectoryRoot(string path); 25 | string validateFileName(string name, bool allowWC = false);//removes various illegal things from the name, exact effect depends on the OS, includes removal of the invalid characters 26 | 27 | template inline bool equals(const t1 & v1, const t2 & v2) {return comparator::compare(v1,v2) == 0;} 28 | 29 | template inline int compare( t1 const & p1, t2 const & p2 ) {return comparator::compare(p1, p2); } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/pfc-license.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /foobar-sdk/pfc/pfc-readme.txt: -------------------------------------------------------------------------------- 1 | PFC : Peter's Foundation Classes 2 | 3 | A library of loosely connected classes used by foobar2000 codebase; freely available and reusable for other projects. 4 | 5 | PFC is not state-of-art code. Many parts of it exist only to keep old bits of foobar2000 codebase ( also third party foobar2000 components ) compiling without modification. For an example, certain classes predating 'pfc' namespace use exist outside the namespace. 6 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/pp-gettickcount.h: -------------------------------------------------------------------------------- 1 | #if !defined(PP_GETTICKCOUNT_H_INCLUDED) && defined(_WIN32) 2 | #define PP_GETTICKCOUNT_H_INCLUDED 3 | 4 | namespace PP { 5 | #if _WIN32_WINNT >= 0x600 6 | typedef uint64_t tickcount_t; 7 | inline tickcount_t getTickCount() { return ::GetTickCount64(); } 8 | #else 9 | #define PFC_TICKCOUNT_32BIT 10 | typedef uint32_t tickcount_t; 11 | inline tickcount_t getTickCount() { return ::GetTickCount(); } 12 | #endif 13 | 14 | } 15 | 16 | #endif // #if !defined(PP_GETTICKCOUNT_H_INCLUDED) && defined(_WIN32) -------------------------------------------------------------------------------- /foobar-sdk/pfc/primitives_part2.h: -------------------------------------------------------------------------------- 1 | namespace pfc { 2 | template 3 | static bool guess_reorder_pattern(pfc::array_t & out, const t_list1 & from, const t_list2 & to) { 4 | typedef typename t_list1::t_item t_item; 5 | const t_size count = from.get_size(); 6 | if (count != to.get_size()) return false; 7 | out.set_size(count); 8 | for(t_size walk = 0; walk < count; ++walk) out[walk] = walk; 9 | //required output: to[n] = from[out[n]]; 10 | typedef pfc::chain_list_v2_t t_queue; 11 | pfc::map_t content; 12 | for(t_size walk = 0; walk < count; ++walk) { 13 | content.find_or_add(from[walk]).add_item(walk); 14 | } 15 | for(t_size walk = 0; walk < count; ++walk) { 16 | t_queue * q = content.query_ptr(to[walk]); 17 | if (q == NULL) return false; 18 | if (q->get_count() == 0) return false; 19 | out[walk] = *q->first(); 20 | q->remove(q->first()); 21 | } 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/ptr_list.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFC_PTR_LIST_H_ 2 | #define __PFC_PTR_LIST_H_ 3 | 4 | namespace pfc { 5 | 6 | template > 7 | class ptr_list_t : public B 8 | { 9 | public: 10 | ptr_list_t() {} 11 | ptr_list_t(const ptr_list_t & p_source) {*this = p_source;} 12 | 13 | void free_by_idx(t_size n) {free_mask(bit_array_one(n));} 14 | void free_all() {this->remove_all_ex(free);} 15 | void free_mask(const bit_array & p_mask) {this->remove_mask_ex(p_mask,free);} 16 | 17 | void delete_item(T* ptr) {delete_by_idx(find_item(ptr));} 18 | 19 | void delete_by_idx(t_size p_index) { 20 | delete_mask(bit_array_one(p_index)); 21 | } 22 | 23 | void delete_all() { 24 | this->remove_all_ex(pfc::delete_t); 25 | } 26 | 27 | void delete_mask(const bit_array & p_mask) { 28 | this->remove_mask_ex(p_mask,pfc::delete_t); 29 | } 30 | 31 | T * operator[](t_size n) const {return this->get_item(n);} 32 | }; 33 | 34 | template 35 | class ptr_list_hybrid_t : public ptr_list_t > { 36 | public: 37 | ptr_list_hybrid_t() {} 38 | ptr_list_hybrid_t(const ptr_list_hybrid_t & p_source) {*this = p_source;} 39 | }; 40 | 41 | typedef ptr_list_t ptr_list; 42 | 43 | template class traits_t > : public traits_t {}; 44 | } 45 | 46 | 47 | #endif //__PFC_PTR_LIST_H_ 48 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/selftest.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | 4 | namespace { 5 | class foo {}; 6 | } 7 | 8 | inline pfc::string_base & operator<<(pfc::string_base & p_fmt,foo p_source) {p_fmt.add_string_("FOO"); return p_fmt;} 9 | 10 | namespace { 11 | using namespace pfc; 12 | class thread_selftest : public thread { 13 | public: 14 | void threadProc() { 15 | pfc::event ev; 16 | ev.wait_for(1); 17 | m_event.set_state(true); 18 | ev.wait_for(1); 19 | } 20 | pfc::event m_event; 21 | 22 | void selftest() { 23 | lores_timer timer; timer.start(); 24 | this->start(); 25 | if (!m_event.wait_for(-1)) { 26 | PFC_ASSERT(!"Should not get here"); 27 | return; 28 | } 29 | PFC_ASSERT(fabs(timer.query() - 1.0) < 0.1); 30 | this->waitTillDone(); 31 | PFC_ASSERT(fabs(timer.query() - 2.0) < 0.1); 32 | } 33 | }; 34 | } 35 | 36 | namespace pfc { 37 | 38 | 39 | 40 | // Self test routines that need to be executed to do their payload 41 | void selftest_runtime() { 42 | { 43 | thread_selftest t; t.selftest(); 44 | } 45 | 46 | } 47 | // Self test routines that fail at compile time if there's something seriously wrong 48 | void selftest_static() { 49 | PFC_STATIC_ASSERT(sizeof(t_uint8) == 1); 50 | PFC_STATIC_ASSERT(sizeof(t_uint16) == 2); 51 | PFC_STATIC_ASSERT(sizeof(t_uint32) == 4); 52 | PFC_STATIC_ASSERT(sizeof(t_uint64) == 8); 53 | 54 | PFC_STATIC_ASSERT(sizeof(t_int8) == 1); 55 | PFC_STATIC_ASSERT(sizeof(t_int16) == 2); 56 | PFC_STATIC_ASSERT(sizeof(t_int32) == 4); 57 | PFC_STATIC_ASSERT(sizeof(t_int64) == 8); 58 | 59 | PFC_STATIC_ASSERT(sizeof(t_float32) == 4); 60 | PFC_STATIC_ASSERT(sizeof(t_float64) == 8); 61 | 62 | PFC_STATIC_ASSERT(sizeof(t_size) == sizeof(void*)); 63 | PFC_STATIC_ASSERT(sizeof(t_ssize) == sizeof(void*)); 64 | 65 | PFC_STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); 66 | 67 | PFC_STATIC_ASSERT(sizeof(GUID) == 16); 68 | 69 | typedef pfc::avltree_t t_asdf; 70 | t_asdf asdf; asdf.add_item(1); 71 | t_asdf::iterator iter = asdf._first_var(); 72 | t_asdf::const_iterator iter2 = asdf._first_var(); 73 | 74 | PFC_string_formatter() << "foo" << 1337 << foo(); 75 | 76 | pfc::list_t l; l.add_item(3); 77 | } 78 | 79 | void selftest() { 80 | selftest_static(); selftest_runtime(); 81 | 82 | debugLog out; out << "PFC selftest OK"; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/stdafx.cpp: -------------------------------------------------------------------------------- 1 | //cpp used to generate precompiled header 2 | #include "pfc.h" -------------------------------------------------------------------------------- /foobar-sdk/pfc/stringNew.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | namespace pfc { 4 | 5 | t_size string::indexOf(char c,t_size base) const { 6 | return pfc::string_find_first(ptr(),c,base); 7 | } 8 | t_size string::lastIndexOf(char c,t_size base) const { 9 | return pfc::string_find_last(ptr(),c,base); 10 | } 11 | t_size string::indexOf(stringp s,t_size base) const { 12 | return pfc::string_find_first(ptr(),s.ptr(),base); 13 | } 14 | t_size string::lastIndexOf(stringp s,t_size base) const { 15 | return pfc::string_find_last(ptr(),s.ptr(),base); 16 | } 17 | t_size string::indexOfAnyChar(stringp _s,t_size base) const { 18 | string s ( _s ); 19 | const t_size len = length(); 20 | const char* content = ptr(); 21 | for(t_size walk = 0; walk < len; ++walk) { 22 | if (s.contains(content[walk])) return walk; 23 | } 24 | return ~0; 25 | } 26 | t_size string::lastIndexOfAnyChar(stringp _s,t_size base) const { 27 | string s ( _s ); 28 | const char* content = ptr(); 29 | for(t_size _walk = length(); _walk > 0; --_walk) { 30 | const t_size walk = _walk-1; 31 | if (s.contains(content[walk])) return walk; 32 | } 33 | return ~0; 34 | } 35 | bool string::startsWith(char c) const { 36 | return (*this)[0] == c; 37 | } 38 | bool string::startsWith(string s) const { 39 | const char * walk = ptr(); 40 | const char * subWalk = s.ptr(); 41 | for(;;) { 42 | if (*subWalk == 0) return true; 43 | if (*walk != *subWalk) return false; 44 | walk++; subWalk++; 45 | } 46 | } 47 | bool string::endsWith(char c) const { 48 | const t_size len = length(); 49 | if (len == 0) return false; 50 | return ptr()[len-1] == c; 51 | } 52 | bool string::endsWith(string s) const { 53 | const t_size len = length(), subLen = s.length(); 54 | if (subLen > len) return false; 55 | return subString(len - subLen) == s; 56 | } 57 | 58 | char string::firstChar() const { 59 | return (*this)[0]; 60 | } 61 | char string::lastChar() const { 62 | const t_size len = length(); 63 | return len > 0 ? (*this)[len-1] : (char)0; 64 | } 65 | 66 | string string::replace(stringp strOld, stringp strNew) const { 67 | t_size walk = 0; 68 | string ret; 69 | for(;;) { 70 | t_size next = indexOf(strOld, walk); 71 | if (next == ~0) { 72 | ret += subString(walk); break; 73 | } 74 | ret += subString(walk,next-walk) + strNew; 75 | walk = next + strOld.length(); 76 | } 77 | return ret; 78 | } 79 | bool string::contains(char c) const {return indexOf(c) != ~0;} 80 | bool string::contains(stringp s) const {return indexOf(s) != ~0;} 81 | bool string::containsAnyChar(stringp s) const {return indexOfAnyChar(s) != ~0;} 82 | } 83 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/string_list.h: -------------------------------------------------------------------------------- 1 | #ifndef _PFC_STRING_LIST_H_ 2 | #define _PFC_STRING_LIST_H_ 3 | 4 | namespace pfc { 5 | 6 | typedef list_base_const_t string_list_const; 7 | 8 | class string_list_impl : public string_list_const 9 | { 10 | public: 11 | t_size get_count() const {return m_data.get_size();} 12 | void get_item_ex(const char* & p_out, t_size n) const {p_out = m_data[n];} 13 | 14 | const char * operator[] (t_size n) const {return m_data[n];} 15 | void add_item(const char * p_string) {pfc::append_t(m_data, p_string);} 16 | 17 | template void add_items(const t_what & p_source) {_append(p_source);} 18 | 19 | void remove_all() {m_data.set_size(0);} 20 | 21 | string_list_impl() {} 22 | template string_list_impl(const t_what & p_source) {_copy(p_source);} 23 | template string_list_impl & operator=(const t_what & p_source) {_copy(p_source); return *this;} 24 | template string_list_impl & operator|=(const string_list_impl & p_source) {_append(p_source); return *this;} 25 | template string_list_impl & operator+=(const t_what & p_source) {pfc::append_t(m_data, p_source); return *this;} 26 | 27 | private: 28 | template void _append(const t_what & p_source) { 29 | const t_size toadd = p_source.get_size(), base = m_data.get_size(); 30 | m_data.set_size(base+toadd); 31 | for(t_size n=0;n void _copy(const t_what & p_source) { 35 | const t_size newcount = p_source.get_size(); 36 | m_data.set_size(newcount); 37 | for(t_size n=0;n m_data; 41 | }; 42 | } 43 | 44 | #endif //_PFC_STRING_LIST_H_ 45 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/synchro_nix.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | #ifndef _WIN32 4 | 5 | namespace pfc { 6 | 7 | void mutexBase::create( const pthread_mutexattr_t * attr ) { 8 | if (pthread_mutex_init( &obj, attr) != 0) { 9 | throw exception_bug_check(); 10 | } 11 | } 12 | void mutexBase::destroy() { 13 | pthread_mutex_destroy( &obj ); 14 | } 15 | void mutexBase::createRecur() { 16 | mutexAttr a; a.setRecursive(); create(&a.attr); 17 | } 18 | void mutexBase::create( const mutexAttr & a ) { 19 | create( & a.attr ); 20 | } 21 | 22 | void readWriteLockBase::create( const pthread_rwlockattr_t * attr ) { 23 | if (pthread_rwlock_init( &obj, attr) != 0) { 24 | throw exception_bug_check(); 25 | } 26 | } 27 | void readWriteLockBase::create( const readWriteLockAttr & a) { 28 | create(&a.attr); 29 | } 30 | 31 | } 32 | 33 | #endif // _WIN32 34 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/threads.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #else 4 | #include 5 | #endif 6 | namespace pfc { 7 | t_size getOptimalWorkerThreadCount(); 8 | t_size getOptimalWorkerThreadCountEx(t_size taskCountLimit); 9 | 10 | //! IMPORTANT: all classes derived from thread must call waitTillDone() in their destructor, to avoid object destruction during a virtual function call! 11 | class thread { 12 | public: 13 | PFC_DECLARE_EXCEPTION(exception_creation, exception, "Could not create thread"); 14 | thread(); 15 | ~thread() {PFC_ASSERT(!isActive()); waitTillDone();} 16 | void startWithPriority(int priority); 17 | void setPriority(int priority); 18 | int getPriority(); 19 | void start(); 20 | bool isActive() const; 21 | void waitTillDone() {close();} 22 | static int currentPriority(); 23 | #ifdef _WIN32 24 | void winStart(int priority, DWORD * outThreadID); 25 | HANDLE winThreadHandle() { return m_thread; } 26 | #else 27 | pthread_t posixThreadHandle() { return m_thread; } 28 | #endif 29 | protected: 30 | virtual void threadProc() {PFC_ASSERT(!"Stub thread entry - should not get here");} 31 | private: 32 | void close(); 33 | #ifdef _WIN32 34 | static unsigned CALLBACK g_entry(void* p_instance); 35 | #else 36 | static void * g_entry( void * arg ); 37 | #endif 38 | void entry(); 39 | 40 | #ifdef _WIN32 41 | HANDLE m_thread; 42 | #else 43 | pthread_t m_thread; 44 | bool m_threadValid; // there is no invalid pthread_t, so we keep a separate 'valid' flag 45 | #endif 46 | 47 | #ifdef __APPLE__ 48 | static void appleStartThreadPrologue(); 49 | #endif 50 | PFC_CLASS_NOT_COPYABLE_EX(thread) 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/timers.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | namespace pfc { 4 | 5 | #ifdef PFC_HAVE_PROFILER 6 | 7 | profiler_static::profiler_static(const char * p_name) 8 | { 9 | name = p_name; 10 | total_time = 0; 11 | num_called = 0; 12 | } 13 | 14 | profiler_static::~profiler_static() 15 | { 16 | try { 17 | pfc::string_fixed_t<511> message; 18 | message << "profiler: " << pfc::format_pad_left >(48,' ',name) << " - " << 19 | pfc::format_pad_right >(16,' ',pfc::format_uint(total_time) ) << " cycles"; 20 | 21 | if (num_called > 0) { 22 | message << " (executed " << num_called << " times, " << (total_time / num_called) << " average)"; 23 | } 24 | message << "\n"; 25 | OutputDebugStringA(message); 26 | } catch(...) { 27 | //should never happen 28 | OutputDebugString(_T("unexpected profiler failure\n")); 29 | } 30 | } 31 | #endif 32 | 33 | #ifndef _WIN32 34 | 35 | void hires_timer::start() { 36 | m_start = nixGetTime(); 37 | } 38 | double hires_timer::query() const { 39 | return nixGetTime() - m_start; 40 | } 41 | double hires_timer::query_reset() { 42 | double t = nixGetTime(); 43 | double r = t - m_start; 44 | m_start = t; 45 | return r; 46 | } 47 | pfc::string8 hires_timer::queryString(unsigned precision) { 48 | return format_time_ex( query(), precision ).get_ptr(); 49 | } 50 | #endif 51 | 52 | 53 | uint64_t fileTimeWtoU(uint64_t ft) { 54 | return (ft - 116444736000000000 + /*rounding*/10000000/2) / 10000000; 55 | } 56 | uint64_t fileTimeUtoW(uint64_t ft) { 57 | return (ft * 10000000) + 116444736000000000; 58 | } 59 | #ifndef _WIN32 60 | uint64_t fileTimeUtoW(const timespec & ts) { 61 | uint64_t ft = (uint64_t)ts.tv_sec * 10000000 + (uint64_t)ts.tv_nsec / 100; 62 | return ft + 116444736000000000; 63 | } 64 | #endif 65 | 66 | uint64_t fileTimeNow() { 67 | #ifdef _WIN32 68 | uint64_t ret; 69 | GetSystemTimeAsFileTime((FILETIME*)&ret); 70 | return ret; 71 | #else 72 | return fileTimeUtoW(time(NULL)); 73 | #endif 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/wildcard.cpp: -------------------------------------------------------------------------------- 1 | #include "pfc.h" 2 | 3 | static bool test_recur(const char * fn,const char * rm,bool b_sep) 4 | { 5 | for(;;) 6 | { 7 | if ((b_sep && *rm==';') || *rm==0) return *fn==0; 8 | else if (*rm=='*') 9 | { 10 | rm++; 11 | do 12 | { 13 | if (test_recur(fn,rm,b_sep)) return true; 14 | } while(pfc::utf8_advance(fn)); 15 | return false; 16 | } 17 | else if (*fn==0) return false; 18 | else if (*rm!='?' && pfc::charLower(pfc::utf8_get_char(fn))!=pfc::charLower(pfc::utf8_get_char(rm))) return false; 19 | 20 | fn = pfc::utf8_char_next(fn); rm = pfc::utf8_char_next(rm); 21 | } 22 | } 23 | 24 | bool wildcard_helper::test_path(const char * path,const char * pattern,bool b_sep) {return test(path + pfc::scan_filename(path),pattern,b_sep);} 25 | 26 | bool wildcard_helper::test(const char * fn,const char * pattern,bool b_sep) 27 | { 28 | if (!b_sep) return test_recur(fn,pattern,false); 29 | const char * rm=pattern; 30 | while(*rm) 31 | { 32 | if (test_recur(fn,rm,true)) return true; 33 | while(*rm && *rm!=';') rm++; 34 | if (*rm==';') 35 | { 36 | while(*rm==';') rm++; 37 | while(*rm==' ') rm++; 38 | } 39 | }; 40 | 41 | return false; 42 | } 43 | 44 | bool wildcard_helper::has_wildcards(const char * str) {return strchr(str,'*') || strchr(str,'?');} 45 | 46 | const char * wildcard_helper::get_wildcard_list() {return "*?";} 47 | 48 | bool wildcard_helper::is_wildcard(char c) { 49 | return c == '*' || c == '?'; 50 | } 51 | -------------------------------------------------------------------------------- /foobar-sdk/pfc/wildcard.h: -------------------------------------------------------------------------------- 1 | namespace wildcard_helper 2 | { 3 | bool test_path(const char * path,const char * pattern,bool b_separate_by_semicolon = false);//will extract filename from path first 4 | bool test(const char * str,const char * pattern,bool b_separate_by_semicolon = false);//tests if str matches pattern 5 | bool has_wildcards(const char * str); 6 | const char * get_wildcard_list(); 7 | bool is_wildcard(char c); 8 | }; 9 | -------------------------------------------------------------------------------- /foobar-sdk/sdk-license.txt: -------------------------------------------------------------------------------- 1 | foobar2000 1.3 SDK 2 | Copyright (c) 2001-2015, Peter Pawlowski 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation or other materials provided with the distribution. 10 | 11 | Usage restrictions: 12 | It is illegal to use this SDK as a part of foobar2000 components that operate outside of legally documented programming interfaces (APIs), such as using window procedure hooks to modify user interface behaviors. We believe components doing so to be harmful to our userbase by introducing compatibility issues and dependencies on undocumented behaviors of our code that may change at any time without any notice or an update to the SDK which would reflect the change. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 AUTHORS 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. 15 | 16 | 17 | 18 | Note that a separate less restrictive license applies to the included 'pfc' library. See pfc-license.txt for details. 19 | -------------------------------------------------------------------------------- /libspotify/LICENSE: -------------------------------------------------------------------------------- 1 | For the current terms and conditions, please read: 2 | 3 | http://developer.spotify.com/en/libspotify/terms-of-use/ 4 | -------------------------------------------------------------------------------- /libspotify/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/libspotify/README -------------------------------------------------------------------------------- /libspotify/docs/images/spotify-core-logo-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/libspotify/docs/images/spotify-core-logo-128x128.png -------------------------------------------------------------------------------- /libspotify/docs/images/spotify-core.txt: -------------------------------------------------------------------------------- 1 | Uses SPOTIFY(R) CORE 2 | -------------------------------------------------------------------------------- /libspotify/examples/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES=jukebox spshell localfiles 2 | 3 | .PHONY: all clean 4 | 5 | ifdef LIBSPOTIFY_PATH 6 | ARG=LIBSPOTIFY_PATH="$(shell cd "$(LIBSPOTIFY_PATH)" && pwd)" 7 | endif 8 | 9 | all clean: 10 | for a in $(EXAMPLES); do $(MAKE) -C $$a $(ARG) $@; done 11 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/Randomify-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.spotify.randomify 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/RandomifyAppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | * 22 | * 23 | * This example application show how to use libspotify in a Mac OS X 24 | * application, playing randomly from your Starred playlist. 25 | * 26 | * This file is part of the libspotify examples suite. 27 | */ 28 | 29 | #import 30 | #import "SpotifySession.h" 31 | 32 | @interface RandomifyAppDelegate : NSObject 33 | 34 | { 35 | IBOutlet NSWindow *window; 36 | IBOutlet NSTextField *username; 37 | IBOutlet NSTextField *password; 38 | IBOutlet NSTextField *log; 39 | IBOutlet NSTextField *status; 40 | 41 | SpotifySession *session; 42 | SpotifyPlaylist *starred; 43 | BOOL playing; 44 | IBOutlet NSButton *playButton; 45 | 46 | SpotifyTrack *playingTrack; 47 | } 48 | -(IBAction)loginAndPlay:(id)sender; 49 | 50 | -(IBAction)playARandomSong:(id)sender; 51 | -(IBAction)togglePlay:(id)sender; 52 | @end 53 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/Randomify_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Randomify' target in the 'Randomify' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/SpotifyPlaylist.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * This file is part of the libspotify examples suite. 4 | * See RandomifyAppDelegate.h for license. 5 | */ 6 | 7 | #import 8 | #import 9 | #import "SpotifyTrack.h" 10 | 11 | @class SpotifyPlaylist; 12 | @protocol SpotifyPlaylistDelegate 13 | @optional 14 | -(void)playlistBeganUpdating:(SpotifyPlaylist*)playlist; 15 | -(void)playlistEndedUpdating:(SpotifyPlaylist*)playlist; 16 | -(void)playlistChangedState:(SpotifyPlaylist*)playlist; 17 | @end 18 | 19 | 20 | @interface SpotifyPlaylist : NSObject { 21 | sp_playlist *playlist; 22 | sp_playlist_callbacks callbacks; 23 | sp_session *session; 24 | NSObject *delegate; 25 | } 26 | -(id)initWithPlaylist:(sp_playlist*)playlist_ onSession:(sp_session*)sess; 27 | @property (assign) NSObject *delegate; 28 | @property (readonly) BOOL loaded; // listen to playlistEndedUpdating if false 29 | 30 | -(NSUInteger)countOfTracks; 31 | -(SpotifyTrack*)objectInTracksAtIndex:(NSUInteger)index; 32 | @end 33 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/SpotifyPlaylist.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * This file is part of the libspotify examples suite. 4 | * See RandomifyAppDelegate.h for license. 5 | */ 6 | 7 | #import "SpotifyPlaylist.h" 8 | #import "SpotifyTrack.h" 9 | 10 | #define plobj ((SpotifyPlaylist*)userdata) 11 | 12 | static void playlist_update_in_progress(sp_playlist *pl, bool done, void *userdata) 13 | { 14 | if(!done) { 15 | if([plobj.delegate respondsToSelector:@selector(playlistBeganUpdating:)]) 16 | [plobj.delegate playlistBeganUpdating:plobj]; 17 | } else { 18 | if([plobj.delegate respondsToSelector:@selector(playlistEndedUpdating:)]) 19 | [plobj.delegate playlistEndedUpdating:plobj]; 20 | } 21 | } 22 | static void playlist_state_changed(sp_playlist *pl, void *userdata) 23 | { 24 | if([plobj.delegate respondsToSelector:@selector(playlistChangedState:)]) 25 | [plobj.delegate playlistChangedState:plobj]; 26 | } 27 | 28 | // TODO: Instead of exposing playlist content changes as delegate methods, 29 | // make tracks KVO-compliant 30 | 31 | @implementation SpotifyPlaylist 32 | @synthesize delegate; 33 | -(id)initWithPlaylist:(sp_playlist*)playlist_ onSession:(sp_session*)sess; 34 | { 35 | playlist = playlist_; 36 | 37 | session = sess; 38 | 39 | callbacks = (sp_playlist_callbacks) { 40 | .playlist_update_in_progress = playlist_update_in_progress, 41 | }; 42 | 43 | sp_playlist_add_ref(playlist); 44 | sp_playlist_add_callbacks(playlist, &callbacks, self); 45 | 46 | 47 | return self; 48 | } 49 | -(void)dealloc; 50 | { 51 | sp_playlist_remove_callbacks(playlist, &callbacks, self); 52 | sp_playlist_release(playlist); 53 | [super dealloc]; 54 | } 55 | 56 | -(BOOL)loaded; 57 | { 58 | return sp_playlist_is_loaded(playlist); 59 | } 60 | -(NSUInteger)countOfTracks; 61 | { 62 | return sp_playlist_num_tracks(playlist); 63 | } 64 | -(SpotifyTrack*)objectInTracksAtIndex:(NSUInteger)index; 65 | { 66 | return [[[SpotifyTrack alloc] initWithTrack:sp_playlist_track(playlist, index) onSession:session] autorelease]; 67 | } 68 | @end 69 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/SpotifySession.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * This file is part of the libspotify examples suite. 4 | * See RandomifyAppDelegate.h for license. 5 | */ 6 | 7 | #import 8 | #import 9 | #import "audio.h" 10 | #import "SpotifyPlaylist.h" 11 | 12 | @class SpotifySession; 13 | @protocol SpotifySessionDelegate 14 | @optional 15 | -(void)sessionLoggedIn:(SpotifySession*)session error:(NSError*)err; 16 | -(void)sessionLoggedOut:(SpotifySession*)session; 17 | -(void)sessionUpdatedMetadata:(SpotifySession*)session; 18 | -(void)session:(SpotifySession*)session connectionError:(NSError*)error; 19 | -(void)session:(SpotifySession*)session hasMessageToUser:(NSString*)message; 20 | -(void)sessionLostPlayToken:(SpotifySession*)session; 21 | -(void)session:(SpotifySession*)session logged:(NSString*)logmsg; 22 | -(void)sessionEndedPlayingTrack:(SpotifySession*)session; 23 | -(void)session:(SpotifySession*)session streamingError:(NSError*)error; 24 | -(void)sessionUpdatedUserinfo:(SpotifySession*)session; 25 | @end 26 | 27 | 28 | @interface SpotifySession : NSObject { 29 | sp_session_config config; 30 | sp_session_callbacks callbacks; 31 | NSString *cachesDir, *supportDir; 32 | audio_fifo_t audiofifo; 33 | sp_session *session; 34 | NSObject *delegate; 35 | } 36 | @property (assign) NSObject *delegate; 37 | -(id)initError:(NSError**)err; 38 | -(void)loginUser:(NSString*)user password:(NSString*)passwd; 39 | -(void)logout; 40 | 41 | @property (readonly) SpotifyPlaylist *starred; 42 | 43 | // Should be its own class: SpotifyPlayer 44 | -(void)loadTrack:(SpotifyTrack*)track; 45 | -(void)pause; 46 | -(void)play; 47 | 48 | 49 | // Stops processing events. If you only release this object, 50 | // the runtime will still own it. 51 | -(void)shutdown; 52 | @end 53 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/SpotifyTrack.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * This file is part of the libspotify examples suite. 4 | * See RandomifyAppDelegate.h for license. 5 | */ 6 | 7 | #import 8 | #import 9 | 10 | @interface SpotifyTrack : NSObject { 11 | sp_track *track; 12 | sp_session *session; 13 | } 14 | -(id)initWithTrack:(sp_track*)track_ onSession:(sp_session*)sess; 15 | 16 | @property (readonly) NSString *name; 17 | @property (readonly) NSString *artistName; 18 | @property (readonly) BOOL loaded; 19 | @property (readonly) BOOL available; 20 | 21 | // Private 22 | @property (readonly) sp_track *track; 23 | @end 24 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/SpotifyTrack.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * This file is part of the libspotify examples suite. 4 | * See RandomifyAppDelegate.h for license. 5 | */ 6 | 7 | #import "SpotifyTrack.h" 8 | 9 | 10 | @implementation SpotifyTrack 11 | @synthesize track; 12 | -(id)initWithTrack:(sp_track*)track_ onSession:(sp_session*)sess; 13 | { 14 | track = track_; 15 | session = sess; 16 | sp_track_add_ref(track); 17 | return self; 18 | } 19 | -(void)dealloc; 20 | { 21 | sp_track_release(track); 22 | [super dealloc]; 23 | } 24 | 25 | -(NSString*)name; 26 | { 27 | const char *name = sp_track_name(track); 28 | if(!name || !sp_track_is_loaded(track)) return @"[loading]"; 29 | return [NSString stringWithUTF8String:sp_track_name(track)]; 30 | } 31 | -(NSString*)artistName; 32 | { 33 | sp_artist *artist = sp_track_artist(track, 0); 34 | const char *artistName = artist ? sp_artist_name(artist) : "[loading]"; 35 | return [NSString stringWithUTF8String:artistName]; 36 | } 37 | -(BOOL)loaded; 38 | { 39 | return sp_track_is_loaded(track); 40 | } 41 | -(BOOL)available; 42 | { 43 | return sp_track_get_availability(session, track) == SP_TRACK_AVAILABILITY_AVAILABLE; 44 | } 45 | 46 | -(NSString*)description; 47 | { 48 | return [NSString stringWithFormat:@"<%@ by %@>", 49 | self.name, 50 | self.artistName 51 | ]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /libspotify/examples/Randomify/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Randomify 4 | // 5 | // Created by Joachim Bengtsson on 2010-03-30. 6 | // Copyright 2010 Spotify. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /libspotify/examples/appkey.c: -------------------------------------------------------------------------------- 1 | #error 2 | #error "You need to replace this file with a libspotify API key provided by Spotify. Please see https://developer.spotify.com/en/libspotify/application-key/" 3 | #error 4 | -------------------------------------------------------------------------------- /libspotify/examples/common.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Spotify Ltd 2 | 3 | all: check-libspotify $(TARGET) 4 | 5 | # 6 | # Direct path to libspotify 7 | # 8 | ifdef LIBSPOTIFY_PATH 9 | 10 | P=$(shell cd "$(LIBSPOTIFY_PATH)" && pwd) 11 | 12 | check-libspotify: 13 | @test -f $(P)/lib/libspotify.so || (echo "Failed to find libspotify.so in $(P)/lib" >&2 ; exit 1) 14 | @test -f $(P)/include/libspotify/api.h || (echo "Failed to find libspotify/api.h in $(P)/include" >&2 ; exit 1) 15 | 16 | CFLAGS += -I$(P)/include 17 | LDFLAGS += -Wl,-rpath,$(P)/lib -L$(P)/lib 18 | LDLIBS += -lspotify 19 | 20 | ifeq ($(shell uname),Darwin) 21 | CPUARCH ?= $(shell uname -m) 22 | CFLAGS += -D__APPLE__ -arch $(CPUARCH) 23 | LDFLAGS += -arch $(CPUARCH) 24 | endif 25 | 26 | # 27 | # Use pkg-config(1) 28 | # 29 | else 30 | 31 | check-libspotify: 32 | @pkg-config --exists libspotify || (echo "Failed to find libspotify using pkg-config(1)" >&2 ; exit 1) 33 | 34 | CFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags libspotify) 35 | LDFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs-only-L libspotify) 36 | LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs-only-l --libs-only-other libspotify) 37 | 38 | endif 39 | 40 | ifdef DEBUG 41 | CFLAGS += -g3 -O0 42 | endif 43 | 44 | CFLAGS += -Wall 45 | 46 | .PHONY: all check-libspotify clean 47 | 48 | vpath %.c ../ 49 | 50 | clean: 51 | rm -f *.o *~ $(TARGET) 52 | -------------------------------------------------------------------------------- /libspotify/examples/jukebox/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(shell uname),Darwin) 2 | ifdef USE_AUDIOQUEUE 3 | AUDIO_DRIVER ?= osx 4 | LDFLAGS += -framework AudioToolbox 5 | else 6 | AUDIO_DRIVER ?= openal 7 | LDFLAGS += -framework OpenAL 8 | endif 9 | else 10 | CFLAGS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags alsa) 11 | LDFLAGS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs-only-L alsa) 12 | LDLIBS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs-only-l --libs-only-other alsa) 13 | AUDIO_DRIVER ?= alsa 14 | endif 15 | 16 | TARGET = jukebox 17 | ## TARGET = playtrack 18 | OBJS = $(TARGET).o appkey.o $(AUDIO_DRIVER)-audio.o audio.o 19 | 20 | $(TARGET): $(OBJS) 21 | $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) 22 | ifdef DEBUG 23 | ifeq ($(shell uname),Darwin) 24 | install_name_tool -change @loader_path/../Frameworks/libspotify.framework/libspotify @rpath/libspotify.so $@ 25 | endif 26 | endif 27 | 28 | include ../common.mk 29 | 30 | 31 | 32 | audio.o: audio.c audio.h 33 | alsa-audio.o: alsa-audio.c audio.h 34 | dummy-audio.o: dummy-audio.c audio.h 35 | osx-audio.o: osx-audio.c audio.h 36 | openal-audio.o: openal-audio.c audio.h 37 | jukebox.o: jukebox.c audio.h 38 | playtrack.o: playtrack.c audio.h 39 | -------------------------------------------------------------------------------- /libspotify/examples/jukebox/audio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Spotify Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | * 22 | * 23 | * Audio helper functions. 24 | * 25 | * This file is part of the libspotify examples suite. 26 | */ 27 | 28 | #include "audio.h" 29 | #include 30 | 31 | audio_fifo_data_t* audio_get(audio_fifo_t *af) 32 | { 33 | audio_fifo_data_t *afd; 34 | pthread_mutex_lock(&af->mutex); 35 | 36 | while (!(afd = TAILQ_FIRST(&af->q))) 37 | pthread_cond_wait(&af->cond, &af->mutex); 38 | 39 | TAILQ_REMOVE(&af->q, afd, link); 40 | af->qlen -= afd->nsamples; 41 | 42 | pthread_mutex_unlock(&af->mutex); 43 | return afd; 44 | } 45 | 46 | void audio_fifo_flush(audio_fifo_t *af) 47 | { 48 | audio_fifo_data_t *afd; 49 | 50 | 51 | pthread_mutex_lock(&af->mutex); 52 | 53 | while((afd = TAILQ_FIRST(&af->q))) { 54 | TAILQ_REMOVE(&af->q, afd, link); 55 | free(afd); 56 | } 57 | 58 | af->qlen = 0; 59 | pthread_mutex_unlock(&af->mutex); 60 | } 61 | -------------------------------------------------------------------------------- /libspotify/examples/jukebox/audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2009 Spotify Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | * 22 | * 23 | * Audio output driver. 24 | * 25 | * This file is part of the libspotify examples suite. 26 | */ 27 | #ifndef _JUKEBOX_AUDIO_H_ 28 | #define _JUKEBOX_AUDIO_H_ 29 | 30 | #include 31 | #include 32 | #include "queue.h" 33 | 34 | 35 | /* --- Types --- */ 36 | typedef struct audio_fifo_data { 37 | TAILQ_ENTRY(audio_fifo_data) link; 38 | int channels; 39 | int rate; 40 | int nsamples; 41 | int16_t samples[0]; 42 | } audio_fifo_data_t; 43 | 44 | typedef struct audio_fifo { 45 | TAILQ_HEAD(, audio_fifo_data) q; 46 | int qlen; 47 | pthread_mutex_t mutex; 48 | pthread_cond_t cond; 49 | } audio_fifo_t; 50 | 51 | 52 | /* --- Functions --- */ 53 | extern void audio_init(audio_fifo_t *af); 54 | extern void audio_fifo_flush(audio_fifo_t *af); 55 | audio_fifo_data_t* audio_get(audio_fifo_t *af); 56 | 57 | #endif /* _JUKEBOX_AUDIO_H_ */ 58 | -------------------------------------------------------------------------------- /libspotify/examples/jukebox/dummy-audio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2009 Spotify Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | * 22 | * 23 | * ALSA audio output driver. 24 | * 25 | * This file is part of the libspotify examples suite. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "audio.h" 37 | 38 | static void* alsa_audio_start(void *aux) 39 | { 40 | audio_fifo_t *af = aux; 41 | 42 | while(1) 43 | free(audio_get(af)); 44 | return NULL; 45 | } 46 | 47 | void audio_init(audio_fifo_t *af) 48 | { 49 | pthread_t tid; 50 | 51 | TAILQ_INIT(&af->q); 52 | af->qlen = 0; 53 | 54 | pthread_mutex_init(&af->mutex, NULL); 55 | pthread_cond_init(&af->cond, NULL); 56 | 57 | pthread_create(&tid, NULL, alsa_audio_start, af); 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /libspotify/examples/localfiles/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=posix_stu 2 | CFLAGs += -Werror 3 | 4 | include ../common.mk 5 | 6 | $(TARGET): main.o appkey.o 7 | $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) 8 | 9 | ifdef DEBUG 10 | ifeq ($(shell uname),Darwin) 11 | install_name_tool -change @loader_path/../Frameworks/libspotify.framework/libspotify @rpath/libspotify.so $@ 12 | endif 13 | endif 14 | -------------------------------------------------------------------------------- /libspotify/examples/localfiles/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | #include 4 | #endif 5 | -------------------------------------------------------------------------------- /libspotify/examples/spshell/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=spshell 2 | LDLIBS += -lreadline 3 | 4 | 5 | ifdef SP_LIBSPOTIFY_WITH_SCROBBLING 6 | CFLAGS += -DSP_LIBSPOTIFY_WITH_SCROBBLING=1 7 | OBJS += scrobbling.o 8 | endif 9 | 10 | include ../common.mk 11 | 12 | OBJS += spshell.o spshell_posix.o appkey.o cmd.o browse.o search.o toplist.o inbox.o star.o playlist.o test.o 13 | 14 | 15 | 16 | $(TARGET): $(OBJS) 17 | $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ 18 | ifdef DEBUG 19 | ifeq ($(shell uname),Darwin) 20 | install_name_tool -change @loader_path/../Frameworks/libspotify.framework/libspotify @rpath/libspotify.so $@ 21 | endif 22 | endif 23 | -------------------------------------------------------------------------------- /libspotify/examples/spshell/spshell.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2006-2010 Spotify Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | * 22 | */ 23 | 24 | #ifndef SPSHELL_H__ 25 | #define SPSHELL_H__ 26 | 27 | #include 28 | #ifndef WIN32 29 | #include 30 | #endif 31 | #include 32 | #include 33 | 34 | #define WITH_TEST_COMMAND 1 35 | 36 | #if WIN32 37 | #include 38 | #define snprintf sprintf_s 39 | #define strcasecmp lstrcmp 40 | #endif 41 | 42 | #ifndef PRIx64 43 | #define PRIx64 "llx" 44 | #endif 45 | 46 | #if USE_STRCMP 47 | #define strcasecmp strcmp 48 | #endif 49 | 50 | extern sp_session *g_session; 51 | 52 | extern void (*metadata_updated_fn)(void); 53 | 54 | extern int spshell_init(const char *username, const char *password, const char *blob, int selftest); 55 | 56 | extern void SP_CALLCONV notify_main_thread(sp_session *session); 57 | 58 | extern void start_prompt(void); 59 | 60 | extern sp_uint64 get_ts(void); 61 | 62 | #if WITH_TEST_COMMAND 63 | 64 | extern void test_finished(void); 65 | 66 | extern void test_process(void); 67 | 68 | extern void SP_CALLCONV end_of_track(sp_session *s); 69 | 70 | extern int SP_CALLCONV music_delivery(sp_session *s, const sp_audioformat *fmt, const void *frames, int num_frames); 71 | 72 | extern void SP_CALLCONV play_token_lost(sp_session *s); 73 | 74 | #endif 75 | 76 | #endif // SPSHELL_H__ 77 | -------------------------------------------------------------------------------- /libspotify/examples/spshell/win32/spshell.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hpp;hxx;hm;inl;inc;xsd 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx 11 | 12 | 13 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 14 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | -------------------------------------------------------------------------------- /libspotify/examples/stub/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=posix_stu 2 | CFLAGs += -Werror 3 | 4 | include ../common.mk 5 | 6 | $(TARGET): main.o 7 | $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $^ -o $@ 8 | 9 | ifdef DEBUG 10 | ifeq ($(shell uname),Darwin) 11 | install_name_tool -change @loader_path/../Frameworks/libspotify.framework/libspotify @rpath/libspotify.so $@ 12 | endif 13 | endif 14 | -------------------------------------------------------------------------------- /libspotify/examples/stub/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | #include 4 | #endif 5 | -------------------------------------------------------------------------------- /libspotify/lib/libspotify.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/libspotify/lib/libspotify.dll -------------------------------------------------------------------------------- /libspotify/lib/libspotify.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stengerh/foo_input_spotify/d6f0da518b30aa16ca70926b5c547de103f038b5/libspotify/lib/libspotify.lib --------------------------------------------------------------------------------