a mega cool windows xp app

feat: add bass integration

dunkirk.sh f0b056e6 6a468a41

verified
+12 -9
CMakeLists.txt
··· 1 1 cmake_minimum_required(VERSION 3.16) 2 - project(HelloWorldApp CXX) 2 + project(ShortwaveApp CXX) 3 3 4 4 # Generate compile_commands.json for editor support 5 5 set(CMAKE_EXPORT_COMPILE_COMMANDS ON) ··· 14 14 add_compile_options(-fno-threadsafe-statics) 15 15 add_compile_options(-D_GLIBCXX_HAS_GTHREADS=0) 16 16 17 - add_executable(HelloWorldApp WIN32 main.cpp) 18 - target_link_libraries(HelloWorldApp user32 gdi32 winmm) 17 + add_executable(ShortwaveApp WIN32 main.cpp) 18 + 19 + # Add BASS library from libs directory 20 + target_include_directories(ShortwaveApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 21 + target_link_libraries(ShortwaveApp user32 gdi32 winmm wininet ${CMAKE_CURRENT_SOURCE_DIR}/libs/bass.lib) 19 22 20 23 # Include current directory for headers 21 - target_include_directories(HelloWorldApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 24 + target_include_directories(ShortwaveApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 22 25 23 26 # Minimal static linking and avoid threading dependencies 24 - target_link_options(HelloWorldApp PRIVATE 27 + target_link_options(ShortwaveApp PRIVATE 25 28 -static-libgcc 26 29 -static-libstdc++ 27 30 -static ··· 30 33 31 34 # Configurable output directory 32 35 if(DEFINED OUTPUT_DIR) 33 - set_target_properties(HelloWorldApp PROPERTIES 36 + set_target_properties(ShortwaveApp PROPERTIES 34 37 RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}" 35 38 RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}" 36 39 RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}" 37 40 ) 38 41 endif() 39 42 40 - set_target_properties(HelloWorldApp PROPERTIES 41 - OUTPUT_NAME "HelloWorld" 43 + set_target_properties(ShortwaveApp PROPERTIES 44 + OUTPUT_NAME "Shortwave" 42 45 ) 43 46 44 47 # Configurable output directory 45 48 if(DEFINED OUTPUT_DIR) 46 - set_target_properties(HelloWorldApp PROPERTIES 49 + set_target_properties(ShortwaveApp PROPERTIES 47 50 RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}" 48 51 RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}" 49 52 RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}"
+20 -7
CRUSH.md
··· 1 - # Shortwave Development Guide 1 + # Shortwave Radio Development Guide 2 2 3 3 ## Project Overview 4 4 - **Language**: C-style C++ for Win32 API compatibility 5 5 - **Target Platform**: Windows XP 6 - - **Primary Goal**: Simple Win32 Application 6 + - **Primary Goal**: Vintage Shortwave Radio Tuner Application 7 7 8 8 ## Build & Development Commands 9 9 - **Build**: `nix build` 10 - - Compiles Win32 application 10 + - Compiles Shortwave Radio application 11 11 - **Dev Setup**: `setup-dev` 12 12 - Generates `compile_commands.json` 13 13 - **Deploy**: `deploy-to-xp` ··· 15 15 - **Debugging**: Use Visual Studio or WinDbg 16 16 - **Testing**: Manual testing on Windows XP 17 17 18 + ## Important: Nix Build System 19 + - **CRITICAL**: Nix only includes files tracked in git 20 + - **Always run**: `git add .` after adding new files/libraries 21 + - **BASS Integration**: Files in `libs/` directory must be committed to git 22 + - **Build fails?** Check if new files are added to git with `git status` 23 + 18 24 ## Code Style Guidelines 19 25 20 26 ### Formatting ··· 24 30 - Avoid trailing whitespace 25 31 26 32 ### Naming Conventions 27 - - Functions: `PascalCase` (e.g., `QRCode_Init`) 33 + - Functions: `PascalCase` (e.g., `StartBassStreaming`) 28 34 - Constants/Macros: `UPPER_SNAKE_CASE` (e.g., `ID_ABOUT`) 29 - - Global Variables: `g_` prefix (e.g., `g_qrCode`) 35 + - Global Variables: `g_` prefix (e.g., `g_radio`) 30 36 - Avoid abbreviations 31 37 32 38 ### Types & Memory ··· 41 47 - Always check Win32 API return values 42 48 - Validate pointers before use 43 49 - Use `NULL` checks 44 - - Log errors to file/console 50 + - Log errors to console/file 45 51 - Graceful failure modes 46 52 47 53 ### Imports & Headers ··· 59 65 - Prioritize Win32 API compatibility 60 66 - Minimize external dependencies 61 67 - Focus on performance and low resource usage 62 - - Test thoroughly on target Windows XP environment 68 + - Test thoroughly on target Windows XP environment 69 + 70 + ## Radio Features 71 + - Vintage shortwave radio interface 72 + - Internet radio streaming capability 73 + - Realistic tuning and signal simulation 74 + - Keyboard and mouse controls 75 + - Debug console for troubleshooting
+36 -39
flake.nix
··· 1 1 { 2 - description = "Win32 Hello World App with About dropdown"; 2 + description = "Shortwave Radio Tuner - Win32 App for Windows XP"; 3 3 4 4 inputs = { 5 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05"; ··· 40 40 41 41 buildPhase = '' 42 42 export LDFLAGS="-static -static-libgcc -static-libstdc++" 43 + 44 + # Check if BASS files exist in libs directory 45 + if [ -f "libs/bass.h" ] && [ -f "libs/bass.lib" ]; then 46 + echo "BASS files found in libs/ - building with audio integration" 47 + else 48 + echo "BASS files not found in libs/ - building without audio integration" 49 + # Disable BASS in the source 50 + sed -i 's|#include "libs/bass.h"|// #include "libs/bass.h"|' main.cpp 51 + sed -i 's|libs/bass.lib||' CMakeLists.txt 52 + fi 53 + 43 54 cmake -DCMAKE_BUILD_TYPE=Release \ 44 55 -DCMAKE_SYSTEM_NAME=Windows \ 45 56 -DCMAKE_C_COMPILER=$CC \ ··· 50 61 51 62 installPhase = '' 52 63 mkdir -p $out/bin 53 - cp HelloWorld.exe $out/bin/ 64 + cp Shortwave.exe $out/bin/ 54 65 ''; 55 66 }; 56 67 ··· 58 69 XP_DIR="$HOME/Documents/xp-drive" 59 70 mkdir -p "$XP_DIR" 60 71 61 - # Handle Windows file locking by using a temporary name first 62 - TEMP_NAME="HelloWorld_new.exe" 63 - OLD_NAME="HelloWorld_old.exe" 64 - FINAL_NAME="HelloWorld.exe" 72 + echo "Deploying Shortwave Radio to $XP_DIR..." 65 73 66 - echo "Deploying to $XP_DIR..." 74 + # Copy executable with force overwrite 75 + if cp -f ${self'.packages.shortwave}/bin/Shortwave.exe "$XP_DIR/"; then 76 + echo "✓ Copied Shortwave.exe" 77 + else 78 + echo "✗ Failed to copy Shortwave.exe" 79 + exit 1 80 + fi 67 81 68 - # Copy to temporary name first 69 - if cp ${self'.packages.shortwave}/bin/HelloWorld.exe "$XP_DIR/$TEMP_NAME"; then 70 - echo "Copied new version as $TEMP_NAME" 71 - 72 - # If the original exists, try to rename it 73 - if [ -f "$XP_DIR/$FINAL_NAME" ]; then 74 - if mv "$XP_DIR/$FINAL_NAME" "$XP_DIR/$OLD_NAME" 2>/dev/null; then 75 - echo "Backed up old version as $OLD_NAME" 76 - else 77 - echo "Warning: Could not backup old version (file may be in use)" 78 - echo "Close the application on XP and try again, or manually rename files" 79 - echo "New version is available as: $TEMP_NAME" 80 - exit 1 81 - fi 82 - fi 83 - 84 - # Move temp to final name 85 - if mv "$XP_DIR/$TEMP_NAME" "$XP_DIR/$FINAL_NAME"; then 86 - echo "Deployed HelloWorld.exe successfully" 87 - 88 - # Clean up old backup if it exists 89 - if [ -f "$XP_DIR/$OLD_NAME" ]; then 90 - rm -f "$XP_DIR/$OLD_NAME" 2>/dev/null || echo "(Old backup file remains)" 91 - fi 82 + # Copy BASS DLL from libs directory 83 + if [ -f libs/bass.dll ]; then 84 + if cp -f libs/bass.dll "$XP_DIR/"; then 85 + echo "✓ Copied bass.dll" 92 86 else 93 - echo "Failed to finalize deployment" 87 + echo "✗ Failed to copy bass.dll" 94 88 exit 1 95 89 fi 96 90 else 97 - echo "Failed to copy new version" 98 - exit 1 91 + echo "⚠ bass.dll not found in libs/ directory - BASS audio will not work" 99 92 fi 93 + 94 + echo "🎵 Shortwave Radio deployed successfully!" 95 + echo "Files in XP directory:" 96 + ls -la "$XP_DIR"/*.{exe,dll} 2>/dev/null || echo "No files found" 100 97 ''; 101 98 102 99 setup-dev = pkgs.writeShellScriptBin "setup-dev" '' 103 - echo "Setting up development environment for Zed..." 100 + echo "Setting up development environment for Shortwave Radio..." 104 101 105 102 # Get dynamic paths from nix packages 106 103 GCC_BASE="${pkgs.pkgsCross.mingw32.buildPackages.gcc}/i686-w64-mingw32" ··· 146 143 EOF 147 144 148 145 echo "Generated .clangd config and compile_commands.json with include paths" 149 - echo "Development environment ready for Zed editor" 146 + echo "Development environment ready for Shortwave Radio development" 150 147 echo "Include paths:" 151 148 echo " C standard library: $SYS_INCLUDE" 152 149 echo " MinGW headers: $MINGW_MAIN_INCLUDE" ··· 166 163 ]; 167 164 168 165 shellHook = '' 169 - echo "Win32 development environment loaded" 166 + echo "Shortwave Radio development environment loaded" 170 167 echo "Available commands:" 171 - echo " nix build - Build the application" 168 + echo " nix build - Build the Shortwave Radio application" 172 169 echo " deploy-to-xp - Deploy to XP VM folder" 173 170 echo "" 174 171 echo "Setting up development environment..." ··· 216 213 EOF 217 214 218 215 echo "✓ Generated .clangd config and compile_commands.json with include paths" 219 - echo "✓ Development environment ready for Zed editor" 216 + echo "✓ Development environment ready for Shortwave Radio development" 220 217 ''; 221 218 }; 222 219 };
libs/bass.dll

This is a binary file and will not be displayed.

+1149
libs/bass.h
··· 1 + /* 2 + BASS 2.4 C/C++ header file 3 + Copyright (c) 1999-2022 Un4seen Developments Ltd. 4 + 5 + See the BASS.CHM file for more detailed documentation 6 + */ 7 + 8 + #ifndef BASS_H 9 + #define BASS_H 10 + 11 + #ifdef _WIN32 12 + #ifdef WINAPI_FAMILY 13 + #include <winapifamily.h> 14 + #endif 15 + #include <wtypes.h> 16 + typedef unsigned __int64 QWORD; 17 + #else 18 + #include <stdint.h> 19 + #define WINAPI 20 + #define CALLBACK 21 + typedef uint8_t BYTE; 22 + typedef uint16_t WORD; 23 + typedef uint32_t DWORD; 24 + typedef uint64_t QWORD; 25 + #ifdef __OBJC__ 26 + typedef int BOOL32; 27 + #define BOOL BOOL32 // override objc's BOOL 28 + #else 29 + typedef int BOOL; 30 + #endif 31 + #ifndef TRUE 32 + #define TRUE 1 33 + #define FALSE 0 34 + #endif 35 + #define LOBYTE(a) (BYTE)(a) 36 + #define HIBYTE(a) (BYTE)((a)>>8) 37 + #define LOWORD(a) (WORD)(a) 38 + #define HIWORD(a) (WORD)((a)>>16) 39 + #define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8)) 40 + #define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16)) 41 + #endif 42 + 43 + #ifdef __cplusplus 44 + extern "C" { 45 + #endif 46 + 47 + #define BASSVERSION 0x204 // API version 48 + #define BASSVERSIONTEXT "2.4" 49 + 50 + #ifndef BASSDEF 51 + #define BASSDEF(f) WINAPI f 52 + #else 53 + #define NOBASSOVERLOADS 54 + #endif 55 + 56 + typedef DWORD HMUSIC; // MOD music handle 57 + typedef DWORD HSAMPLE; // sample handle 58 + typedef DWORD HCHANNEL; // sample playback handle 59 + typedef DWORD HSTREAM; // sample stream handle 60 + typedef DWORD HRECORD; // recording handle 61 + typedef DWORD HSYNC; // synchronizer handle 62 + typedef DWORD HDSP; // DSP handle 63 + typedef DWORD HFX; // effect handle 64 + typedef DWORD HPLUGIN; // plugin handle 65 + 66 + // Error codes returned by BASS_ErrorGetCode 67 + #define BASS_OK 0 // all is OK 68 + #define BASS_ERROR_MEM 1 // memory error 69 + #define BASS_ERROR_FILEOPEN 2 // can't open the file 70 + #define BASS_ERROR_DRIVER 3 // can't find a free/valid driver 71 + #define BASS_ERROR_BUFLOST 4 // the sample buffer was lost 72 + #define BASS_ERROR_HANDLE 5 // invalid handle 73 + #define BASS_ERROR_FORMAT 6 // unsupported sample format 74 + #define BASS_ERROR_POSITION 7 // invalid position 75 + #define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called 76 + #define BASS_ERROR_START 9 // BASS_Start has not been successfully called 77 + #define BASS_ERROR_SSL 10 // SSL/HTTPS support isn't available 78 + #define BASS_ERROR_REINIT 11 // device needs to be reinitialized 79 + #define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever 80 + #define BASS_ERROR_NOTAUDIO 17 // file does not contain audio 81 + #define BASS_ERROR_NOCHAN 18 // can't get a free channel 82 + #define BASS_ERROR_ILLTYPE 19 // an illegal type was specified 83 + #define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified 84 + #define BASS_ERROR_NO3D 21 // no 3D support 85 + #define BASS_ERROR_NOEAX 22 // no EAX support 86 + #define BASS_ERROR_DEVICE 23 // illegal device number 87 + #define BASS_ERROR_NOPLAY 24 // not playing 88 + #define BASS_ERROR_FREQ 25 // illegal sample rate 89 + #define BASS_ERROR_NOTFILE 27 // the stream is not a file stream 90 + #define BASS_ERROR_NOHW 29 // no hardware voices available 91 + #define BASS_ERROR_EMPTY 31 // the file has no sample data 92 + #define BASS_ERROR_NONET 32 // no internet connection could be opened 93 + #define BASS_ERROR_CREATE 33 // couldn't create the file 94 + #define BASS_ERROR_NOFX 34 // effects are not available 95 + #define BASS_ERROR_NOTAVAIL 37 // requested data/action is not available 96 + #define BASS_ERROR_DECODE 38 // the channel is/isn't a "decoding channel" 97 + #define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed 98 + #define BASS_ERROR_TIMEOUT 40 // connection timedout 99 + #define BASS_ERROR_FILEFORM 41 // unsupported file format 100 + #define BASS_ERROR_SPEAKER 42 // unavailable speaker 101 + #define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons) 102 + #define BASS_ERROR_CODEC 44 // codec is not available/supported 103 + #define BASS_ERROR_ENDED 45 // the channel/file has ended 104 + #define BASS_ERROR_BUSY 46 // the device is busy 105 + #define BASS_ERROR_UNSTREAMABLE 47 // unstreamable file 106 + #define BASS_ERROR_PROTOCOL 48 // unsupported protocol 107 + #define BASS_ERROR_DENIED 49 // access denied 108 + #define BASS_ERROR_UNKNOWN -1 // some other mystery problem 109 + 110 + // BASS_SetConfig options 111 + #define BASS_CONFIG_BUFFER 0 112 + #define BASS_CONFIG_UPDATEPERIOD 1 113 + #define BASS_CONFIG_GVOL_SAMPLE 4 114 + #define BASS_CONFIG_GVOL_STREAM 5 115 + #define BASS_CONFIG_GVOL_MUSIC 6 116 + #define BASS_CONFIG_CURVE_VOL 7 117 + #define BASS_CONFIG_CURVE_PAN 8 118 + #define BASS_CONFIG_FLOATDSP 9 119 + #define BASS_CONFIG_3DALGORITHM 10 120 + #define BASS_CONFIG_NET_TIMEOUT 11 121 + #define BASS_CONFIG_NET_BUFFER 12 122 + #define BASS_CONFIG_PAUSE_NOPLAY 13 123 + #define BASS_CONFIG_NET_PREBUF 15 124 + #define BASS_CONFIG_NET_PASSIVE 18 125 + #define BASS_CONFIG_REC_BUFFER 19 126 + #define BASS_CONFIG_NET_PLAYLIST 21 127 + #define BASS_CONFIG_MUSIC_VIRTUAL 22 128 + #define BASS_CONFIG_VERIFY 23 129 + #define BASS_CONFIG_UPDATETHREADS 24 130 + #define BASS_CONFIG_DEV_BUFFER 27 131 + #define BASS_CONFIG_REC_LOOPBACK 28 132 + #define BASS_CONFIG_VISTA_TRUEPOS 30 133 + #define BASS_CONFIG_IOS_SESSION 34 134 + #define BASS_CONFIG_IOS_MIXAUDIO 34 135 + #define BASS_CONFIG_DEV_DEFAULT 36 136 + #define BASS_CONFIG_NET_READTIMEOUT 37 137 + #define BASS_CONFIG_VISTA_SPEAKERS 38 138 + #define BASS_CONFIG_IOS_SPEAKER 39 139 + #define BASS_CONFIG_MF_DISABLE 40 140 + #define BASS_CONFIG_HANDLES 41 141 + #define BASS_CONFIG_UNICODE 42 142 + #define BASS_CONFIG_SRC 43 143 + #define BASS_CONFIG_SRC_SAMPLE 44 144 + #define BASS_CONFIG_ASYNCFILE_BUFFER 45 145 + #define BASS_CONFIG_OGG_PRESCAN 47 146 + #define BASS_CONFIG_MF_VIDEO 48 147 + #define BASS_CONFIG_AIRPLAY 49 148 + #define BASS_CONFIG_DEV_NONSTOP 50 149 + #define BASS_CONFIG_IOS_NOCATEGORY 51 150 + #define BASS_CONFIG_VERIFY_NET 52 151 + #define BASS_CONFIG_DEV_PERIOD 53 152 + #define BASS_CONFIG_FLOAT 54 153 + #define BASS_CONFIG_NET_SEEK 56 154 + #define BASS_CONFIG_AM_DISABLE 58 155 + #define BASS_CONFIG_NET_PLAYLIST_DEPTH 59 156 + #define BASS_CONFIG_NET_PREBUF_WAIT 60 157 + #define BASS_CONFIG_ANDROID_SESSIONID 62 158 + #define BASS_CONFIG_WASAPI_PERSIST 65 159 + #define BASS_CONFIG_REC_WASAPI 66 160 + #define BASS_CONFIG_ANDROID_AAUDIO 67 161 + #define BASS_CONFIG_SAMPLE_ONEHANDLE 69 162 + #define BASS_CONFIG_NET_META 71 163 + #define BASS_CONFIG_NET_RESTRATE 72 164 + #define BASS_CONFIG_REC_DEFAULT 73 165 + #define BASS_CONFIG_NORAMP 74 166 + 167 + // BASS_SetConfigPtr options 168 + #define BASS_CONFIG_NET_AGENT 16 169 + #define BASS_CONFIG_NET_PROXY 17 170 + #define BASS_CONFIG_IOS_NOTIFY 46 171 + #define BASS_CONFIG_ANDROID_JAVAVM 63 172 + #define BASS_CONFIG_LIBSSL 64 173 + #define BASS_CONFIG_FILENAME 75 174 + 175 + #define BASS_CONFIG_THREAD 0x40000000 // flag: thread-specific setting 176 + 177 + // BASS_CONFIG_IOS_SESSION flags 178 + #define BASS_IOS_SESSION_MIX 1 179 + #define BASS_IOS_SESSION_DUCK 2 180 + #define BASS_IOS_SESSION_AMBIENT 4 181 + #define BASS_IOS_SESSION_SPEAKER 8 182 + #define BASS_IOS_SESSION_DISABLE 16 183 + #define BASS_IOS_SESSION_DEACTIVATE 32 184 + #define BASS_IOS_SESSION_AIRPLAY 64 185 + #define BASS_IOS_SESSION_BTHFP 128 186 + #define BASS_IOS_SESSION_BTA2DP 0x100 187 + 188 + // BASS_Init flags 189 + #define BASS_DEVICE_8BITS 1 // unused 190 + #define BASS_DEVICE_MONO 2 // mono 191 + #define BASS_DEVICE_3D 4 // unused 192 + #define BASS_DEVICE_16BITS 8 // limit output to 16-bit 193 + #define BASS_DEVICE_REINIT 128 // reinitialize 194 + #define BASS_DEVICE_LATENCY 0x100 // unused 195 + #define BASS_DEVICE_CPSPEAKERS 0x400 // unused 196 + #define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment 197 + #define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement 198 + #define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin 199 + #define BASS_DEVICE_FREQ 0x4000 // set device sample rate 200 + #define BASS_DEVICE_STEREO 0x8000 // limit output to stereo 201 + #define BASS_DEVICE_HOG 0x10000 // hog/exclusive mode 202 + #define BASS_DEVICE_AUDIOTRACK 0x20000 // use AudioTrack output 203 + #define BASS_DEVICE_DSOUND 0x40000 // use DirectSound output 204 + #define BASS_DEVICE_SOFTWARE 0x80000 // disable hardware/fastpath output 205 + 206 + // DirectSound interfaces (for use with BASS_GetDSoundObject) 207 + #define BASS_OBJECT_DS 1 // IDirectSound 208 + #define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener 209 + 210 + // Device info structure 211 + typedef struct { 212 + #if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) 213 + const wchar_t *name; // description 214 + const wchar_t *driver; // driver 215 + #else 216 + const char *name; // description 217 + const char *driver; // driver 218 + #endif 219 + DWORD flags; 220 + } BASS_DEVICEINFO; 221 + 222 + // BASS_DEVICEINFO flags 223 + #define BASS_DEVICE_ENABLED 1 224 + #define BASS_DEVICE_DEFAULT 2 225 + #define BASS_DEVICE_INIT 4 226 + #define BASS_DEVICE_LOOPBACK 8 227 + #define BASS_DEVICE_DEFAULTCOM 128 228 + 229 + #define BASS_DEVICE_TYPE_MASK 0xff000000 230 + #define BASS_DEVICE_TYPE_NETWORK 0x01000000 231 + #define BASS_DEVICE_TYPE_SPEAKERS 0x02000000 232 + #define BASS_DEVICE_TYPE_LINE 0x03000000 233 + #define BASS_DEVICE_TYPE_HEADPHONES 0x04000000 234 + #define BASS_DEVICE_TYPE_MICROPHONE 0x05000000 235 + #define BASS_DEVICE_TYPE_HEADSET 0x06000000 236 + #define BASS_DEVICE_TYPE_HANDSET 0x07000000 237 + #define BASS_DEVICE_TYPE_DIGITAL 0x08000000 238 + #define BASS_DEVICE_TYPE_SPDIF 0x09000000 239 + #define BASS_DEVICE_TYPE_HDMI 0x0a000000 240 + #define BASS_DEVICE_TYPE_DISPLAYPORT 0x40000000 241 + 242 + // BASS_GetDeviceInfo flags 243 + #define BASS_DEVICES_AIRPLAY 0x1000000 244 + 245 + typedef struct { 246 + DWORD flags; // device capabilities (DSCAPS_xxx flags) 247 + DWORD hwsize; // unused 248 + DWORD hwfree; // unused 249 + DWORD freesam; // unused 250 + DWORD free3d; // unused 251 + DWORD minrate; // unused 252 + DWORD maxrate; // unused 253 + BOOL eax; // unused 254 + DWORD minbuf; // recommended minimum buffer length in ms 255 + DWORD dsver; // DirectSound version 256 + DWORD latency; // average delay (in ms) before start of playback 257 + DWORD initflags; // BASS_Init "flags" parameter 258 + DWORD speakers; // number of speakers available 259 + DWORD freq; // current output rate 260 + } BASS_INFO; 261 + 262 + // BASS_INFO flags (from DSOUND.H) 263 + #define DSCAPS_EMULDRIVER 0x00000020 // device does not have hardware DirectSound support 264 + #define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft 265 + 266 + #define DSCAPS_HARDWARE 0x80000000 // hardware mixed 267 + 268 + // Recording device info structure 269 + typedef struct { 270 + DWORD flags; // device capabilities (DSCCAPS_xxx flags) 271 + DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags) 272 + DWORD inputs; // number of inputs 273 + BOOL singlein; // TRUE = only 1 input can be set at a time 274 + DWORD freq; // current input rate 275 + } BASS_RECORDINFO; 276 + 277 + // BASS_RECORDINFO flags (from DSOUND.H) 278 + #define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does not have hardware DirectSound recording support 279 + #define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft 280 + 281 + // defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H) 282 + #ifndef WAVE_FORMAT_1M08 283 + #define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */ 284 + #define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */ 285 + #define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */ 286 + #define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */ 287 + #define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */ 288 + #define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */ 289 + #define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */ 290 + #define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */ 291 + #define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */ 292 + #define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */ 293 + #define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */ 294 + #define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */ 295 + #endif 296 + 297 + // Sample info structure 298 + typedef struct { 299 + DWORD freq; // default playback rate 300 + float volume; // default volume (0-1) 301 + float pan; // default pan (-1=left, 0=middle, 1=right) 302 + DWORD flags; // BASS_SAMPLE_xxx flags 303 + DWORD length; // length (in bytes) 304 + DWORD max; // maximum simultaneous playbacks 305 + DWORD origres; // original resolution 306 + DWORD chans; // number of channels 307 + DWORD mingap; // minimum gap (ms) between creating channels 308 + DWORD mode3d; // BASS_3DMODE_xxx mode 309 + float mindist; // minimum distance 310 + float maxdist; // maximum distance 311 + DWORD iangle; // angle of inside projection cone 312 + DWORD oangle; // angle of outside projection cone 313 + float outvol; // delta-volume outside the projection cone 314 + DWORD vam; // unused 315 + DWORD priority; // unused 316 + } BASS_SAMPLE; 317 + 318 + #define BASS_SAMPLE_8BITS 1 // 8 bit 319 + #define BASS_SAMPLE_FLOAT 256 // 32 bit floating-point 320 + #define BASS_SAMPLE_MONO 2 // mono 321 + #define BASS_SAMPLE_LOOP 4 // looped 322 + #define BASS_SAMPLE_3D 8 // 3D functionality 323 + #define BASS_SAMPLE_SOFTWARE 16 // unused 324 + #define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only) 325 + #define BASS_SAMPLE_VAM 64 // unused 326 + #define BASS_SAMPLE_FX 128 // unused 327 + #define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume 328 + #define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing 329 + #define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only) 330 + 331 + #define BASS_STREAM_PRESCAN 0x20000 // scan file for accurate seeking and length 332 + #define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stops/ends 333 + #define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file stream 334 + #define BASS_STREAM_BLOCK 0x100000 // download internet file stream in small blocks 335 + #define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode 336 + #define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC 337 + 338 + #define BASS_MP3_IGNOREDELAY 0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info 339 + #define BASS_MP3_SETPOS BASS_STREAM_PRESCAN 340 + 341 + #define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT 342 + #define BASS_MUSIC_MONO BASS_SAMPLE_MONO 343 + #define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP 344 + #define BASS_MUSIC_3D BASS_SAMPLE_3D 345 + #define BASS_MUSIC_FX BASS_SAMPLE_FX 346 + #define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE 347 + #define BASS_MUSIC_DECODE BASS_STREAM_DECODE 348 + #define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length 349 + #define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN 350 + #define BASS_MUSIC_RAMP 0x200 // normal ramping 351 + #define BASS_MUSIC_RAMPS 0x400 // sensitive ramping 352 + #define BASS_MUSIC_SURROUND 0x800 // surround sound 353 + #define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2) 354 + #define BASS_MUSIC_FT2PAN 0x2000 // apply FastTracker 2 panning to XM files 355 + #define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does 356 + #define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does 357 + #define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing 358 + #define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing 359 + #define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position 360 + #define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position 361 + #define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect 362 + #define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples 363 + 364 + // Speaker assignment flags 365 + #define BASS_SPEAKER_FRONT 0x1000000 // front speakers 366 + #define BASS_SPEAKER_REAR 0x2000000 // rear speakers 367 + #define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1) 368 + #define BASS_SPEAKER_SIDE 0x4000000 // side speakers (7.1) 369 + #define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15) 370 + #define BASS_SPEAKER_LEFT 0x10000000 // modifier: left 371 + #define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right 372 + #define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT | BASS_SPEAKER_LEFT 373 + #define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT | BASS_SPEAKER_RIGHT 374 + #define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR | BASS_SPEAKER_LEFT 375 + #define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR | BASS_SPEAKER_RIGHT 376 + #define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE | BASS_SPEAKER_LEFT 377 + #define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE | BASS_SPEAKER_RIGHT 378 + #define BASS_SPEAKER_SIDELEFT BASS_SPEAKER_SIDE | BASS_SPEAKER_LEFT 379 + #define BASS_SPEAKER_SIDERIGHT BASS_SPEAKER_SIDE | BASS_SPEAKER_RIGHT 380 + #define BASS_SPEAKER_REAR2 BASS_SPEAKER_SIDE 381 + #define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_SIDELEFT 382 + #define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_SIDERIGHT 383 + 384 + #define BASS_ASYNCFILE 0x40000000 // read file asynchronously 385 + #define BASS_UNICODE 0x80000000 // UTF-16 386 + 387 + #define BASS_RECORD_ECHOCANCEL 0x2000 388 + #define BASS_RECORD_AGC 0x4000 389 + #define BASS_RECORD_PAUSE 0x8000 // start recording paused 390 + 391 + // DX7 voice allocation & management flags 392 + #define BASS_VAM_HARDWARE 1 393 + #define BASS_VAM_SOFTWARE 2 394 + #define BASS_VAM_TERM_TIME 4 395 + #define BASS_VAM_TERM_DIST 8 396 + #define BASS_VAM_TERM_PRIO 16 397 + 398 + // Channel info structure 399 + typedef struct { 400 + DWORD freq; // default playback rate 401 + DWORD chans; // channels 402 + DWORD flags; 403 + DWORD ctype; // type of channel 404 + DWORD origres; // original resolution 405 + HPLUGIN plugin; 406 + HSAMPLE sample; 407 + const char *filename; 408 + } BASS_CHANNELINFO; 409 + 410 + #define BASS_ORIGRES_FLOAT 0x10000 411 + 412 + // BASS_CHANNELINFO types 413 + #define BASS_CTYPE_SAMPLE 1 414 + #define BASS_CTYPE_RECORD 2 415 + #define BASS_CTYPE_STREAM 0x10000 416 + #define BASS_CTYPE_STREAM_VORBIS 0x10002 417 + #define BASS_CTYPE_STREAM_OGG 0x10002 418 + #define BASS_CTYPE_STREAM_MP1 0x10003 419 + #define BASS_CTYPE_STREAM_MP2 0x10004 420 + #define BASS_CTYPE_STREAM_MP3 0x10005 421 + #define BASS_CTYPE_STREAM_AIFF 0x10006 422 + #define BASS_CTYPE_STREAM_CA 0x10007 423 + #define BASS_CTYPE_STREAM_MF 0x10008 424 + #define BASS_CTYPE_STREAM_AM 0x10009 425 + #define BASS_CTYPE_STREAM_SAMPLE 0x1000a 426 + #define BASS_CTYPE_STREAM_DUMMY 0x18000 427 + #define BASS_CTYPE_STREAM_DEVICE 0x18001 428 + #define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag (LOWORD=codec) 429 + #define BASS_CTYPE_STREAM_WAV_PCM 0x50001 430 + #define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003 431 + #define BASS_CTYPE_MUSIC_MOD 0x20000 432 + #define BASS_CTYPE_MUSIC_MTM 0x20001 433 + #define BASS_CTYPE_MUSIC_S3M 0x20002 434 + #define BASS_CTYPE_MUSIC_XM 0x20003 435 + #define BASS_CTYPE_MUSIC_IT 0x20004 436 + #define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag 437 + 438 + // BASS_PluginLoad flags 439 + #define BASS_PLUGIN_PROC 1 440 + 441 + typedef struct { 442 + DWORD ctype; // channel type 443 + #if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) 444 + const wchar_t *name; // format description 445 + const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...) 446 + #else 447 + const char *name; // format description 448 + const char *exts; // file extension filter (*.ext1;*.ext2;etc...) 449 + #endif 450 + } BASS_PLUGINFORM; 451 + 452 + typedef struct { 453 + DWORD version; // version (same form as BASS_GetVersion) 454 + DWORD formatc; // number of formats 455 + const BASS_PLUGINFORM *formats; // the array of formats 456 + } BASS_PLUGININFO; 457 + 458 + // 3D vector (for 3D positions/velocities/orientations) 459 + typedef struct BASS_3DVECTOR { 460 + #ifdef __cplusplus 461 + BASS_3DVECTOR() {} 462 + BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} 463 + #endif 464 + float x; // +=right, -=left 465 + float y; // +=up, -=down 466 + float z; // +=front, -=behind 467 + } BASS_3DVECTOR; 468 + 469 + // 3D channel modes 470 + #define BASS_3DMODE_NORMAL 0 // normal 3D processing 471 + #define BASS_3DMODE_RELATIVE 1 // position is relative to the listener 472 + #define BASS_3DMODE_OFF 2 // no 3D processing 473 + 474 + // software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM) 475 + #define BASS_3DALG_DEFAULT 0 476 + #define BASS_3DALG_OFF 1 477 + #define BASS_3DALG_FULL 2 478 + #define BASS_3DALG_LIGHT 3 479 + 480 + // BASS_SampleGetChannel flags 481 + #define BASS_SAMCHAN_NEW 1 // get a new playback channel 482 + #define BASS_SAMCHAN_STREAM 2 // create a stream 483 + 484 + typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user); 485 + /* User stream callback function. 486 + handle : The stream that needs writing 487 + buffer : Buffer to write the samples in 488 + length : Number of bytes to write 489 + user : The 'user' parameter value given when calling BASS_StreamCreate 490 + RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */ 491 + 492 + #define BASS_STREAMPROC_END 0x80000000 // end of user stream flag 493 + 494 + // Special STREAMPROCs 495 + #define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream 496 + #define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream 497 + #define STREAMPROC_DEVICE (STREAMPROC*)-2 // device mix stream 498 + #define STREAMPROC_DEVICE_3D (STREAMPROC*)-3 // device 3D mix stream 499 + 500 + // BASS_StreamCreateFileUser file systems 501 + #define STREAMFILE_NOBUFFER 0 502 + #define STREAMFILE_BUFFER 1 503 + #define STREAMFILE_BUFFERPUSH 2 504 + 505 + // User file stream callback functions 506 + typedef void (CALLBACK FILECLOSEPROC)(void *user); 507 + typedef QWORD (CALLBACK FILELENPROC)(void *user); 508 + typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user); 509 + typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user); 510 + 511 + typedef struct { 512 + FILECLOSEPROC *close; 513 + FILELENPROC *length; 514 + FILEREADPROC *read; 515 + FILESEEKPROC *seek; 516 + } BASS_FILEPROCS; 517 + 518 + // BASS_StreamPutFileData options 519 + #define BASS_FILEDATA_END 0 // end & close the file 520 + 521 + // BASS_StreamGetFilePosition modes 522 + #define BASS_FILEPOS_CURRENT 0 523 + #define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT 524 + #define BASS_FILEPOS_DOWNLOAD 1 525 + #define BASS_FILEPOS_END 2 526 + #define BASS_FILEPOS_START 3 527 + #define BASS_FILEPOS_CONNECTED 4 528 + #define BASS_FILEPOS_BUFFER 5 529 + #define BASS_FILEPOS_SOCKET 6 530 + #define BASS_FILEPOS_ASYNCBUF 7 531 + #define BASS_FILEPOS_SIZE 8 532 + #define BASS_FILEPOS_BUFFERING 9 533 + #define BASS_FILEPOS_AVAILABLE 10 534 + 535 + typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user); 536 + /* Internet stream download callback function. 537 + buffer : Buffer containing the downloaded data... NULL=end of download 538 + length : Number of bytes in the buffer 539 + user : The 'user' parameter value given when calling BASS_StreamCreateURL */ 540 + 541 + // BASS_ChannelSetSync types 542 + #define BASS_SYNC_POS 0 543 + #define BASS_SYNC_END 2 544 + #define BASS_SYNC_META 4 545 + #define BASS_SYNC_SLIDE 5 546 + #define BASS_SYNC_STALL 6 547 + #define BASS_SYNC_DOWNLOAD 7 548 + #define BASS_SYNC_FREE 8 549 + #define BASS_SYNC_SETPOS 11 550 + #define BASS_SYNC_MUSICPOS 10 551 + #define BASS_SYNC_MUSICINST 1 552 + #define BASS_SYNC_MUSICFX 3 553 + #define BASS_SYNC_OGG_CHANGE 12 554 + #define BASS_SYNC_DEV_FAIL 14 555 + #define BASS_SYNC_DEV_FORMAT 15 556 + #define BASS_SYNC_THREAD 0x20000000 // flag: call sync in other thread 557 + #define BASS_SYNC_MIXTIME 0x40000000 // flag: sync at mixtime, else at playtime 558 + #define BASS_SYNC_ONETIME 0x80000000 // flag: sync only once, else continuously 559 + 560 + typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user); 561 + /* Sync callback function. 562 + handle : The sync that has occured 563 + channel: Channel that the sync occured in 564 + data : Additional data associated with the sync's occurance 565 + user : The 'user' parameter given when calling BASS_ChannelSetSync */ 566 + 567 + typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user); 568 + /* DSP callback function. 569 + handle : The DSP handle 570 + channel: Channel that the DSP is being applied to 571 + buffer : Buffer to apply the DSP to 572 + length : Number of bytes in the buffer 573 + user : The 'user' parameter given when calling BASS_ChannelSetDSP */ 574 + 575 + typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user); 576 + /* Recording callback function. 577 + handle : The recording handle 578 + buffer : Buffer containing the recorded sample data 579 + length : Number of bytes 580 + user : The 'user' parameter value given when calling BASS_RecordStart 581 + RETURN : TRUE = continue recording, FALSE = stop */ 582 + 583 + // BASS_ChannelIsActive return values 584 + #define BASS_ACTIVE_STOPPED 0 585 + #define BASS_ACTIVE_PLAYING 1 586 + #define BASS_ACTIVE_STALLED 2 587 + #define BASS_ACTIVE_PAUSED 3 588 + #define BASS_ACTIVE_PAUSED_DEVICE 4 589 + 590 + // Channel attributes 591 + #define BASS_ATTRIB_FREQ 1 592 + #define BASS_ATTRIB_VOL 2 593 + #define BASS_ATTRIB_PAN 3 594 + #define BASS_ATTRIB_EAXMIX 4 595 + #define BASS_ATTRIB_NOBUFFER 5 596 + #define BASS_ATTRIB_VBR 6 597 + #define BASS_ATTRIB_CPU 7 598 + #define BASS_ATTRIB_SRC 8 599 + #define BASS_ATTRIB_NET_RESUME 9 600 + #define BASS_ATTRIB_SCANINFO 10 601 + #define BASS_ATTRIB_NORAMP 11 602 + #define BASS_ATTRIB_BITRATE 12 603 + #define BASS_ATTRIB_BUFFER 13 604 + #define BASS_ATTRIB_GRANULE 14 605 + #define BASS_ATTRIB_USER 15 606 + #define BASS_ATTRIB_TAIL 16 607 + #define BASS_ATTRIB_PUSH_LIMIT 17 608 + #define BASS_ATTRIB_DOWNLOADPROC 18 609 + #define BASS_ATTRIB_VOLDSP 19 610 + #define BASS_ATTRIB_VOLDSP_PRIORITY 20 611 + #define BASS_ATTRIB_MUSIC_AMPLIFY 0x100 612 + #define BASS_ATTRIB_MUSIC_PANSEP 0x101 613 + #define BASS_ATTRIB_MUSIC_PSCALER 0x102 614 + #define BASS_ATTRIB_MUSIC_BPM 0x103 615 + #define BASS_ATTRIB_MUSIC_SPEED 0x104 616 + #define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105 617 + #define BASS_ATTRIB_MUSIC_ACTIVE 0x106 618 + #define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel # 619 + #define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument # 620 + 621 + // BASS_ChannelSlideAttribute flags 622 + #define BASS_SLIDE_LOG 0x1000000 623 + 624 + // BASS_ChannelGetData flags 625 + #define BASS_DATA_AVAILABLE 0 // query how much data is buffered 626 + #define BASS_DATA_NOREMOVE 0x10000000 // flag: don't remove data from recording buffer 627 + #define BASS_DATA_FIXED 0x20000000 // unused 628 + #define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data 629 + #define BASS_DATA_FFT256 0x80000000 // 256 sample FFT 630 + #define BASS_DATA_FFT512 0x80000001 // 512 FFT 631 + #define BASS_DATA_FFT1024 0x80000002 // 1024 FFT 632 + #define BASS_DATA_FFT2048 0x80000003 // 2048 FFT 633 + #define BASS_DATA_FFT4096 0x80000004 // 4096 FFT 634 + #define BASS_DATA_FFT8192 0x80000005 // 8192 FFT 635 + #define BASS_DATA_FFT16384 0x80000006 // 16384 FFT 636 + #define BASS_DATA_FFT32768 0x80000007 // 32768 FFT 637 + #define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined 638 + #define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window 639 + #define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias 640 + #define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data 641 + #define BASS_DATA_FFT_NYQUIST 0x100 // FFT flag: return extra Nyquist value 642 + 643 + // BASS_ChannelGetLevelEx flags 644 + #define BASS_LEVEL_MONO 1 // get mono level 645 + #define BASS_LEVEL_STEREO 2 // get stereo level 646 + #define BASS_LEVEL_RMS 4 // get RMS levels 647 + #define BASS_LEVEL_VOLPAN 8 // apply VOL/PAN attributes to the levels 648 + #define BASS_LEVEL_NOREMOVE 16 // don't remove data from recording buffer 649 + 650 + // BASS_ChannelGetTags types : what's returned 651 + #define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure 652 + #define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block 653 + #define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings 654 + #define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ASCII strings 655 + #define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings 656 + #define BASS_TAG_META 5 // ICY metadata : ANSI string 657 + #define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings 658 + #define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings 659 + #define BASS_TAG_WMA 8 // WMA tags : series of null-terminated UTF-8 strings 660 + #define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string 661 + #define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string 662 + #define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure 663 + #define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings 664 + #define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure 665 + #define BASS_TAG_AM_NAME 16 // Android Media codec name : ASCII string 666 + #define BASS_TAG_ID3V2_2 17 // ID3v2 tags (2nd block) : variable length block 667 + #define BASS_TAG_AM_MIME 18 // Android Media MIME type : ASCII string 668 + #define BASS_TAG_LOCATION 19 // redirected URL : ASCII string 669 + #define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings 670 + #define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure 671 + #define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure 672 + #define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string 673 + #define BASS_TAG_RIFF_CUE 0x104 // RIFF "cue " chunk : TAG_CUE structure 674 + #define BASS_TAG_RIFF_SMPL 0x105 // RIFF "smpl" chunk : TAG_SMPL structure 675 + #define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure 676 + #define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string 677 + #define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string 678 + #define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers 679 + #define BASS_TAG_MUSIC_AUTH 0x10003 // MOD author : UTF-8 string 680 + #define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string 681 + #define BASS_TAG_MUSIC_CHAN 0x10200 // + channel #, MOD channel name : ANSI string 682 + #define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string 683 + 684 + // ID3v1 tag structure 685 + typedef struct { 686 + char id[3]; 687 + char title[30]; 688 + char artist[30]; 689 + char album[30]; 690 + char year[4]; 691 + char comment[30]; 692 + BYTE genre; 693 + } TAG_ID3; 694 + 695 + // Binary APE tag structure 696 + typedef struct { 697 + const char *key; 698 + const void *data; 699 + DWORD length; 700 + } TAG_APE_BINARY; 701 + 702 + // BWF "bext" tag structure 703 + #ifdef _MSC_VER 704 + #pragma warning(push) 705 + #pragma warning(disable:4200) 706 + #endif 707 + #pragma pack(push,1) 708 + typedef struct { 709 + char Description[256]; // description 710 + char Originator[32]; // name of the originator 711 + char OriginatorReference[32]; // reference of the originator 712 + char OriginationDate[10]; // date of creation (yyyy-mm-dd) 713 + char OriginationTime[8]; // time of creation (hh-mm-ss) 714 + QWORD TimeReference; // first sample count since midnight (little-endian) 715 + WORD Version; // BWF version (little-endian) 716 + BYTE UMID[64]; // SMPTE UMID 717 + BYTE Reserved[190]; 718 + #if defined(__GNUC__) && __GNUC__<3 719 + char CodingHistory[0]; // history 720 + #elif 1 // change to 0 if compiler fails the following line 721 + char CodingHistory[]; // history 722 + #else 723 + char CodingHistory[1]; // history 724 + #endif 725 + } TAG_BEXT; 726 + #pragma pack(pop) 727 + 728 + // BWF "cart" tag structures 729 + typedef struct 730 + { 731 + DWORD dwUsage; // FOURCC timer usage ID 732 + DWORD dwValue; // timer value in samples from head 733 + } TAG_CART_TIMER; 734 + 735 + typedef struct 736 + { 737 + char Version[4]; // version of the data structure 738 + char Title[64]; // title of cart audio sequence 739 + char Artist[64]; // artist or creator name 740 + char CutID[64]; // cut number identification 741 + char ClientID[64]; // client identification 742 + char Category[64]; // category ID, PSA, NEWS, etc 743 + char Classification[64]; // classification or auxiliary key 744 + char OutCue[64]; // out cue text 745 + char StartDate[10]; // yyyy-mm-dd 746 + char StartTime[8]; // hh:mm:ss 747 + char EndDate[10]; // yyyy-mm-dd 748 + char EndTime[8]; // hh:mm:ss 749 + char ProducerAppID[64]; // name of vendor or application 750 + char ProducerAppVersion[64]; // version of producer application 751 + char UserDef[64]; // user defined text 752 + DWORD dwLevelReference; // sample value for 0 dB reference 753 + TAG_CART_TIMER PostTimer[8]; // 8 time markers after head 754 + char Reserved[276]; 755 + char URL[1024]; // uniform resource locator 756 + #if defined(__GNUC__) && __GNUC__<3 757 + char TagText[0]; // free form text for scripts or tags 758 + #elif 1 // change to 0 if compiler fails the following line 759 + char TagText[]; // free form text for scripts or tags 760 + #else 761 + char TagText[1]; // free form text for scripts or tags 762 + #endif 763 + } TAG_CART; 764 + 765 + // RIFF "cue " tag structures 766 + typedef struct 767 + { 768 + DWORD dwName; 769 + DWORD dwPosition; 770 + DWORD fccChunk; 771 + DWORD dwChunkStart; 772 + DWORD dwBlockStart; 773 + DWORD dwSampleOffset; 774 + } TAG_CUE_POINT; 775 + 776 + typedef struct 777 + { 778 + DWORD dwCuePoints; 779 + #if defined(__GNUC__) && __GNUC__<3 780 + TAG_CUE_POINT CuePoints[0]; 781 + #elif 1 // change to 0 if compiler fails the following line 782 + TAG_CUE_POINT CuePoints[]; 783 + #else 784 + TAG_CUE_POINT CuePoints[1]; 785 + #endif 786 + } TAG_CUE; 787 + 788 + // RIFF "smpl" tag structures 789 + typedef struct 790 + { 791 + DWORD dwIdentifier; 792 + DWORD dwType; 793 + DWORD dwStart; 794 + DWORD dwEnd; 795 + DWORD dwFraction; 796 + DWORD dwPlayCount; 797 + } TAG_SMPL_LOOP; 798 + 799 + typedef struct 800 + { 801 + DWORD dwManufacturer; 802 + DWORD dwProduct; 803 + DWORD dwSamplePeriod; 804 + DWORD dwMIDIUnityNote; 805 + DWORD dwMIDIPitchFraction; 806 + DWORD dwSMPTEFormat; 807 + DWORD dwSMPTEOffset; 808 + DWORD cSampleLoops; 809 + DWORD cbSamplerData; 810 + #if defined(__GNUC__) && __GNUC__<3 811 + TAG_SMPL_LOOP SampleLoops[0]; 812 + #elif 1 // change to 0 if compiler fails the following line 813 + TAG_SMPL_LOOP SampleLoops[]; 814 + #else 815 + TAG_SMPL_LOOP SampleLoops[1]; 816 + #endif 817 + } TAG_SMPL; 818 + #ifdef _MSC_VER 819 + #pragma warning(pop) 820 + #endif 821 + 822 + // CoreAudio codec info structure 823 + typedef struct { 824 + DWORD ftype; // file format 825 + DWORD atype; // audio format 826 + const char *name; // description 827 + } TAG_CA_CODEC; 828 + 829 + #ifndef _WAVEFORMATEX_ 830 + #define _WAVEFORMATEX_ 831 + #pragma pack(push,1) 832 + typedef struct tWAVEFORMATEX 833 + { 834 + WORD wFormatTag; 835 + WORD nChannels; 836 + DWORD nSamplesPerSec; 837 + DWORD nAvgBytesPerSec; 838 + WORD nBlockAlign; 839 + WORD wBitsPerSample; 840 + WORD cbSize; 841 + } WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX; 842 + typedef const WAVEFORMATEX *LPCWAVEFORMATEX; 843 + #pragma pack(pop) 844 + #endif 845 + 846 + // BASS_ChannelGetLength/GetPosition/SetPosition modes 847 + #define BASS_POS_BYTE 0 // byte position 848 + #define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row) 849 + #define BASS_POS_OGG 3 // OGG bitstream number 850 + #define BASS_POS_END 0x10 // trimmed end position 851 + #define BASS_POS_LOOP 0x11 // loop start positiom 852 + #define BASS_POS_FLUSH 0x1000000 // flag: flush decoder/FX buffers 853 + #define BASS_POS_RESET 0x2000000 // flag: reset user file buffers 854 + #define BASS_POS_RELATIVE 0x4000000 // flag: seek relative to the current position 855 + #define BASS_POS_INEXACT 0x8000000 // flag: allow seeking to inexact position 856 + #define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position 857 + #define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking 858 + #define BASS_POS_SCAN 0x40000000 // flag: scan to the position 859 + 860 + // BASS_ChannelSetDevice/GetDevice option 861 + #define BASS_NODEVICE 0x20000 862 + 863 + // BASS_RecordSetInput flags 864 + #define BASS_INPUT_OFF 0x10000 865 + #define BASS_INPUT_ON 0x20000 866 + 867 + #define BASS_INPUT_TYPE_MASK 0xff000000 868 + #define BASS_INPUT_TYPE_UNDEF 0x00000000 869 + #define BASS_INPUT_TYPE_DIGITAL 0x01000000 870 + #define BASS_INPUT_TYPE_LINE 0x02000000 871 + #define BASS_INPUT_TYPE_MIC 0x03000000 872 + #define BASS_INPUT_TYPE_SYNTH 0x04000000 873 + #define BASS_INPUT_TYPE_CD 0x05000000 874 + #define BASS_INPUT_TYPE_PHONE 0x06000000 875 + #define BASS_INPUT_TYPE_SPEAKER 0x07000000 876 + #define BASS_INPUT_TYPE_WAVE 0x08000000 877 + #define BASS_INPUT_TYPE_AUX 0x09000000 878 + #define BASS_INPUT_TYPE_ANALOG 0x0a000000 879 + 880 + // BASS_ChannelSetFX effect types 881 + #define BASS_FX_DX8_CHORUS 0 882 + #define BASS_FX_DX8_COMPRESSOR 1 883 + #define BASS_FX_DX8_DISTORTION 2 884 + #define BASS_FX_DX8_ECHO 3 885 + #define BASS_FX_DX8_FLANGER 4 886 + #define BASS_FX_DX8_GARGLE 5 887 + #define BASS_FX_DX8_I3DL2REVERB 6 888 + #define BASS_FX_DX8_PARAMEQ 7 889 + #define BASS_FX_DX8_REVERB 8 890 + #define BASS_FX_VOLUME 9 891 + 892 + typedef struct { 893 + float fWetDryMix; 894 + float fDepth; 895 + float fFeedback; 896 + float fFrequency; 897 + DWORD lWaveform; // 0=triangle, 1=sine 898 + float fDelay; 899 + DWORD lPhase; // BASS_DX8_PHASE_xxx 900 + } BASS_DX8_CHORUS; 901 + 902 + typedef struct { 903 + float fGain; 904 + float fAttack; 905 + float fRelease; 906 + float fThreshold; 907 + float fRatio; 908 + float fPredelay; 909 + } BASS_DX8_COMPRESSOR; 910 + 911 + typedef struct { 912 + float fGain; 913 + float fEdge; 914 + float fPostEQCenterFrequency; 915 + float fPostEQBandwidth; 916 + float fPreLowpassCutoff; 917 + } BASS_DX8_DISTORTION; 918 + 919 + typedef struct { 920 + float fWetDryMix; 921 + float fFeedback; 922 + float fLeftDelay; 923 + float fRightDelay; 924 + BOOL lPanDelay; 925 + } BASS_DX8_ECHO; 926 + 927 + typedef struct { 928 + float fWetDryMix; 929 + float fDepth; 930 + float fFeedback; 931 + float fFrequency; 932 + DWORD lWaveform; // 0=triangle, 1=sine 933 + float fDelay; 934 + DWORD lPhase; // BASS_DX8_PHASE_xxx 935 + } BASS_DX8_FLANGER; 936 + 937 + typedef struct { 938 + DWORD dwRateHz; // Rate of modulation in hz 939 + DWORD dwWaveShape; // 0=triangle, 1=square 940 + } BASS_DX8_GARGLE; 941 + 942 + typedef struct { 943 + int lRoom; // [-10000, 0] default: -1000 mB 944 + int lRoomHF; // [-10000, 0] default: 0 mB 945 + float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 946 + float flDecayTime; // [0.1, 20.0] default: 1.49s 947 + float flDecayHFRatio; // [0.1, 2.0] default: 0.83 948 + int lReflections; // [-10000, 1000] default: -2602 mB 949 + float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s 950 + int lReverb; // [-10000, 2000] default: 200 mB 951 + float flReverbDelay; // [0.0, 0.1] default: 0.011 s 952 + float flDiffusion; // [0.0, 100.0] default: 100.0 % 953 + float flDensity; // [0.0, 100.0] default: 100.0 % 954 + float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz 955 + } BASS_DX8_I3DL2REVERB; 956 + 957 + typedef struct { 958 + float fCenter; 959 + float fBandwidth; 960 + float fGain; 961 + } BASS_DX8_PARAMEQ; 962 + 963 + typedef struct { 964 + float fInGain; // [-96.0,0.0] default: 0.0 dB 965 + float fReverbMix; // [-96.0,0.0] default: 0.0 db 966 + float fReverbTime; // [0.001,3000.0] default: 1000.0 ms 967 + float fHighFreqRTRatio; // [0.001,0.999] default: 0.001 968 + } BASS_DX8_REVERB; 969 + 970 + #define BASS_DX8_PHASE_NEG_180 0 971 + #define BASS_DX8_PHASE_NEG_90 1 972 + #define BASS_DX8_PHASE_ZERO 2 973 + #define BASS_DX8_PHASE_90 3 974 + #define BASS_DX8_PHASE_180 4 975 + 976 + typedef struct { 977 + float fTarget; 978 + float fCurrent; 979 + float fTime; 980 + DWORD lCurve; 981 + } BASS_FX_VOLUME_PARAM; 982 + 983 + typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status); 984 + /* iOS notification callback function. 985 + status : The notification (BASS_IOSNOTIFY_xxx) */ 986 + 987 + #define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started 988 + #define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended 989 + 990 + BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value); 991 + DWORD BASSDEF(BASS_GetConfig)(DWORD option); 992 + BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value); 993 + const void *BASSDEF(BASS_GetConfigPtr)(DWORD option); 994 + DWORD BASSDEF(BASS_GetVersion)(void); 995 + int BASSDEF(BASS_ErrorGetCode)(void); 996 + 997 + BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); 998 + #if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) 999 + BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const void *dsguid); 1000 + #else 1001 + BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, const void *dsguid); 1002 + #endif 1003 + BOOL BASSDEF(BASS_Free)(void); 1004 + BOOL BASSDEF(BASS_SetDevice)(DWORD device); 1005 + DWORD BASSDEF(BASS_GetDevice)(void); 1006 + BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info); 1007 + BOOL BASSDEF(BASS_Start)(void); 1008 + BOOL BASSDEF(BASS_Stop)(void); 1009 + BOOL BASSDEF(BASS_Pause)(void); 1010 + DWORD BASSDEF(BASS_IsStarted)(void); 1011 + BOOL BASSDEF(BASS_Update)(DWORD length); 1012 + float BASSDEF(BASS_GetCPU)(void); 1013 + BOOL BASSDEF(BASS_SetVolume)(float volume); 1014 + float BASSDEF(BASS_GetVolume)(void); 1015 + #if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) 1016 + void *BASSDEF(BASS_GetDSoundObject)(DWORD object); 1017 + #endif 1018 + 1019 + BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf); 1020 + BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf); 1021 + BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top); 1022 + BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top); 1023 + void BASSDEF(BASS_Apply3D)(void); 1024 + 1025 + HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags); 1026 + BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle); 1027 + BOOL BASSDEF(BASS_PluginEnable)(HPLUGIN handle, BOOL enable); 1028 + const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle); 1029 + 1030 + HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags); 1031 + HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags); 1032 + BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle); 1033 + BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer); 1034 + BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer); 1035 + BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info); 1036 + BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info); 1037 + DWORD BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, DWORD flags); 1038 + DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels); 1039 + BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle); 1040 + 1041 + HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user); 1042 + HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags); 1043 + HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user); 1044 + HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user); 1045 + BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle); 1046 + QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode); 1047 + DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length); 1048 + DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length); 1049 + 1050 + HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq); 1051 + BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle); 1052 + 1053 + BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); 1054 + BOOL BASSDEF(BASS_RecordInit)(int device); 1055 + BOOL BASSDEF(BASS_RecordFree)(void); 1056 + BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device); 1057 + DWORD BASSDEF(BASS_RecordGetDevice)(void); 1058 + BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info); 1059 + const char *BASSDEF(BASS_RecordGetInputName)(int input); 1060 + BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume); 1061 + DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume); 1062 + HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user); 1063 + 1064 + double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos); 1065 + QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos); 1066 + DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle); 1067 + BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device); 1068 + DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle); 1069 + BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info); 1070 + const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags); 1071 + DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask); 1072 + BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock); 1073 + BOOL BASSDEF(BASS_ChannelFree)(DWORD handle); 1074 + BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart); 1075 + BOOL BASSDEF(BASS_ChannelStart)(DWORD handle); 1076 + BOOL BASSDEF(BASS_ChannelStop)(DWORD handle); 1077 + BOOL BASSDEF(BASS_ChannelPause)(DWORD handle); 1078 + BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length); 1079 + BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value); 1080 + BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value); 1081 + BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time); 1082 + BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib); 1083 + BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); 1084 + DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); 1085 + BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol); 1086 + BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol); 1087 + BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel); 1088 + BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel); 1089 + QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode); 1090 + BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode); 1091 + QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode); 1092 + DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle); 1093 + BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags); 1094 + DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length); 1095 + HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user); 1096 + BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync); 1097 + BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan); 1098 + BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan); 1099 + HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority); 1100 + BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp); 1101 + HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority); 1102 + BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx); 1103 + 1104 + BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params); 1105 + BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params); 1106 + BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority); 1107 + BOOL BASSDEF(BASS_FXReset)(DWORD handle); 1108 + 1109 + #ifdef __cplusplus 1110 + } 1111 + 1112 + #if defined(_WIN32) && !defined(NOBASSOVERLOADS) 1113 + static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags) 1114 + { 1115 + return BASS_PluginLoad((const char*)file, flags | BASS_UNICODE); 1116 + } 1117 + 1118 + static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq) 1119 + { 1120 + return BASS_MusicLoad(mem, (const void*)file, offset, length, flags | BASS_UNICODE, freq); 1121 + } 1122 + 1123 + static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags) 1124 + { 1125 + return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags | BASS_UNICODE); 1126 + } 1127 + 1128 + static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags) 1129 + { 1130 + return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags | BASS_UNICODE); 1131 + } 1132 + 1133 + static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user) 1134 + { 1135 + return BASS_StreamCreateURL((const char*)url, offset, flags | BASS_UNICODE, proc, user); 1136 + } 1137 + 1138 + static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value) 1139 + { 1140 + return BASS_SetConfigPtr(option | BASS_UNICODE, (const void*)value); 1141 + } 1142 + #endif 1143 + #endif 1144 + 1145 + #ifdef __OBJC__ 1146 + #undef BOOL 1147 + #endif 1148 + 1149 + #endif
libs/bass.lib

This is a binary file and will not be displayed.

+291 -153
main.cpp
··· 3 3 #include <stdio.h> 4 4 #include <string.h> 5 5 #include <mmsystem.h> 6 + #include <wininet.h> 7 + #include "libs/bass.h" 6 8 7 9 #pragma comment(lib, "winmm.lib") 10 + #pragma comment(lib, "wininet.lib") 8 11 9 12 #define ID_ABOUT 1001 10 13 #define ID_EXIT 1002 ··· 19 22 float frequency; 20 23 char name[64]; 21 24 char description[128]; 25 + char streamUrl[256]; 22 26 } RadioStation; 23 27 24 28 RadioStation g_stations[] = { 25 - {14.230f, "BBC World Service", "International news and current affairs"}, 26 - {15.770f, "Radio Moscow", "Russian international broadcast"}, 27 - {17.895f, "Voice of America", "American international news"}, 28 - {21.500f, "Radio Australia", "Australian international service"}, 29 - {25.820f, "Radio Canada", "Canadian international broadcast"}, 30 - {28.400f, "Amateur Radio", "Ham radio operators"}, 31 - {31.100f, "Time Signal", "Atomic clock time broadcast"} 29 + {14.230f, "SomaFM Groove", "Downtempo and chillout", "http://ice1.somafm.com/groovesalad-128-mp3"}, 30 + {15.770f, "Radio Paradise", "Eclectic music mix", "http://stream.radioparadise.com/mp3-128"}, 31 + {17.895f, "Jazz Radio", "Smooth jazz", "http://jazz-wr04.ice.infomaniak.ch/jazz-wr04-128.mp3"}, 32 + {21.500f, "Classical Music", "Classical radio", "http://stream.wqxr.org/wqxr"}, 33 + {31.100f, "Chillout Lounge", "Relaxing music", "http://air.radiorecord.ru:805/chil_320"} 32 34 }; 33 35 34 36 #define NUM_STATIONS (sizeof(g_stations) / sizeof(RadioStation)) ··· 40 42 41 43 // Audio state 42 44 typedef struct { 43 - HWAVEOUT hWaveOut; 44 - WAVEHDR waveHeaders[NUM_BUFFERS]; 45 - short audioBuffers[NUM_BUFFERS][BUFFER_SIZE]; 46 - int currentBuffer; 45 + // BASS handles 46 + HSTREAM currentStream; 47 + HSTREAM staticStream; 47 48 int isPlaying; 48 49 float staticVolume; 49 50 float radioVolume; 51 + 52 + // Station tracking 53 + RadioStation* currentStation; 50 54 } AudioState; 51 55 52 56 // Radio state ··· 59 63 int isDraggingVolume; 60 64 } RadioState; 61 65 62 - RadioState g_radio = {14.230f, 0.5f, 0, 0, 0, 0}; 66 + RadioState g_radio = {14.230f, 0.8f, 0, 0, 0, 0}; // Increase default volume to 0.8 63 67 AudioState g_audio = {0}; 64 68 65 69 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); ··· 77 81 // Audio functions 78 82 int InitializeAudio(); 79 83 void CleanupAudio(); 80 - void GenerateStaticBuffer(short* buffer, int size); 81 - void FillAudioBuffer(short* buffer, int size); 82 - void CALLBACK WaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2); 83 84 void StartAudio(); 84 85 void StopAudio(); 85 86 RadioStation* FindNearestStation(float frequency); 86 87 float GetStationSignalStrength(RadioStation* station, float currentFreq); 88 + 89 + // BASS streaming functions 90 + int StartBassStreaming(RadioStation* station); 91 + void StopBassStreaming(); 87 92 88 93 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { 94 + // Allocate console for debugging 95 + AllocConsole(); 96 + freopen("CONOUT$", "w", stdout); 97 + freopen("CONOUT$", "w", stderr); 98 + printf("Shortwave Radio Debug Console\n"); 99 + printf("=============================\n"); 100 + 89 101 const char* CLASS_NAME = "ShortwaveRadio"; 90 102 91 103 WNDCLASS wc = {}; ··· 174 186 case WM_LBUTTONDOWN: { 175 187 int mouseX = LOWORD(lParam); 176 188 int mouseY = HIWORD(lParam); 177 - 189 + 178 190 // Check if clicking on tuning dial 179 191 if (IsPointInCircle(mouseX, mouseY, 150, 200, 60)) { 180 192 g_radio.isDraggingDial = 1; ··· 227 239 return 0; 228 240 } 229 241 242 + case WM_KEYDOWN: { 243 + switch (wParam) { 244 + case VK_UP: { 245 + // Increase frequency by 0.1 MHz (fine tuning) 246 + g_radio.frequency += 0.1f; 247 + if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f; 248 + 249 + // Update signal strength for new frequency 250 + RadioStation* station = FindNearestStation(g_radio.frequency); 251 + if (station) { 252 + g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f); 253 + if (g_radio.signalStrength > 50 && station != g_audio.currentStation) { 254 + StopBassStreaming(); 255 + StartBassStreaming(station); 256 + } 257 + } else { 258 + g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency)); 259 + StopBassStreaming(); 260 + } 261 + 262 + if (g_radio.signalStrength < 0) g_radio.signalStrength = 0; 263 + if (g_radio.signalStrength > 100) g_radio.signalStrength = 100; 264 + 265 + InvalidateRect(hwnd, NULL, TRUE); 266 + break; 267 + } 268 + 269 + case VK_DOWN: { 270 + // Decrease frequency by 0.1 MHz (fine tuning) 271 + g_radio.frequency -= 0.1f; 272 + if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f; 273 + 274 + // Update signal strength for new frequency 275 + RadioStation* station = FindNearestStation(g_radio.frequency); 276 + if (station) { 277 + g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f); 278 + if (g_radio.signalStrength > 50 && station != g_audio.currentStation) { 279 + StopBassStreaming(); 280 + StartBassStreaming(station); 281 + } 282 + } else { 283 + g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency)); 284 + StopBassStreaming(); 285 + } 286 + 287 + if (g_radio.signalStrength < 0) g_radio.signalStrength = 0; 288 + if (g_radio.signalStrength > 100) g_radio.signalStrength = 100; 289 + 290 + InvalidateRect(hwnd, NULL, TRUE); 291 + break; 292 + } 293 + 294 + case VK_RIGHT: { 295 + // Increase frequency by 1.0 MHz (coarse tuning) 296 + g_radio.frequency += 1.0f; 297 + if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f; 298 + 299 + // Update signal strength for new frequency 300 + RadioStation* station = FindNearestStation(g_radio.frequency); 301 + if (station) { 302 + g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f); 303 + if (g_radio.signalStrength > 50 && station != g_audio.currentStation) { 304 + StopBassStreaming(); 305 + StartBassStreaming(station); 306 + } 307 + } else { 308 + g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency)); 309 + StopBassStreaming(); 310 + } 311 + 312 + if (g_radio.signalStrength < 0) g_radio.signalStrength = 0; 313 + if (g_radio.signalStrength > 100) g_radio.signalStrength = 100; 314 + 315 + InvalidateRect(hwnd, NULL, TRUE); 316 + break; 317 + } 318 + 319 + case VK_LEFT: { 320 + // Decrease frequency by 1.0 MHz (coarse tuning) 321 + g_radio.frequency -= 1.0f; 322 + if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f; 323 + 324 + // Update signal strength for new frequency 325 + RadioStation* station = FindNearestStation(g_radio.frequency); 326 + if (station) { 327 + g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f); 328 + if (g_radio.signalStrength > 50 && station != g_audio.currentStation) { 329 + StopBassStreaming(); 330 + StartBassStreaming(station); 331 + } 332 + } else { 333 + g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency)); 334 + StopBassStreaming(); 335 + } 336 + 337 + if (g_radio.signalStrength < 0) g_radio.signalStrength = 0; 338 + if (g_radio.signalStrength > 100) g_radio.signalStrength = 100; 339 + 340 + InvalidateRect(hwnd, NULL, TRUE); 341 + break; 342 + } 343 + } 344 + return 0; 345 + } 346 + 230 347 case WM_COMMAND: 231 348 switch (LOWORD(wParam)) { 232 349 case ID_ABOUT: { ··· 238 355 "Features:\n" 239 356 "- Realistic tuning interface\n" 240 357 "- Internet radio streaming\n" 241 - "- Authentic static noise"; 358 + "- Authentic static noise\n\n" 359 + "Controls:\n" 360 + "- Drag tuning dial to change frequency\n" 361 + "- UP/DOWN arrows: Fine tuning (0.1 MHz)\n" 362 + "- LEFT/RIGHT arrows: Coarse tuning (1.0 MHz)\n" 363 + "- Click power button to turn on/off\n" 364 + "- Drag volume knob to adjust volume"; 242 365 MessageBox(hwnd, aboutText, "About Shortwave Radio", 243 366 MB_OK | MB_ICONINFORMATION); 244 367 break; ··· 268 391 // Draw panel border (raised effect) 269 392 HPEN lightPen = CreatePen(PS_SOLID, 2, RGB(140, 100, 60)); 270 393 HPEN darkPen = CreatePen(PS_SOLID, 2, RGB(40, 25, 15)); 271 - 394 + 272 395 SelectObject(hdc, lightPen); 273 396 MoveToEx(hdc, panel.left, panel.bottom, NULL); 274 397 LineTo(hdc, panel.left, panel.top); 275 398 LineTo(hdc, panel.right, panel.top); 276 - 399 + 277 400 SelectObject(hdc, darkPen); 278 401 LineTo(hdc, panel.right, panel.bottom); 279 402 LineTo(hdc, panel.left, panel.bottom); 280 - 403 + 281 404 DeleteObject(lightPen); 282 405 DeleteObject(darkPen); 283 406 ··· 303 426 HBRUSH stationBrush = CreateSolidBrush(RGB(0, 0, 0)); 304 427 FillRect(hdc, &stationRect, stationBrush); 305 428 DeleteObject(stationBrush); 306 - 429 + 307 430 HPEN stationPen = CreatePen(PS_SOLID, 1, RGB(100, 100, 100)); 308 431 SelectObject(hdc, stationPen); 309 432 Rectangle(hdc, stationRect.left, stationRect.top, stationRect.right, stationRect.bottom); 310 433 DeleteObject(stationPen); 311 - 434 + 312 435 SetTextColor(hdc, RGB(0, 255, 0)); 313 436 HFONT stationFont = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, 314 437 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, 315 438 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 316 439 DEFAULT_PITCH | FF_SWISS, "Arial"); 317 440 SelectObject(hdc, stationFont); 318 - 441 + 319 442 char stationText[256]; 320 - sprintf(stationText, "%.3f MHz - %s: %s", 443 + sprintf(stationText, "%.3f MHz - %s: %s", 321 444 currentStation->frequency, currentStation->name, currentStation->description); 322 - 445 + 323 446 SetTextAlign(hdc, TA_LEFT); 324 447 TextOut(hdc, stationRect.left + 5, stationRect.top + 5, stationText, strlen(stationText)); 325 - 448 + 326 449 DeleteObject(stationFont); 327 450 } 328 451 ··· 359 482 // Draw frequency text 360 483 char freqText[32]; 361 484 sprintf(freqText, "%.3f MHz", frequency); 362 - 485 + 363 486 SetBkMode(hdc, TRANSPARENT); 364 487 SetTextColor(hdc, RGB(0, 255, 0)); // Green LCD color 365 488 HFONT lcdFont = CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ··· 367 490 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 368 491 FIXED_PITCH | FF_MODERN, "Courier New"); 369 492 SelectObject(hdc, lcdFont); 370 - 493 + 371 494 SetTextAlign(hdc, TA_CENTER); 372 495 TextOut(hdc, x, y - 8, freqText, strlen(freqText)); 373 - 496 + 374 497 DeleteObject(lcdFont); 375 498 } 376 499 ··· 400 523 float angle = (float)i * 3.14159f / 6.0f; 401 524 int markX = x + (int)((radius - 15) * cos(angle)); 402 525 int markY = y + (int)((radius - 15) * sin(angle)); 403 - 526 + 404 527 char mark[8]; 405 528 sprintf(mark, "%d", 10 + i * 2); 406 529 TextOut(hdc, markX, markY - 5, mark, strlen(mark)); ··· 410 533 float angle = (frequency - 10.0f) / 24.0f * 3.14159f; 411 534 int pointerX = x + (int)((radius - 10) * cos(angle)); 412 535 int pointerY = y + (int)((radius - 10) * sin(angle)); 413 - 536 + 414 537 HPEN pointerPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); 415 538 SelectObject(hdc, pointerPen); 416 539 MoveToEx(hdc, x, y, NULL); ··· 437 560 float angle = volume * 3.14159f * 1.5f - 3.14159f * 0.75f; 438 561 int indicatorX = x + (int)((radius - 5) * cos(angle)); 439 562 int indicatorY = y + (int)((radius - 5) * sin(angle)); 440 - 563 + 441 564 HPEN indicatorPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255)); 442 565 SelectObject(hdc, indicatorPen); 443 566 MoveToEx(hdc, x, y, NULL); ··· 462 585 int barWidth = 8; 463 586 int numBars = strength / 10; 464 587 for (int i = 0; i < numBars && i < 10; i++) { 465 - RECT bar = {x + 2 + i * barWidth, y + 2, 588 + RECT bar = {x + 2 + i * barWidth, y + 2, 466 589 x + 2 + (i + 1) * barWidth - 1, y + 18}; 467 - 590 + 468 591 COLORREF barColor; 469 592 if (i < 3) barColor = RGB(0, 255, 0); // Green 470 593 else if (i < 7) barColor = RGB(255, 255, 0); // Yellow 471 594 else barColor = RGB(255, 0, 0); // Red 472 - 595 + 473 596 HBRUSH barBrush = CreateSolidBrush(barColor); 474 597 FillRect(hdc, &bar, barBrush); 475 598 DeleteObject(barBrush); ··· 494 617 if (power) { 495 618 HPEN symbolPen = CreatePen(PS_SOLID, 3, RGB(255, 255, 255)); 496 619 SelectObject(hdc, symbolPen); 497 - 620 + 498 621 // Draw power symbol (circle with line) 499 622 Arc(hdc, x - 8, y - 8, x + 8, y + 8, x + 6, y - 6, x - 6, y - 6); 500 623 MoveToEx(hdc, x, y - 10, NULL); 501 624 LineTo(hdc, x, y - 2); 502 - 625 + 503 626 DeleteObject(symbolPen); 504 627 } 505 628 } ··· 516 639 517 640 void UpdateFrequencyFromMouse(int mouseX, int mouseY) { 518 641 float angle = GetAngleFromPoint(mouseX, mouseY, 150, 200); 519 - 642 + 520 643 // Convert angle to frequency (10-34 MHz range) 521 644 // Normalize angle from -PI to PI to 0-1 range 522 645 float normalizedAngle = (angle + 3.14159f) / (2.0f * 3.14159f); 523 - 646 + 524 647 // Map to frequency range 525 648 g_radio.frequency = 10.0f + normalizedAngle * 24.0f; 526 - 649 + 527 650 // Clamp frequency 528 651 if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f; 529 652 if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f; 530 - 653 + 531 654 // Calculate signal strength based on nearest station 532 655 RadioStation* nearestStation = FindNearestStation(g_radio.frequency); 533 656 if (nearestStation) { 534 657 g_radio.signalStrength = (int)(GetStationSignalStrength(nearestStation, g_radio.frequency) * 100.0f); 658 + 659 + // Start streaming if signal is strong enough and station changed 660 + if (g_radio.signalStrength > 50 && nearestStation != g_audio.currentStation) { 661 + StopBassStreaming(); 662 + StartBassStreaming(nearestStation); 663 + } 535 664 } else { 536 665 g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency)); 666 + StopBassStreaming(); 537 667 } 538 - 668 + 539 669 if (g_radio.signalStrength < 0) g_radio.signalStrength = 0; 540 670 if (g_radio.signalStrength > 100) g_radio.signalStrength = 100; 541 671 } 542 672 543 673 void UpdateVolumeFromMouse(int mouseX, int mouseY) { 544 674 float angle = GetAngleFromPoint(mouseX, mouseY, 350, 200); 545 - 675 + 546 676 // Convert angle to volume (0-1 range) 547 677 // Map from -135 degrees to +135 degrees 548 678 float normalizedAngle = (angle + 3.14159f * 0.75f) / (3.14159f * 1.5f); 549 - 679 + 550 680 g_radio.volume = normalizedAngle; 551 - 681 + 552 682 // Clamp volume 553 683 if (g_radio.volume < 0.0f) g_radio.volume = 0.0f; 554 684 if (g_radio.volume > 1.0f) g_radio.volume = 1.0f; 555 685 } 556 686 557 687 int InitializeAudio() { 558 - WAVEFORMATEX waveFormat; 559 - waveFormat.wFormatTag = WAVE_FORMAT_PCM; 560 - waveFormat.nChannels = CHANNELS; 561 - waveFormat.nSamplesPerSec = SAMPLE_RATE; 562 - waveFormat.wBitsPerSample = BITS_PER_SAMPLE; 563 - waveFormat.nBlockAlign = (waveFormat.nChannels * waveFormat.wBitsPerSample) / 8; 564 - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; 565 - waveFormat.cbSize = 0; 566 - 567 - MMRESULT result = waveOutOpen(&g_audio.hWaveOut, WAVE_MAPPER, &waveFormat, 568 - (DWORD_PTR)WaveOutProc, 0, CALLBACK_FUNCTION); 688 + // Initialize BASS with more detailed error reporting 689 + printf("Initializing BASS audio system...\n"); 569 690 570 - if (result != MMSYSERR_NOERROR) { 571 - return -1; 572 - } 573 - 574 - // Initialize audio buffers 575 - for (int i = 0; i < NUM_BUFFERS; i++) { 576 - memset(&g_audio.waveHeaders[i], 0, sizeof(WAVEHDR)); 577 - g_audio.waveHeaders[i].lpData = (LPSTR)g_audio.audioBuffers[i]; 578 - g_audio.waveHeaders[i].dwBufferLength = BUFFER_SIZE * sizeof(short); 579 - g_audio.waveHeaders[i].dwFlags = 0; 691 + if (!BASS_Init(-1, 44100, 0, 0, NULL)) { 692 + DWORD error = BASS_ErrorGetCode(); 693 + printf("BASS initialization failed (Error: %lu)\n", error); 580 694 581 - result = waveOutPrepareHeader(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR)); 582 - if (result != MMSYSERR_NOERROR) { 695 + // Try alternative initialization methods 696 + printf("Trying alternative audio device...\n"); 697 + if (!BASS_Init(0, 44100, 0, 0, NULL)) { 698 + error = BASS_ErrorGetCode(); 699 + printf("Alternative BASS init also failed (Error: %lu)\n", error); 700 + printf("BASS Error meanings:\n"); 701 + printf(" 1 = BASS_ERROR_MEM (memory error)\n"); 702 + printf(" 2 = BASS_ERROR_FILEOPEN (file/URL error)\n"); 703 + printf(" 3 = BASS_ERROR_DRIVER (no audio driver)\n"); 704 + printf(" 8 = BASS_ERROR_ALREADY (already initialized)\n"); 705 + printf(" 14 = BASS_ERROR_DEVICE (invalid device)\n"); 583 706 return -1; 584 707 } 585 708 } 586 - 587 - g_audio.currentBuffer = 0; 709 + 710 + printf("BASS initialized successfully\n"); 711 + 712 + // Get BASS version info 713 + DWORD version = BASS_GetVersion(); 714 + printf("BASS version: %d.%d.%d.%d\n", 715 + HIBYTE(HIWORD(version)), LOBYTE(HIWORD(version)), 716 + HIBYTE(LOWORD(version)), LOBYTE(LOWORD(version))); 717 + 718 + g_audio.currentStream = 0; 719 + g_audio.staticStream = 0; 588 720 g_audio.isPlaying = 0; 589 - g_audio.staticVolume = 0.3f; 721 + g_audio.staticVolume = 0.8f; 590 722 g_audio.radioVolume = 0.0f; 723 + g_audio.currentStation = NULL; 591 724 592 725 return 0; 593 726 } 594 727 595 728 void CleanupAudio() { 596 - if (g_audio.hWaveOut) { 597 - waveOutReset(g_audio.hWaveOut); 598 - 599 - for (int i = 0; i < NUM_BUFFERS; i++) { 600 - waveOutUnprepareHeader(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR)); 601 - } 602 - 603 - waveOutClose(g_audio.hWaveOut); 604 - g_audio.hWaveOut = NULL; 605 - } 606 - } 607 - 608 - void GenerateStaticBuffer(short* buffer, int size) { 609 - for (int i = 0; i < size; i++) { 610 - // Generate white noise 611 - float noise = ((float)rand() / RAND_MAX) * 2.0f - 1.0f; 612 - 613 - // Apply volume and convert to 16-bit 614 - float volume = g_audio.staticVolume * g_radio.volume; 615 - buffer[i] = (short)(noise * volume * 32767.0f); 616 - } 617 - } 618 - 619 - void FillAudioBuffer(short* buffer, int size) { 620 - // Only generate audio if radio is powered on 621 - if (!g_radio.power) { 622 - memset(buffer, 0, size * sizeof(short)); 623 - return; 624 - } 729 + StopBassStreaming(); 625 730 626 - // Generate static 627 - GenerateStaticBuffer(buffer, size); 628 - 629 - // Find nearest station and mix in signal 630 - RadioStation* station = FindNearestStation(g_radio.frequency); 631 - if (station && g_radio.signalStrength > 20) { 632 - float signalStrength = GetStationSignalStrength(station, g_radio.frequency); 633 - float radioVolume = signalStrength * g_radio.volume * 0.7f; 634 - 635 - for (int i = 0; i < size; i++) { 636 - // Generate different tones for different stations 637 - float time = (float)i / SAMPLE_RATE; 638 - float tone1 = sin(2.0f * 3.14159f * (station->frequency * 50.0f) * time); 639 - float tone2 = sin(2.0f * 3.14159f * (station->frequency * 75.0f) * time) * 0.5f; 640 - float tone = (tone1 + tone2) * 0.5f; 641 - 642 - // Add some modulation to simulate voice/music 643 - float modulation = sin(2.0f * 3.14159f * 3.0f * time) * 0.3f + 0.7f; 644 - tone *= modulation; 645 - 646 - // Mix tone with existing static 647 - float mixed = (float)buffer[i] / 32767.0f; 648 - mixed = mixed * (1.0f - radioVolume) + tone * radioVolume; 649 - 650 - buffer[i] = (short)(mixed * 32767.0f); 651 - } 652 - } 653 - } 654 - 655 - void CALLBACK WaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, 656 - DWORD_PTR dwParam1, DWORD_PTR dwParam2) { 657 - if (uMsg == WOM_DONE && g_audio.isPlaying) { 658 - WAVEHDR* waveHeader = (WAVEHDR*)dwParam1; 659 - 660 - // Refill the buffer 661 - FillAudioBuffer((short*)waveHeader->lpData, BUFFER_SIZE); 662 - 663 - // Queue the buffer for playback 664 - waveOutWrite(g_audio.hWaveOut, waveHeader, sizeof(WAVEHDR)); 665 - } 731 + // Free BASS 732 + BASS_Free(); 733 + printf("BASS cleaned up\n"); 666 734 } 667 735 668 736 void StartAudio() { 669 737 if (!g_audio.isPlaying) { 670 738 g_audio.isPlaying = 1; 671 - 672 - // Fill and queue all buffers 673 - for (int i = 0; i < NUM_BUFFERS; i++) { 674 - FillAudioBuffer(g_audio.audioBuffers[i], BUFFER_SIZE); 675 - waveOutWrite(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR)); 676 - } 739 + printf("Audio started\n"); 677 740 } 678 741 } 679 742 680 743 void StopAudio() { 681 744 if (g_audio.isPlaying) { 682 745 g_audio.isPlaying = 0; 683 - waveOutReset(g_audio.hWaveOut); 746 + StopBassStreaming(); 747 + printf("Audio stopped\n"); 684 748 } 685 749 } 686 750 687 751 RadioStation* FindNearestStation(float frequency) { 688 752 RadioStation* nearest = NULL; 689 753 float minDistance = 999.0f; 690 - 754 + 691 755 for (int i = 0; i < NUM_STATIONS; i++) { 692 756 float distance = fabs(g_stations[i].frequency - frequency); 693 757 if (distance < minDistance) { ··· 695 759 nearest = &g_stations[i]; 696 760 } 697 761 } 698 - 762 + 699 763 // Only return station if we're close enough (within 0.5 MHz) 700 764 if (minDistance <= 0.5f) { 701 765 return nearest; 702 766 } 703 - 767 + 704 768 return NULL; 705 769 } 706 770 707 771 float GetStationSignalStrength(RadioStation* station, float currentFreq) { 708 772 if (!station) return 0.0f; 709 - 773 + 710 774 float distance = fabs(station->frequency - currentFreq); 711 - 775 + 712 776 // Signal strength drops off with distance from exact frequency 713 777 if (distance < 0.05f) { 714 778 return 0.9f; // Very strong signal ··· 719 783 } else if (distance < 0.5f) { 720 784 return 0.2f; // Weak signal 721 785 } 722 - 786 + 723 787 return 0.0f; // No signal 724 788 } 789 + 790 + int StartBassStreaming(RadioStation* station) { 791 + if (!station) { 792 + printf("StartBassStreaming failed: no station\n"); 793 + return 0; 794 + } 795 + 796 + StopBassStreaming(); 797 + 798 + printf("Attempting to stream: %s at %s\n", station->name, station->streamUrl); 799 + 800 + // Check if BASS is initialized 801 + if (!BASS_GetVersion()) { 802 + printf("BASS not initialized - cannot stream\n"); 803 + return 0; 804 + } 805 + 806 + // Create BASS stream from URL with more options 807 + printf("Creating BASS stream...\n"); 808 + g_audio.currentStream = BASS_StreamCreateURL(station->streamUrl, 0, 809 + BASS_STREAM_BLOCK | BASS_STREAM_STATUS | BASS_STREAM_AUTOFREE, NULL, 0); 810 + 811 + if (g_audio.currentStream) { 812 + printf("Successfully connected to stream: %s\n", station->name); 813 + 814 + // Get stream info 815 + BASS_CHANNELINFO info; 816 + if (BASS_ChannelGetInfo(g_audio.currentStream, &info)) { 817 + printf("Stream info: %lu Hz, %lu channels, type=%lu\n", 818 + info.freq, info.chans, info.ctype); 819 + } 820 + 821 + // Set volume based on signal strength and radio volume 822 + float volume = g_radio.volume * (g_radio.signalStrength / 100.0f); 823 + BASS_ChannelSetAttribute(g_audio.currentStream, BASS_ATTRIB_VOL, volume); 824 + printf("Set volume to: %.2f\n", volume); 825 + 826 + // Start playing 827 + if (BASS_ChannelPlay(g_audio.currentStream, FALSE)) { 828 + printf("Stream playback started\n"); 829 + } else { 830 + DWORD error = BASS_ErrorGetCode(); 831 + printf("Failed to start playback (BASS Error: %lu)\n", error); 832 + } 833 + 834 + g_audio.currentStation = station; 835 + return 1; 836 + } else { 837 + DWORD error = BASS_ErrorGetCode(); 838 + printf("Failed to connect to stream: %s (BASS Error: %lu)\n", station->name, error); 839 + printf("BASS Error meanings:\n"); 840 + printf(" 1 = BASS_ERROR_MEM (out of memory)\n"); 841 + printf(" 2 = BASS_ERROR_FILEOPEN (file/URL cannot be opened)\n"); 842 + printf(" 3 = BASS_ERROR_DRIVER (no audio driver available)\n"); 843 + printf(" 6 = BASS_ERROR_FORMAT (unsupported format)\n"); 844 + printf(" 7 = BASS_ERROR_POSITION (invalid position)\n"); 845 + printf(" 14 = BASS_ERROR_DEVICE (invalid device)\n"); 846 + printf(" 21 = BASS_ERROR_TIMEOUT (connection timeout)\n"); 847 + printf(" 41 = BASS_ERROR_SSL (SSL/HTTPS not supported)\n"); 848 + } 849 + 850 + return 0; 851 + } 852 + 853 + void StopBassStreaming() { 854 + if (g_audio.currentStream) { 855 + BASS_StreamFree(g_audio.currentStream); 856 + g_audio.currentStream = 0; 857 + printf("Stopped streaming\n"); 858 + } 859 + 860 + g_audio.currentStation = NULL; 861 + } 862 +