···11-# Shortwave Development Guide
11+# Shortwave Radio Development Guide
2233## Project Overview
44- **Language**: C-style C++ for Win32 API compatibility
55- **Target Platform**: Windows XP
66-- **Primary Goal**: Simple Win32 Application
66+- **Primary Goal**: Vintage Shortwave Radio Tuner Application
7788## Build & Development Commands
99- **Build**: `nix build`
1010- - Compiles Win32 application
1010+ - Compiles Shortwave Radio application
1111- **Dev Setup**: `setup-dev`
1212 - Generates `compile_commands.json`
1313- **Deploy**: `deploy-to-xp`
···1515- **Debugging**: Use Visual Studio or WinDbg
1616- **Testing**: Manual testing on Windows XP
17171818+## Important: Nix Build System
1919+- **CRITICAL**: Nix only includes files tracked in git
2020+- **Always run**: `git add .` after adding new files/libraries
2121+- **BASS Integration**: Files in `libs/` directory must be committed to git
2222+- **Build fails?** Check if new files are added to git with `git status`
2323+1824## Code Style Guidelines
19252026### Formatting
···2430- Avoid trailing whitespace
25312632### Naming Conventions
2727-- Functions: `PascalCase` (e.g., `QRCode_Init`)
3333+- Functions: `PascalCase` (e.g., `StartBassStreaming`)
2834- Constants/Macros: `UPPER_SNAKE_CASE` (e.g., `ID_ABOUT`)
2929-- Global Variables: `g_` prefix (e.g., `g_qrCode`)
3535+- Global Variables: `g_` prefix (e.g., `g_radio`)
3036- Avoid abbreviations
31373238### Types & Memory
···4147- Always check Win32 API return values
4248- Validate pointers before use
4349- Use `NULL` checks
4444-- Log errors to file/console
5050+- Log errors to console/file
4551- Graceful failure modes
46524753### Imports & Headers
···5965- Prioritize Win32 API compatibility
6066- Minimize external dependencies
6167- Focus on performance and low resource usage
6262-- Test thoroughly on target Windows XP environment6868+- Test thoroughly on target Windows XP environment
6969+7070+## Radio Features
7171+- Vintage shortwave radio interface
7272+- Internet radio streaming capability
7373+- Realistic tuning and signal simulation
7474+- Keyboard and mouse controls
7575+- Debug console for troubleshooting
+36-39
flake.nix
···11{
22- description = "Win32 Hello World App with About dropdown";
22+ description = "Shortwave Radio Tuner - Win32 App for Windows XP";
3344 inputs = {
55 nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05";
···40404141 buildPhase = ''
4242 export LDFLAGS="-static -static-libgcc -static-libstdc++"
4343+4444+ # Check if BASS files exist in libs directory
4545+ if [ -f "libs/bass.h" ] && [ -f "libs/bass.lib" ]; then
4646+ echo "BASS files found in libs/ - building with audio integration"
4747+ else
4848+ echo "BASS files not found in libs/ - building without audio integration"
4949+ # Disable BASS in the source
5050+ sed -i 's|#include "libs/bass.h"|// #include "libs/bass.h"|' main.cpp
5151+ sed -i 's|libs/bass.lib||' CMakeLists.txt
5252+ fi
5353+4354 cmake -DCMAKE_BUILD_TYPE=Release \
4455 -DCMAKE_SYSTEM_NAME=Windows \
4556 -DCMAKE_C_COMPILER=$CC \
···50615162 installPhase = ''
5263 mkdir -p $out/bin
5353- cp HelloWorld.exe $out/bin/
6464+ cp Shortwave.exe $out/bin/
5465 '';
5566 };
5667···5869 XP_DIR="$HOME/Documents/xp-drive"
5970 mkdir -p "$XP_DIR"
60716161- # Handle Windows file locking by using a temporary name first
6262- TEMP_NAME="HelloWorld_new.exe"
6363- OLD_NAME="HelloWorld_old.exe"
6464- FINAL_NAME="HelloWorld.exe"
7272+ echo "Deploying Shortwave Radio to $XP_DIR..."
65736666- echo "Deploying to $XP_DIR..."
7474+ # Copy executable with force overwrite
7575+ if cp -f ${self'.packages.shortwave}/bin/Shortwave.exe "$XP_DIR/"; then
7676+ echo "✓ Copied Shortwave.exe"
7777+ else
7878+ echo "✗ Failed to copy Shortwave.exe"
7979+ exit 1
8080+ fi
67816868- # Copy to temporary name first
6969- if cp ${self'.packages.shortwave}/bin/HelloWorld.exe "$XP_DIR/$TEMP_NAME"; then
7070- echo "Copied new version as $TEMP_NAME"
7171-7272- # If the original exists, try to rename it
7373- if [ -f "$XP_DIR/$FINAL_NAME" ]; then
7474- if mv "$XP_DIR/$FINAL_NAME" "$XP_DIR/$OLD_NAME" 2>/dev/null; then
7575- echo "Backed up old version as $OLD_NAME"
7676- else
7777- echo "Warning: Could not backup old version (file may be in use)"
7878- echo "Close the application on XP and try again, or manually rename files"
7979- echo "New version is available as: $TEMP_NAME"
8080- exit 1
8181- fi
8282- fi
8383-8484- # Move temp to final name
8585- if mv "$XP_DIR/$TEMP_NAME" "$XP_DIR/$FINAL_NAME"; then
8686- echo "Deployed HelloWorld.exe successfully"
8787-8888- # Clean up old backup if it exists
8989- if [ -f "$XP_DIR/$OLD_NAME" ]; then
9090- rm -f "$XP_DIR/$OLD_NAME" 2>/dev/null || echo "(Old backup file remains)"
9191- fi
8282+ # Copy BASS DLL from libs directory
8383+ if [ -f libs/bass.dll ]; then
8484+ if cp -f libs/bass.dll "$XP_DIR/"; then
8585+ echo "✓ Copied bass.dll"
9286 else
9393- echo "Failed to finalize deployment"
8787+ echo "✗ Failed to copy bass.dll"
9488 exit 1
9589 fi
9690 else
9797- echo "Failed to copy new version"
9898- exit 1
9191+ echo "⚠ bass.dll not found in libs/ directory - BASS audio will not work"
9992 fi
9393+9494+ echo "🎵 Shortwave Radio deployed successfully!"
9595+ echo "Files in XP directory:"
9696+ ls -la "$XP_DIR"/*.{exe,dll} 2>/dev/null || echo "No files found"
10097 '';
1019810299 setup-dev = pkgs.writeShellScriptBin "setup-dev" ''
103103- echo "Setting up development environment for Zed..."
100100+ echo "Setting up development environment for Shortwave Radio..."
104101105102 # Get dynamic paths from nix packages
106103 GCC_BASE="${pkgs.pkgsCross.mingw32.buildPackages.gcc}/i686-w64-mingw32"
···146143 EOF
147144148145 echo "Generated .clangd config and compile_commands.json with include paths"
149149- echo "Development environment ready for Zed editor"
146146+ echo "Development environment ready for Shortwave Radio development"
150147 echo "Include paths:"
151148 echo " C standard library: $SYS_INCLUDE"
152149 echo " MinGW headers: $MINGW_MAIN_INCLUDE"
···166163 ];
167164168165 shellHook = ''
169169- echo "Win32 development environment loaded"
166166+ echo "Shortwave Radio development environment loaded"
170167 echo "Available commands:"
171171- echo " nix build - Build the application"
168168+ echo " nix build - Build the Shortwave Radio application"
172169 echo " deploy-to-xp - Deploy to XP VM folder"
173170 echo ""
174171 echo "Setting up development environment..."
···216213 EOF
217214218215 echo "✓ Generated .clangd config and compile_commands.json with include paths"
219219- echo "✓ Development environment ready for Zed editor"
216216+ echo "✓ Development environment ready for Shortwave Radio development"
220217 '';
221218 };
222219 };
libs/bass.dll
This is a binary file and will not be displayed.
+1149
libs/bass.h
···11+/*
22+ BASS 2.4 C/C++ header file
33+ Copyright (c) 1999-2022 Un4seen Developments Ltd.
44+55+ See the BASS.CHM file for more detailed documentation
66+*/
77+88+#ifndef BASS_H
99+#define BASS_H
1010+1111+#ifdef _WIN32
1212+#ifdef WINAPI_FAMILY
1313+#include <winapifamily.h>
1414+#endif
1515+#include <wtypes.h>
1616+typedef unsigned __int64 QWORD;
1717+#else
1818+#include <stdint.h>
1919+#define WINAPI
2020+#define CALLBACK
2121+typedef uint8_t BYTE;
2222+typedef uint16_t WORD;
2323+typedef uint32_t DWORD;
2424+typedef uint64_t QWORD;
2525+#ifdef __OBJC__
2626+typedef int BOOL32;
2727+#define BOOL BOOL32 // override objc's BOOL
2828+#else
2929+typedef int BOOL;
3030+#endif
3131+#ifndef TRUE
3232+#define TRUE 1
3333+#define FALSE 0
3434+#endif
3535+#define LOBYTE(a) (BYTE)(a)
3636+#define HIBYTE(a) (BYTE)((a)>>8)
3737+#define LOWORD(a) (WORD)(a)
3838+#define HIWORD(a) (WORD)((a)>>16)
3939+#define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8))
4040+#define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16))
4141+#endif
4242+4343+#ifdef __cplusplus
4444+extern "C" {
4545+#endif
4646+4747+#define BASSVERSION 0x204 // API version
4848+#define BASSVERSIONTEXT "2.4"
4949+5050+#ifndef BASSDEF
5151+#define BASSDEF(f) WINAPI f
5252+#else
5353+#define NOBASSOVERLOADS
5454+#endif
5555+5656+typedef DWORD HMUSIC; // MOD music handle
5757+typedef DWORD HSAMPLE; // sample handle
5858+typedef DWORD HCHANNEL; // sample playback handle
5959+typedef DWORD HSTREAM; // sample stream handle
6060+typedef DWORD HRECORD; // recording handle
6161+typedef DWORD HSYNC; // synchronizer handle
6262+typedef DWORD HDSP; // DSP handle
6363+typedef DWORD HFX; // effect handle
6464+typedef DWORD HPLUGIN; // plugin handle
6565+6666+// Error codes returned by BASS_ErrorGetCode
6767+#define BASS_OK 0 // all is OK
6868+#define BASS_ERROR_MEM 1 // memory error
6969+#define BASS_ERROR_FILEOPEN 2 // can't open the file
7070+#define BASS_ERROR_DRIVER 3 // can't find a free/valid driver
7171+#define BASS_ERROR_BUFLOST 4 // the sample buffer was lost
7272+#define BASS_ERROR_HANDLE 5 // invalid handle
7373+#define BASS_ERROR_FORMAT 6 // unsupported sample format
7474+#define BASS_ERROR_POSITION 7 // invalid position
7575+#define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called
7676+#define BASS_ERROR_START 9 // BASS_Start has not been successfully called
7777+#define BASS_ERROR_SSL 10 // SSL/HTTPS support isn't available
7878+#define BASS_ERROR_REINIT 11 // device needs to be reinitialized
7979+#define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever
8080+#define BASS_ERROR_NOTAUDIO 17 // file does not contain audio
8181+#define BASS_ERROR_NOCHAN 18 // can't get a free channel
8282+#define BASS_ERROR_ILLTYPE 19 // an illegal type was specified
8383+#define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified
8484+#define BASS_ERROR_NO3D 21 // no 3D support
8585+#define BASS_ERROR_NOEAX 22 // no EAX support
8686+#define BASS_ERROR_DEVICE 23 // illegal device number
8787+#define BASS_ERROR_NOPLAY 24 // not playing
8888+#define BASS_ERROR_FREQ 25 // illegal sample rate
8989+#define BASS_ERROR_NOTFILE 27 // the stream is not a file stream
9090+#define BASS_ERROR_NOHW 29 // no hardware voices available
9191+#define BASS_ERROR_EMPTY 31 // the file has no sample data
9292+#define BASS_ERROR_NONET 32 // no internet connection could be opened
9393+#define BASS_ERROR_CREATE 33 // couldn't create the file
9494+#define BASS_ERROR_NOFX 34 // effects are not available
9595+#define BASS_ERROR_NOTAVAIL 37 // requested data/action is not available
9696+#define BASS_ERROR_DECODE 38 // the channel is/isn't a "decoding channel"
9797+#define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed
9898+#define BASS_ERROR_TIMEOUT 40 // connection timedout
9999+#define BASS_ERROR_FILEFORM 41 // unsupported file format
100100+#define BASS_ERROR_SPEAKER 42 // unavailable speaker
101101+#define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons)
102102+#define BASS_ERROR_CODEC 44 // codec is not available/supported
103103+#define BASS_ERROR_ENDED 45 // the channel/file has ended
104104+#define BASS_ERROR_BUSY 46 // the device is busy
105105+#define BASS_ERROR_UNSTREAMABLE 47 // unstreamable file
106106+#define BASS_ERROR_PROTOCOL 48 // unsupported protocol
107107+#define BASS_ERROR_DENIED 49 // access denied
108108+#define BASS_ERROR_UNKNOWN -1 // some other mystery problem
109109+110110+// BASS_SetConfig options
111111+#define BASS_CONFIG_BUFFER 0
112112+#define BASS_CONFIG_UPDATEPERIOD 1
113113+#define BASS_CONFIG_GVOL_SAMPLE 4
114114+#define BASS_CONFIG_GVOL_STREAM 5
115115+#define BASS_CONFIG_GVOL_MUSIC 6
116116+#define BASS_CONFIG_CURVE_VOL 7
117117+#define BASS_CONFIG_CURVE_PAN 8
118118+#define BASS_CONFIG_FLOATDSP 9
119119+#define BASS_CONFIG_3DALGORITHM 10
120120+#define BASS_CONFIG_NET_TIMEOUT 11
121121+#define BASS_CONFIG_NET_BUFFER 12
122122+#define BASS_CONFIG_PAUSE_NOPLAY 13
123123+#define BASS_CONFIG_NET_PREBUF 15
124124+#define BASS_CONFIG_NET_PASSIVE 18
125125+#define BASS_CONFIG_REC_BUFFER 19
126126+#define BASS_CONFIG_NET_PLAYLIST 21
127127+#define BASS_CONFIG_MUSIC_VIRTUAL 22
128128+#define BASS_CONFIG_VERIFY 23
129129+#define BASS_CONFIG_UPDATETHREADS 24
130130+#define BASS_CONFIG_DEV_BUFFER 27
131131+#define BASS_CONFIG_REC_LOOPBACK 28
132132+#define BASS_CONFIG_VISTA_TRUEPOS 30
133133+#define BASS_CONFIG_IOS_SESSION 34
134134+#define BASS_CONFIG_IOS_MIXAUDIO 34
135135+#define BASS_CONFIG_DEV_DEFAULT 36
136136+#define BASS_CONFIG_NET_READTIMEOUT 37
137137+#define BASS_CONFIG_VISTA_SPEAKERS 38
138138+#define BASS_CONFIG_IOS_SPEAKER 39
139139+#define BASS_CONFIG_MF_DISABLE 40
140140+#define BASS_CONFIG_HANDLES 41
141141+#define BASS_CONFIG_UNICODE 42
142142+#define BASS_CONFIG_SRC 43
143143+#define BASS_CONFIG_SRC_SAMPLE 44
144144+#define BASS_CONFIG_ASYNCFILE_BUFFER 45
145145+#define BASS_CONFIG_OGG_PRESCAN 47
146146+#define BASS_CONFIG_MF_VIDEO 48
147147+#define BASS_CONFIG_AIRPLAY 49
148148+#define BASS_CONFIG_DEV_NONSTOP 50
149149+#define BASS_CONFIG_IOS_NOCATEGORY 51
150150+#define BASS_CONFIG_VERIFY_NET 52
151151+#define BASS_CONFIG_DEV_PERIOD 53
152152+#define BASS_CONFIG_FLOAT 54
153153+#define BASS_CONFIG_NET_SEEK 56
154154+#define BASS_CONFIG_AM_DISABLE 58
155155+#define BASS_CONFIG_NET_PLAYLIST_DEPTH 59
156156+#define BASS_CONFIG_NET_PREBUF_WAIT 60
157157+#define BASS_CONFIG_ANDROID_SESSIONID 62
158158+#define BASS_CONFIG_WASAPI_PERSIST 65
159159+#define BASS_CONFIG_REC_WASAPI 66
160160+#define BASS_CONFIG_ANDROID_AAUDIO 67
161161+#define BASS_CONFIG_SAMPLE_ONEHANDLE 69
162162+#define BASS_CONFIG_NET_META 71
163163+#define BASS_CONFIG_NET_RESTRATE 72
164164+#define BASS_CONFIG_REC_DEFAULT 73
165165+#define BASS_CONFIG_NORAMP 74
166166+167167+// BASS_SetConfigPtr options
168168+#define BASS_CONFIG_NET_AGENT 16
169169+#define BASS_CONFIG_NET_PROXY 17
170170+#define BASS_CONFIG_IOS_NOTIFY 46
171171+#define BASS_CONFIG_ANDROID_JAVAVM 63
172172+#define BASS_CONFIG_LIBSSL 64
173173+#define BASS_CONFIG_FILENAME 75
174174+175175+#define BASS_CONFIG_THREAD 0x40000000 // flag: thread-specific setting
176176+177177+// BASS_CONFIG_IOS_SESSION flags
178178+#define BASS_IOS_SESSION_MIX 1
179179+#define BASS_IOS_SESSION_DUCK 2
180180+#define BASS_IOS_SESSION_AMBIENT 4
181181+#define BASS_IOS_SESSION_SPEAKER 8
182182+#define BASS_IOS_SESSION_DISABLE 16
183183+#define BASS_IOS_SESSION_DEACTIVATE 32
184184+#define BASS_IOS_SESSION_AIRPLAY 64
185185+#define BASS_IOS_SESSION_BTHFP 128
186186+#define BASS_IOS_SESSION_BTA2DP 0x100
187187+188188+// BASS_Init flags
189189+#define BASS_DEVICE_8BITS 1 // unused
190190+#define BASS_DEVICE_MONO 2 // mono
191191+#define BASS_DEVICE_3D 4 // unused
192192+#define BASS_DEVICE_16BITS 8 // limit output to 16-bit
193193+#define BASS_DEVICE_REINIT 128 // reinitialize
194194+#define BASS_DEVICE_LATENCY 0x100 // unused
195195+#define BASS_DEVICE_CPSPEAKERS 0x400 // unused
196196+#define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment
197197+#define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement
198198+#define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin
199199+#define BASS_DEVICE_FREQ 0x4000 // set device sample rate
200200+#define BASS_DEVICE_STEREO 0x8000 // limit output to stereo
201201+#define BASS_DEVICE_HOG 0x10000 // hog/exclusive mode
202202+#define BASS_DEVICE_AUDIOTRACK 0x20000 // use AudioTrack output
203203+#define BASS_DEVICE_DSOUND 0x40000 // use DirectSound output
204204+#define BASS_DEVICE_SOFTWARE 0x80000 // disable hardware/fastpath output
205205+206206+// DirectSound interfaces (for use with BASS_GetDSoundObject)
207207+#define BASS_OBJECT_DS 1 // IDirectSound
208208+#define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener
209209+210210+// Device info structure
211211+typedef struct {
212212+#if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
213213+ const wchar_t *name; // description
214214+ const wchar_t *driver; // driver
215215+#else
216216+ const char *name; // description
217217+ const char *driver; // driver
218218+#endif
219219+ DWORD flags;
220220+} BASS_DEVICEINFO;
221221+222222+// BASS_DEVICEINFO flags
223223+#define BASS_DEVICE_ENABLED 1
224224+#define BASS_DEVICE_DEFAULT 2
225225+#define BASS_DEVICE_INIT 4
226226+#define BASS_DEVICE_LOOPBACK 8
227227+#define BASS_DEVICE_DEFAULTCOM 128
228228+229229+#define BASS_DEVICE_TYPE_MASK 0xff000000
230230+#define BASS_DEVICE_TYPE_NETWORK 0x01000000
231231+#define BASS_DEVICE_TYPE_SPEAKERS 0x02000000
232232+#define BASS_DEVICE_TYPE_LINE 0x03000000
233233+#define BASS_DEVICE_TYPE_HEADPHONES 0x04000000
234234+#define BASS_DEVICE_TYPE_MICROPHONE 0x05000000
235235+#define BASS_DEVICE_TYPE_HEADSET 0x06000000
236236+#define BASS_DEVICE_TYPE_HANDSET 0x07000000
237237+#define BASS_DEVICE_TYPE_DIGITAL 0x08000000
238238+#define BASS_DEVICE_TYPE_SPDIF 0x09000000
239239+#define BASS_DEVICE_TYPE_HDMI 0x0a000000
240240+#define BASS_DEVICE_TYPE_DISPLAYPORT 0x40000000
241241+242242+// BASS_GetDeviceInfo flags
243243+#define BASS_DEVICES_AIRPLAY 0x1000000
244244+245245+typedef struct {
246246+ DWORD flags; // device capabilities (DSCAPS_xxx flags)
247247+ DWORD hwsize; // unused
248248+ DWORD hwfree; // unused
249249+ DWORD freesam; // unused
250250+ DWORD free3d; // unused
251251+ DWORD minrate; // unused
252252+ DWORD maxrate; // unused
253253+ BOOL eax; // unused
254254+ DWORD minbuf; // recommended minimum buffer length in ms
255255+ DWORD dsver; // DirectSound version
256256+ DWORD latency; // average delay (in ms) before start of playback
257257+ DWORD initflags; // BASS_Init "flags" parameter
258258+ DWORD speakers; // number of speakers available
259259+ DWORD freq; // current output rate
260260+} BASS_INFO;
261261+262262+// BASS_INFO flags (from DSOUND.H)
263263+#define DSCAPS_EMULDRIVER 0x00000020 // device does not have hardware DirectSound support
264264+#define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft
265265+266266+#define DSCAPS_HARDWARE 0x80000000 // hardware mixed
267267+268268+// Recording device info structure
269269+typedef struct {
270270+ DWORD flags; // device capabilities (DSCCAPS_xxx flags)
271271+ DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags)
272272+ DWORD inputs; // number of inputs
273273+ BOOL singlein; // TRUE = only 1 input can be set at a time
274274+ DWORD freq; // current input rate
275275+} BASS_RECORDINFO;
276276+277277+// BASS_RECORDINFO flags (from DSOUND.H)
278278+#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does not have hardware DirectSound recording support
279279+#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft
280280+281281+// defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H)
282282+#ifndef WAVE_FORMAT_1M08
283283+#define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */
284284+#define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */
285285+#define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */
286286+#define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */
287287+#define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */
288288+#define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */
289289+#define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */
290290+#define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */
291291+#define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */
292292+#define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */
293293+#define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */
294294+#define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */
295295+#endif
296296+297297+// Sample info structure
298298+typedef struct {
299299+ DWORD freq; // default playback rate
300300+ float volume; // default volume (0-1)
301301+ float pan; // default pan (-1=left, 0=middle, 1=right)
302302+ DWORD flags; // BASS_SAMPLE_xxx flags
303303+ DWORD length; // length (in bytes)
304304+ DWORD max; // maximum simultaneous playbacks
305305+ DWORD origres; // original resolution
306306+ DWORD chans; // number of channels
307307+ DWORD mingap; // minimum gap (ms) between creating channels
308308+ DWORD mode3d; // BASS_3DMODE_xxx mode
309309+ float mindist; // minimum distance
310310+ float maxdist; // maximum distance
311311+ DWORD iangle; // angle of inside projection cone
312312+ DWORD oangle; // angle of outside projection cone
313313+ float outvol; // delta-volume outside the projection cone
314314+ DWORD vam; // unused
315315+ DWORD priority; // unused
316316+} BASS_SAMPLE;
317317+318318+#define BASS_SAMPLE_8BITS 1 // 8 bit
319319+#define BASS_SAMPLE_FLOAT 256 // 32 bit floating-point
320320+#define BASS_SAMPLE_MONO 2 // mono
321321+#define BASS_SAMPLE_LOOP 4 // looped
322322+#define BASS_SAMPLE_3D 8 // 3D functionality
323323+#define BASS_SAMPLE_SOFTWARE 16 // unused
324324+#define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only)
325325+#define BASS_SAMPLE_VAM 64 // unused
326326+#define BASS_SAMPLE_FX 128 // unused
327327+#define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume
328328+#define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing
329329+#define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only)
330330+331331+#define BASS_STREAM_PRESCAN 0x20000 // scan file for accurate seeking and length
332332+#define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stops/ends
333333+#define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file stream
334334+#define BASS_STREAM_BLOCK 0x100000 // download internet file stream in small blocks
335335+#define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode
336336+#define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC
337337+338338+#define BASS_MP3_IGNOREDELAY 0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info
339339+#define BASS_MP3_SETPOS BASS_STREAM_PRESCAN
340340+341341+#define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT
342342+#define BASS_MUSIC_MONO BASS_SAMPLE_MONO
343343+#define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP
344344+#define BASS_MUSIC_3D BASS_SAMPLE_3D
345345+#define BASS_MUSIC_FX BASS_SAMPLE_FX
346346+#define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE
347347+#define BASS_MUSIC_DECODE BASS_STREAM_DECODE
348348+#define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length
349349+#define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN
350350+#define BASS_MUSIC_RAMP 0x200 // normal ramping
351351+#define BASS_MUSIC_RAMPS 0x400 // sensitive ramping
352352+#define BASS_MUSIC_SURROUND 0x800 // surround sound
353353+#define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2)
354354+#define BASS_MUSIC_FT2PAN 0x2000 // apply FastTracker 2 panning to XM files
355355+#define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does
356356+#define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does
357357+#define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing
358358+#define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing
359359+#define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position
360360+#define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position
361361+#define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect
362362+#define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples
363363+364364+// Speaker assignment flags
365365+#define BASS_SPEAKER_FRONT 0x1000000 // front speakers
366366+#define BASS_SPEAKER_REAR 0x2000000 // rear speakers
367367+#define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1)
368368+#define BASS_SPEAKER_SIDE 0x4000000 // side speakers (7.1)
369369+#define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15)
370370+#define BASS_SPEAKER_LEFT 0x10000000 // modifier: left
371371+#define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right
372372+#define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT | BASS_SPEAKER_LEFT
373373+#define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT | BASS_SPEAKER_RIGHT
374374+#define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR | BASS_SPEAKER_LEFT
375375+#define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR | BASS_SPEAKER_RIGHT
376376+#define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE | BASS_SPEAKER_LEFT
377377+#define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE | BASS_SPEAKER_RIGHT
378378+#define BASS_SPEAKER_SIDELEFT BASS_SPEAKER_SIDE | BASS_SPEAKER_LEFT
379379+#define BASS_SPEAKER_SIDERIGHT BASS_SPEAKER_SIDE | BASS_SPEAKER_RIGHT
380380+#define BASS_SPEAKER_REAR2 BASS_SPEAKER_SIDE
381381+#define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_SIDELEFT
382382+#define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_SIDERIGHT
383383+384384+#define BASS_ASYNCFILE 0x40000000 // read file asynchronously
385385+#define BASS_UNICODE 0x80000000 // UTF-16
386386+387387+#define BASS_RECORD_ECHOCANCEL 0x2000
388388+#define BASS_RECORD_AGC 0x4000
389389+#define BASS_RECORD_PAUSE 0x8000 // start recording paused
390390+391391+// DX7 voice allocation & management flags
392392+#define BASS_VAM_HARDWARE 1
393393+#define BASS_VAM_SOFTWARE 2
394394+#define BASS_VAM_TERM_TIME 4
395395+#define BASS_VAM_TERM_DIST 8
396396+#define BASS_VAM_TERM_PRIO 16
397397+398398+// Channel info structure
399399+typedef struct {
400400+ DWORD freq; // default playback rate
401401+ DWORD chans; // channels
402402+ DWORD flags;
403403+ DWORD ctype; // type of channel
404404+ DWORD origres; // original resolution
405405+ HPLUGIN plugin;
406406+ HSAMPLE sample;
407407+ const char *filename;
408408+} BASS_CHANNELINFO;
409409+410410+#define BASS_ORIGRES_FLOAT 0x10000
411411+412412+// BASS_CHANNELINFO types
413413+#define BASS_CTYPE_SAMPLE 1
414414+#define BASS_CTYPE_RECORD 2
415415+#define BASS_CTYPE_STREAM 0x10000
416416+#define BASS_CTYPE_STREAM_VORBIS 0x10002
417417+#define BASS_CTYPE_STREAM_OGG 0x10002
418418+#define BASS_CTYPE_STREAM_MP1 0x10003
419419+#define BASS_CTYPE_STREAM_MP2 0x10004
420420+#define BASS_CTYPE_STREAM_MP3 0x10005
421421+#define BASS_CTYPE_STREAM_AIFF 0x10006
422422+#define BASS_CTYPE_STREAM_CA 0x10007
423423+#define BASS_CTYPE_STREAM_MF 0x10008
424424+#define BASS_CTYPE_STREAM_AM 0x10009
425425+#define BASS_CTYPE_STREAM_SAMPLE 0x1000a
426426+#define BASS_CTYPE_STREAM_DUMMY 0x18000
427427+#define BASS_CTYPE_STREAM_DEVICE 0x18001
428428+#define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag (LOWORD=codec)
429429+#define BASS_CTYPE_STREAM_WAV_PCM 0x50001
430430+#define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003
431431+#define BASS_CTYPE_MUSIC_MOD 0x20000
432432+#define BASS_CTYPE_MUSIC_MTM 0x20001
433433+#define BASS_CTYPE_MUSIC_S3M 0x20002
434434+#define BASS_CTYPE_MUSIC_XM 0x20003
435435+#define BASS_CTYPE_MUSIC_IT 0x20004
436436+#define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag
437437+438438+// BASS_PluginLoad flags
439439+#define BASS_PLUGIN_PROC 1
440440+441441+typedef struct {
442442+ DWORD ctype; // channel type
443443+#if defined(_WIN32_WCE) || (defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
444444+ const wchar_t *name; // format description
445445+ const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...)
446446+#else
447447+ const char *name; // format description
448448+ const char *exts; // file extension filter (*.ext1;*.ext2;etc...)
449449+#endif
450450+} BASS_PLUGINFORM;
451451+452452+typedef struct {
453453+ DWORD version; // version (same form as BASS_GetVersion)
454454+ DWORD formatc; // number of formats
455455+ const BASS_PLUGINFORM *formats; // the array of formats
456456+} BASS_PLUGININFO;
457457+458458+// 3D vector (for 3D positions/velocities/orientations)
459459+typedef struct BASS_3DVECTOR {
460460+#ifdef __cplusplus
461461+ BASS_3DVECTOR() {}
462462+ BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
463463+#endif
464464+ float x; // +=right, -=left
465465+ float y; // +=up, -=down
466466+ float z; // +=front, -=behind
467467+} BASS_3DVECTOR;
468468+469469+// 3D channel modes
470470+#define BASS_3DMODE_NORMAL 0 // normal 3D processing
471471+#define BASS_3DMODE_RELATIVE 1 // position is relative to the listener
472472+#define BASS_3DMODE_OFF 2 // no 3D processing
473473+474474+// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM)
475475+#define BASS_3DALG_DEFAULT 0
476476+#define BASS_3DALG_OFF 1
477477+#define BASS_3DALG_FULL 2
478478+#define BASS_3DALG_LIGHT 3
479479+480480+// BASS_SampleGetChannel flags
481481+#define BASS_SAMCHAN_NEW 1 // get a new playback channel
482482+#define BASS_SAMCHAN_STREAM 2 // create a stream
483483+484484+typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user);
485485+/* User stream callback function.
486486+handle : The stream that needs writing
487487+buffer : Buffer to write the samples in
488488+length : Number of bytes to write
489489+user : The 'user' parameter value given when calling BASS_StreamCreate
490490+RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */
491491+492492+#define BASS_STREAMPROC_END 0x80000000 // end of user stream flag
493493+494494+// Special STREAMPROCs
495495+#define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream
496496+#define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream
497497+#define STREAMPROC_DEVICE (STREAMPROC*)-2 // device mix stream
498498+#define STREAMPROC_DEVICE_3D (STREAMPROC*)-3 // device 3D mix stream
499499+500500+// BASS_StreamCreateFileUser file systems
501501+#define STREAMFILE_NOBUFFER 0
502502+#define STREAMFILE_BUFFER 1
503503+#define STREAMFILE_BUFFERPUSH 2
504504+505505+// User file stream callback functions
506506+typedef void (CALLBACK FILECLOSEPROC)(void *user);
507507+typedef QWORD (CALLBACK FILELENPROC)(void *user);
508508+typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user);
509509+typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user);
510510+511511+typedef struct {
512512+ FILECLOSEPROC *close;
513513+ FILELENPROC *length;
514514+ FILEREADPROC *read;
515515+ FILESEEKPROC *seek;
516516+} BASS_FILEPROCS;
517517+518518+// BASS_StreamPutFileData options
519519+#define BASS_FILEDATA_END 0 // end & close the file
520520+521521+// BASS_StreamGetFilePosition modes
522522+#define BASS_FILEPOS_CURRENT 0
523523+#define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT
524524+#define BASS_FILEPOS_DOWNLOAD 1
525525+#define BASS_FILEPOS_END 2
526526+#define BASS_FILEPOS_START 3
527527+#define BASS_FILEPOS_CONNECTED 4
528528+#define BASS_FILEPOS_BUFFER 5
529529+#define BASS_FILEPOS_SOCKET 6
530530+#define BASS_FILEPOS_ASYNCBUF 7
531531+#define BASS_FILEPOS_SIZE 8
532532+#define BASS_FILEPOS_BUFFERING 9
533533+#define BASS_FILEPOS_AVAILABLE 10
534534+535535+typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user);
536536+/* Internet stream download callback function.
537537+buffer : Buffer containing the downloaded data... NULL=end of download
538538+length : Number of bytes in the buffer
539539+user : The 'user' parameter value given when calling BASS_StreamCreateURL */
540540+541541+// BASS_ChannelSetSync types
542542+#define BASS_SYNC_POS 0
543543+#define BASS_SYNC_END 2
544544+#define BASS_SYNC_META 4
545545+#define BASS_SYNC_SLIDE 5
546546+#define BASS_SYNC_STALL 6
547547+#define BASS_SYNC_DOWNLOAD 7
548548+#define BASS_SYNC_FREE 8
549549+#define BASS_SYNC_SETPOS 11
550550+#define BASS_SYNC_MUSICPOS 10
551551+#define BASS_SYNC_MUSICINST 1
552552+#define BASS_SYNC_MUSICFX 3
553553+#define BASS_SYNC_OGG_CHANGE 12
554554+#define BASS_SYNC_DEV_FAIL 14
555555+#define BASS_SYNC_DEV_FORMAT 15
556556+#define BASS_SYNC_THREAD 0x20000000 // flag: call sync in other thread
557557+#define BASS_SYNC_MIXTIME 0x40000000 // flag: sync at mixtime, else at playtime
558558+#define BASS_SYNC_ONETIME 0x80000000 // flag: sync only once, else continuously
559559+560560+typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user);
561561+/* Sync callback function.
562562+handle : The sync that has occured
563563+channel: Channel that the sync occured in
564564+data : Additional data associated with the sync's occurance
565565+user : The 'user' parameter given when calling BASS_ChannelSetSync */
566566+567567+typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user);
568568+/* DSP callback function.
569569+handle : The DSP handle
570570+channel: Channel that the DSP is being applied to
571571+buffer : Buffer to apply the DSP to
572572+length : Number of bytes in the buffer
573573+user : The 'user' parameter given when calling BASS_ChannelSetDSP */
574574+575575+typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user);
576576+/* Recording callback function.
577577+handle : The recording handle
578578+buffer : Buffer containing the recorded sample data
579579+length : Number of bytes
580580+user : The 'user' parameter value given when calling BASS_RecordStart
581581+RETURN : TRUE = continue recording, FALSE = stop */
582582+583583+// BASS_ChannelIsActive return values
584584+#define BASS_ACTIVE_STOPPED 0
585585+#define BASS_ACTIVE_PLAYING 1
586586+#define BASS_ACTIVE_STALLED 2
587587+#define BASS_ACTIVE_PAUSED 3
588588+#define BASS_ACTIVE_PAUSED_DEVICE 4
589589+590590+// Channel attributes
591591+#define BASS_ATTRIB_FREQ 1
592592+#define BASS_ATTRIB_VOL 2
593593+#define BASS_ATTRIB_PAN 3
594594+#define BASS_ATTRIB_EAXMIX 4
595595+#define BASS_ATTRIB_NOBUFFER 5
596596+#define BASS_ATTRIB_VBR 6
597597+#define BASS_ATTRIB_CPU 7
598598+#define BASS_ATTRIB_SRC 8
599599+#define BASS_ATTRIB_NET_RESUME 9
600600+#define BASS_ATTRIB_SCANINFO 10
601601+#define BASS_ATTRIB_NORAMP 11
602602+#define BASS_ATTRIB_BITRATE 12
603603+#define BASS_ATTRIB_BUFFER 13
604604+#define BASS_ATTRIB_GRANULE 14
605605+#define BASS_ATTRIB_USER 15
606606+#define BASS_ATTRIB_TAIL 16
607607+#define BASS_ATTRIB_PUSH_LIMIT 17
608608+#define BASS_ATTRIB_DOWNLOADPROC 18
609609+#define BASS_ATTRIB_VOLDSP 19
610610+#define BASS_ATTRIB_VOLDSP_PRIORITY 20
611611+#define BASS_ATTRIB_MUSIC_AMPLIFY 0x100
612612+#define BASS_ATTRIB_MUSIC_PANSEP 0x101
613613+#define BASS_ATTRIB_MUSIC_PSCALER 0x102
614614+#define BASS_ATTRIB_MUSIC_BPM 0x103
615615+#define BASS_ATTRIB_MUSIC_SPEED 0x104
616616+#define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105
617617+#define BASS_ATTRIB_MUSIC_ACTIVE 0x106
618618+#define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel #
619619+#define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument #
620620+621621+// BASS_ChannelSlideAttribute flags
622622+#define BASS_SLIDE_LOG 0x1000000
623623+624624+// BASS_ChannelGetData flags
625625+#define BASS_DATA_AVAILABLE 0 // query how much data is buffered
626626+#define BASS_DATA_NOREMOVE 0x10000000 // flag: don't remove data from recording buffer
627627+#define BASS_DATA_FIXED 0x20000000 // unused
628628+#define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data
629629+#define BASS_DATA_FFT256 0x80000000 // 256 sample FFT
630630+#define BASS_DATA_FFT512 0x80000001 // 512 FFT
631631+#define BASS_DATA_FFT1024 0x80000002 // 1024 FFT
632632+#define BASS_DATA_FFT2048 0x80000003 // 2048 FFT
633633+#define BASS_DATA_FFT4096 0x80000004 // 4096 FFT
634634+#define BASS_DATA_FFT8192 0x80000005 // 8192 FFT
635635+#define BASS_DATA_FFT16384 0x80000006 // 16384 FFT
636636+#define BASS_DATA_FFT32768 0x80000007 // 32768 FFT
637637+#define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined
638638+#define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window
639639+#define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias
640640+#define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data
641641+#define BASS_DATA_FFT_NYQUIST 0x100 // FFT flag: return extra Nyquist value
642642+643643+// BASS_ChannelGetLevelEx flags
644644+#define BASS_LEVEL_MONO 1 // get mono level
645645+#define BASS_LEVEL_STEREO 2 // get stereo level
646646+#define BASS_LEVEL_RMS 4 // get RMS levels
647647+#define BASS_LEVEL_VOLPAN 8 // apply VOL/PAN attributes to the levels
648648+#define BASS_LEVEL_NOREMOVE 16 // don't remove data from recording buffer
649649+650650+// BASS_ChannelGetTags types : what's returned
651651+#define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure
652652+#define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block
653653+#define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings
654654+#define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ASCII strings
655655+#define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings
656656+#define BASS_TAG_META 5 // ICY metadata : ANSI string
657657+#define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings
658658+#define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings
659659+#define BASS_TAG_WMA 8 // WMA tags : series of null-terminated UTF-8 strings
660660+#define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string
661661+#define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string
662662+#define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure
663663+#define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings
664664+#define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure
665665+#define BASS_TAG_AM_NAME 16 // Android Media codec name : ASCII string
666666+#define BASS_TAG_ID3V2_2 17 // ID3v2 tags (2nd block) : variable length block
667667+#define BASS_TAG_AM_MIME 18 // Android Media MIME type : ASCII string
668668+#define BASS_TAG_LOCATION 19 // redirected URL : ASCII string
669669+#define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings
670670+#define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure
671671+#define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure
672672+#define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string
673673+#define BASS_TAG_RIFF_CUE 0x104 // RIFF "cue " chunk : TAG_CUE structure
674674+#define BASS_TAG_RIFF_SMPL 0x105 // RIFF "smpl" chunk : TAG_SMPL structure
675675+#define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure
676676+#define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string
677677+#define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string
678678+#define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers
679679+#define BASS_TAG_MUSIC_AUTH 0x10003 // MOD author : UTF-8 string
680680+#define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string
681681+#define BASS_TAG_MUSIC_CHAN 0x10200 // + channel #, MOD channel name : ANSI string
682682+#define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string
683683+684684+// ID3v1 tag structure
685685+typedef struct {
686686+ char id[3];
687687+ char title[30];
688688+ char artist[30];
689689+ char album[30];
690690+ char year[4];
691691+ char comment[30];
692692+ BYTE genre;
693693+} TAG_ID3;
694694+695695+// Binary APE tag structure
696696+typedef struct {
697697+ const char *key;
698698+ const void *data;
699699+ DWORD length;
700700+} TAG_APE_BINARY;
701701+702702+// BWF "bext" tag structure
703703+#ifdef _MSC_VER
704704+#pragma warning(push)
705705+#pragma warning(disable:4200)
706706+#endif
707707+#pragma pack(push,1)
708708+typedef struct {
709709+ char Description[256]; // description
710710+ char Originator[32]; // name of the originator
711711+ char OriginatorReference[32]; // reference of the originator
712712+ char OriginationDate[10]; // date of creation (yyyy-mm-dd)
713713+ char OriginationTime[8]; // time of creation (hh-mm-ss)
714714+ QWORD TimeReference; // first sample count since midnight (little-endian)
715715+ WORD Version; // BWF version (little-endian)
716716+ BYTE UMID[64]; // SMPTE UMID
717717+ BYTE Reserved[190];
718718+#if defined(__GNUC__) && __GNUC__<3
719719+ char CodingHistory[0]; // history
720720+#elif 1 // change to 0 if compiler fails the following line
721721+ char CodingHistory[]; // history
722722+#else
723723+ char CodingHistory[1]; // history
724724+#endif
725725+} TAG_BEXT;
726726+#pragma pack(pop)
727727+728728+// BWF "cart" tag structures
729729+typedef struct
730730+{
731731+ DWORD dwUsage; // FOURCC timer usage ID
732732+ DWORD dwValue; // timer value in samples from head
733733+} TAG_CART_TIMER;
734734+735735+typedef struct
736736+{
737737+ char Version[4]; // version of the data structure
738738+ char Title[64]; // title of cart audio sequence
739739+ char Artist[64]; // artist or creator name
740740+ char CutID[64]; // cut number identification
741741+ char ClientID[64]; // client identification
742742+ char Category[64]; // category ID, PSA, NEWS, etc
743743+ char Classification[64]; // classification or auxiliary key
744744+ char OutCue[64]; // out cue text
745745+ char StartDate[10]; // yyyy-mm-dd
746746+ char StartTime[8]; // hh:mm:ss
747747+ char EndDate[10]; // yyyy-mm-dd
748748+ char EndTime[8]; // hh:mm:ss
749749+ char ProducerAppID[64]; // name of vendor or application
750750+ char ProducerAppVersion[64]; // version of producer application
751751+ char UserDef[64]; // user defined text
752752+ DWORD dwLevelReference; // sample value for 0 dB reference
753753+ TAG_CART_TIMER PostTimer[8]; // 8 time markers after head
754754+ char Reserved[276];
755755+ char URL[1024]; // uniform resource locator
756756+#if defined(__GNUC__) && __GNUC__<3
757757+ char TagText[0]; // free form text for scripts or tags
758758+#elif 1 // change to 0 if compiler fails the following line
759759+ char TagText[]; // free form text for scripts or tags
760760+#else
761761+ char TagText[1]; // free form text for scripts or tags
762762+#endif
763763+} TAG_CART;
764764+765765+// RIFF "cue " tag structures
766766+typedef struct
767767+{
768768+ DWORD dwName;
769769+ DWORD dwPosition;
770770+ DWORD fccChunk;
771771+ DWORD dwChunkStart;
772772+ DWORD dwBlockStart;
773773+ DWORD dwSampleOffset;
774774+} TAG_CUE_POINT;
775775+776776+typedef struct
777777+{
778778+ DWORD dwCuePoints;
779779+#if defined(__GNUC__) && __GNUC__<3
780780+ TAG_CUE_POINT CuePoints[0];
781781+#elif 1 // change to 0 if compiler fails the following line
782782+ TAG_CUE_POINT CuePoints[];
783783+#else
784784+ TAG_CUE_POINT CuePoints[1];
785785+#endif
786786+} TAG_CUE;
787787+788788+// RIFF "smpl" tag structures
789789+typedef struct
790790+{
791791+ DWORD dwIdentifier;
792792+ DWORD dwType;
793793+ DWORD dwStart;
794794+ DWORD dwEnd;
795795+ DWORD dwFraction;
796796+ DWORD dwPlayCount;
797797+} TAG_SMPL_LOOP;
798798+799799+typedef struct
800800+{
801801+ DWORD dwManufacturer;
802802+ DWORD dwProduct;
803803+ DWORD dwSamplePeriod;
804804+ DWORD dwMIDIUnityNote;
805805+ DWORD dwMIDIPitchFraction;
806806+ DWORD dwSMPTEFormat;
807807+ DWORD dwSMPTEOffset;
808808+ DWORD cSampleLoops;
809809+ DWORD cbSamplerData;
810810+#if defined(__GNUC__) && __GNUC__<3
811811+ TAG_SMPL_LOOP SampleLoops[0];
812812+#elif 1 // change to 0 if compiler fails the following line
813813+ TAG_SMPL_LOOP SampleLoops[];
814814+#else
815815+ TAG_SMPL_LOOP SampleLoops[1];
816816+#endif
817817+} TAG_SMPL;
818818+#ifdef _MSC_VER
819819+#pragma warning(pop)
820820+#endif
821821+822822+// CoreAudio codec info structure
823823+typedef struct {
824824+ DWORD ftype; // file format
825825+ DWORD atype; // audio format
826826+ const char *name; // description
827827+} TAG_CA_CODEC;
828828+829829+#ifndef _WAVEFORMATEX_
830830+#define _WAVEFORMATEX_
831831+#pragma pack(push,1)
832832+typedef struct tWAVEFORMATEX
833833+{
834834+ WORD wFormatTag;
835835+ WORD nChannels;
836836+ DWORD nSamplesPerSec;
837837+ DWORD nAvgBytesPerSec;
838838+ WORD nBlockAlign;
839839+ WORD wBitsPerSample;
840840+ WORD cbSize;
841841+} WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX;
842842+typedef const WAVEFORMATEX *LPCWAVEFORMATEX;
843843+#pragma pack(pop)
844844+#endif
845845+846846+// BASS_ChannelGetLength/GetPosition/SetPosition modes
847847+#define BASS_POS_BYTE 0 // byte position
848848+#define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row)
849849+#define BASS_POS_OGG 3 // OGG bitstream number
850850+#define BASS_POS_END 0x10 // trimmed end position
851851+#define BASS_POS_LOOP 0x11 // loop start positiom
852852+#define BASS_POS_FLUSH 0x1000000 // flag: flush decoder/FX buffers
853853+#define BASS_POS_RESET 0x2000000 // flag: reset user file buffers
854854+#define BASS_POS_RELATIVE 0x4000000 // flag: seek relative to the current position
855855+#define BASS_POS_INEXACT 0x8000000 // flag: allow seeking to inexact position
856856+#define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position
857857+#define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking
858858+#define BASS_POS_SCAN 0x40000000 // flag: scan to the position
859859+860860+// BASS_ChannelSetDevice/GetDevice option
861861+#define BASS_NODEVICE 0x20000
862862+863863+// BASS_RecordSetInput flags
864864+#define BASS_INPUT_OFF 0x10000
865865+#define BASS_INPUT_ON 0x20000
866866+867867+#define BASS_INPUT_TYPE_MASK 0xff000000
868868+#define BASS_INPUT_TYPE_UNDEF 0x00000000
869869+#define BASS_INPUT_TYPE_DIGITAL 0x01000000
870870+#define BASS_INPUT_TYPE_LINE 0x02000000
871871+#define BASS_INPUT_TYPE_MIC 0x03000000
872872+#define BASS_INPUT_TYPE_SYNTH 0x04000000
873873+#define BASS_INPUT_TYPE_CD 0x05000000
874874+#define BASS_INPUT_TYPE_PHONE 0x06000000
875875+#define BASS_INPUT_TYPE_SPEAKER 0x07000000
876876+#define BASS_INPUT_TYPE_WAVE 0x08000000
877877+#define BASS_INPUT_TYPE_AUX 0x09000000
878878+#define BASS_INPUT_TYPE_ANALOG 0x0a000000
879879+880880+// BASS_ChannelSetFX effect types
881881+#define BASS_FX_DX8_CHORUS 0
882882+#define BASS_FX_DX8_COMPRESSOR 1
883883+#define BASS_FX_DX8_DISTORTION 2
884884+#define BASS_FX_DX8_ECHO 3
885885+#define BASS_FX_DX8_FLANGER 4
886886+#define BASS_FX_DX8_GARGLE 5
887887+#define BASS_FX_DX8_I3DL2REVERB 6
888888+#define BASS_FX_DX8_PARAMEQ 7
889889+#define BASS_FX_DX8_REVERB 8
890890+#define BASS_FX_VOLUME 9
891891+892892+typedef struct {
893893+ float fWetDryMix;
894894+ float fDepth;
895895+ float fFeedback;
896896+ float fFrequency;
897897+ DWORD lWaveform; // 0=triangle, 1=sine
898898+ float fDelay;
899899+ DWORD lPhase; // BASS_DX8_PHASE_xxx
900900+} BASS_DX8_CHORUS;
901901+902902+typedef struct {
903903+ float fGain;
904904+ float fAttack;
905905+ float fRelease;
906906+ float fThreshold;
907907+ float fRatio;
908908+ float fPredelay;
909909+} BASS_DX8_COMPRESSOR;
910910+911911+typedef struct {
912912+ float fGain;
913913+ float fEdge;
914914+ float fPostEQCenterFrequency;
915915+ float fPostEQBandwidth;
916916+ float fPreLowpassCutoff;
917917+} BASS_DX8_DISTORTION;
918918+919919+typedef struct {
920920+ float fWetDryMix;
921921+ float fFeedback;
922922+ float fLeftDelay;
923923+ float fRightDelay;
924924+ BOOL lPanDelay;
925925+} BASS_DX8_ECHO;
926926+927927+typedef struct {
928928+ float fWetDryMix;
929929+ float fDepth;
930930+ float fFeedback;
931931+ float fFrequency;
932932+ DWORD lWaveform; // 0=triangle, 1=sine
933933+ float fDelay;
934934+ DWORD lPhase; // BASS_DX8_PHASE_xxx
935935+} BASS_DX8_FLANGER;
936936+937937+typedef struct {
938938+ DWORD dwRateHz; // Rate of modulation in hz
939939+ DWORD dwWaveShape; // 0=triangle, 1=square
940940+} BASS_DX8_GARGLE;
941941+942942+typedef struct {
943943+ int lRoom; // [-10000, 0] default: -1000 mB
944944+ int lRoomHF; // [-10000, 0] default: 0 mB
945945+ float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
946946+ float flDecayTime; // [0.1, 20.0] default: 1.49s
947947+ float flDecayHFRatio; // [0.1, 2.0] default: 0.83
948948+ int lReflections; // [-10000, 1000] default: -2602 mB
949949+ float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s
950950+ int lReverb; // [-10000, 2000] default: 200 mB
951951+ float flReverbDelay; // [0.0, 0.1] default: 0.011 s
952952+ float flDiffusion; // [0.0, 100.0] default: 100.0 %
953953+ float flDensity; // [0.0, 100.0] default: 100.0 %
954954+ float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz
955955+} BASS_DX8_I3DL2REVERB;
956956+957957+typedef struct {
958958+ float fCenter;
959959+ float fBandwidth;
960960+ float fGain;
961961+} BASS_DX8_PARAMEQ;
962962+963963+typedef struct {
964964+ float fInGain; // [-96.0,0.0] default: 0.0 dB
965965+ float fReverbMix; // [-96.0,0.0] default: 0.0 db
966966+ float fReverbTime; // [0.001,3000.0] default: 1000.0 ms
967967+ float fHighFreqRTRatio; // [0.001,0.999] default: 0.001
968968+} BASS_DX8_REVERB;
969969+970970+#define BASS_DX8_PHASE_NEG_180 0
971971+#define BASS_DX8_PHASE_NEG_90 1
972972+#define BASS_DX8_PHASE_ZERO 2
973973+#define BASS_DX8_PHASE_90 3
974974+#define BASS_DX8_PHASE_180 4
975975+976976+typedef struct {
977977+ float fTarget;
978978+ float fCurrent;
979979+ float fTime;
980980+ DWORD lCurve;
981981+} BASS_FX_VOLUME_PARAM;
982982+983983+typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status);
984984+/* iOS notification callback function.
985985+status : The notification (BASS_IOSNOTIFY_xxx) */
986986+987987+#define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started
988988+#define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended
989989+990990+BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value);
991991+DWORD BASSDEF(BASS_GetConfig)(DWORD option);
992992+BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value);
993993+const void *BASSDEF(BASS_GetConfigPtr)(DWORD option);
994994+DWORD BASSDEF(BASS_GetVersion)(void);
995995+int BASSDEF(BASS_ErrorGetCode)(void);
996996+997997+BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
998998+#if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
999999+BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const void *dsguid);
10001000+#else
10011001+BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, const void *dsguid);
10021002+#endif
10031003+BOOL BASSDEF(BASS_Free)(void);
10041004+BOOL BASSDEF(BASS_SetDevice)(DWORD device);
10051005+DWORD BASSDEF(BASS_GetDevice)(void);
10061006+BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info);
10071007+BOOL BASSDEF(BASS_Start)(void);
10081008+BOOL BASSDEF(BASS_Stop)(void);
10091009+BOOL BASSDEF(BASS_Pause)(void);
10101010+DWORD BASSDEF(BASS_IsStarted)(void);
10111011+BOOL BASSDEF(BASS_Update)(DWORD length);
10121012+float BASSDEF(BASS_GetCPU)(void);
10131013+BOOL BASSDEF(BASS_SetVolume)(float volume);
10141014+float BASSDEF(BASS_GetVolume)(void);
10151015+#if defined(_WIN32) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
10161016+void *BASSDEF(BASS_GetDSoundObject)(DWORD object);
10171017+#endif
10181018+10191019+BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf);
10201020+BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf);
10211021+BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top);
10221022+BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top);
10231023+void BASSDEF(BASS_Apply3D)(void);
10241024+10251025+HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags);
10261026+BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle);
10271027+BOOL BASSDEF(BASS_PluginEnable)(HPLUGIN handle, BOOL enable);
10281028+const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle);
10291029+10301030+HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags);
10311031+HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags);
10321032+BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle);
10331033+BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer);
10341034+BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer);
10351035+BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info);
10361036+BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info);
10371037+DWORD BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, DWORD flags);
10381038+DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels);
10391039+BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle);
10401040+10411041+HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user);
10421042+HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
10431043+HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
10441044+HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user);
10451045+BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle);
10461046+QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode);
10471047+DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length);
10481048+DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length);
10491049+10501050+HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq);
10511051+BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle);
10521052+10531053+BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
10541054+BOOL BASSDEF(BASS_RecordInit)(int device);
10551055+BOOL BASSDEF(BASS_RecordFree)(void);
10561056+BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device);
10571057+DWORD BASSDEF(BASS_RecordGetDevice)(void);
10581058+BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info);
10591059+const char *BASSDEF(BASS_RecordGetInputName)(int input);
10601060+BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume);
10611061+DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume);
10621062+HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user);
10631063+10641064+double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos);
10651065+QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos);
10661066+DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle);
10671067+BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device);
10681068+DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle);
10691069+BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info);
10701070+const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags);
10711071+DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask);
10721072+BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock);
10731073+BOOL BASSDEF(BASS_ChannelFree)(DWORD handle);
10741074+BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart);
10751075+BOOL BASSDEF(BASS_ChannelStart)(DWORD handle);
10761076+BOOL BASSDEF(BASS_ChannelStop)(DWORD handle);
10771077+BOOL BASSDEF(BASS_ChannelPause)(DWORD handle);
10781078+BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length);
10791079+BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value);
10801080+BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value);
10811081+BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time);
10821082+BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib);
10831083+BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size);
10841084+DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size);
10851085+BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol);
10861086+BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol);
10871087+BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel);
10881088+BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel);
10891089+QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode);
10901090+BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode);
10911091+QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode);
10921092+DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle);
10931093+BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags);
10941094+DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length);
10951095+HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user);
10961096+BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync);
10971097+BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan);
10981098+BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan);
10991099+HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority);
11001100+BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp);
11011101+HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority);
11021102+BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx);
11031103+11041104+BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params);
11051105+BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params);
11061106+BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority);
11071107+BOOL BASSDEF(BASS_FXReset)(DWORD handle);
11081108+11091109+#ifdef __cplusplus
11101110+}
11111111+11121112+#if defined(_WIN32) && !defined(NOBASSOVERLOADS)
11131113+static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags)
11141114+{
11151115+ return BASS_PluginLoad((const char*)file, flags | BASS_UNICODE);
11161116+}
11171117+11181118+static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq)
11191119+{
11201120+ return BASS_MusicLoad(mem, (const void*)file, offset, length, flags | BASS_UNICODE, freq);
11211121+}
11221122+11231123+static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags)
11241124+{
11251125+ return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags | BASS_UNICODE);
11261126+}
11271127+11281128+static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags)
11291129+{
11301130+ return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags | BASS_UNICODE);
11311131+}
11321132+11331133+static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user)
11341134+{
11351135+ return BASS_StreamCreateURL((const char*)url, offset, flags | BASS_UNICODE, proc, user);
11361136+}
11371137+11381138+static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value)
11391139+{
11401140+ return BASS_SetConfigPtr(option | BASS_UNICODE, (const void*)value);
11411141+}
11421142+#endif
11431143+#endif
11441144+11451145+#ifdef __OBJC__
11461146+#undef BOOL
11471147+#endif
11481148+11491149+#endif
libs/bass.lib
This is a binary file and will not be displayed.
+291-153
main.cpp
···33#include <stdio.h>
44#include <string.h>
55#include <mmsystem.h>
66+#include <wininet.h>
77+#include "libs/bass.h"
6879#pragma comment(lib, "winmm.lib")
1010+#pragma comment(lib, "wininet.lib")
811912#define ID_ABOUT 1001
1013#define ID_EXIT 1002
···1922 float frequency;
2023 char name[64];
2124 char description[128];
2525+ char streamUrl[256];
2226} RadioStation;
23272428RadioStation g_stations[] = {
2525- {14.230f, "BBC World Service", "International news and current affairs"},
2626- {15.770f, "Radio Moscow", "Russian international broadcast"},
2727- {17.895f, "Voice of America", "American international news"},
2828- {21.500f, "Radio Australia", "Australian international service"},
2929- {25.820f, "Radio Canada", "Canadian international broadcast"},
3030- {28.400f, "Amateur Radio", "Ham radio operators"},
3131- {31.100f, "Time Signal", "Atomic clock time broadcast"}
2929+ {14.230f, "SomaFM Groove", "Downtempo and chillout", "http://ice1.somafm.com/groovesalad-128-mp3"},
3030+ {15.770f, "Radio Paradise", "Eclectic music mix", "http://stream.radioparadise.com/mp3-128"},
3131+ {17.895f, "Jazz Radio", "Smooth jazz", "http://jazz-wr04.ice.infomaniak.ch/jazz-wr04-128.mp3"},
3232+ {21.500f, "Classical Music", "Classical radio", "http://stream.wqxr.org/wqxr"},
3333+ {31.100f, "Chillout Lounge", "Relaxing music", "http://air.radiorecord.ru:805/chil_320"}
3234};
33353436#define NUM_STATIONS (sizeof(g_stations) / sizeof(RadioStation))
···40424143// Audio state
4244typedef struct {
4343- HWAVEOUT hWaveOut;
4444- WAVEHDR waveHeaders[NUM_BUFFERS];
4545- short audioBuffers[NUM_BUFFERS][BUFFER_SIZE];
4646- int currentBuffer;
4545+ // BASS handles
4646+ HSTREAM currentStream;
4747+ HSTREAM staticStream;
4748 int isPlaying;
4849 float staticVolume;
4950 float radioVolume;
5151+5252+ // Station tracking
5353+ RadioStation* currentStation;
5054} AudioState;
51555256// Radio state
···5963 int isDraggingVolume;
6064} RadioState;
61656262-RadioState g_radio = {14.230f, 0.5f, 0, 0, 0, 0};
6666+RadioState g_radio = {14.230f, 0.8f, 0, 0, 0, 0}; // Increase default volume to 0.8
6367AudioState g_audio = {0};
64686569LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
···7781// Audio functions
7882int InitializeAudio();
7983void CleanupAudio();
8080-void GenerateStaticBuffer(short* buffer, int size);
8181-void FillAudioBuffer(short* buffer, int size);
8282-void CALLBACK WaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
8384void StartAudio();
8485void StopAudio();
8586RadioStation* FindNearestStation(float frequency);
8687float GetStationSignalStrength(RadioStation* station, float currentFreq);
8888+8989+// BASS streaming functions
9090+int StartBassStreaming(RadioStation* station);
9191+void StopBassStreaming();
87928893int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
9494+ // Allocate console for debugging
9595+ AllocConsole();
9696+ freopen("CONOUT$", "w", stdout);
9797+ freopen("CONOUT$", "w", stderr);
9898+ printf("Shortwave Radio Debug Console\n");
9999+ printf("=============================\n");
100100+89101 const char* CLASS_NAME = "ShortwaveRadio";
9010291103 WNDCLASS wc = {};
···174186 case WM_LBUTTONDOWN: {
175187 int mouseX = LOWORD(lParam);
176188 int mouseY = HIWORD(lParam);
177177-189189+178190 // Check if clicking on tuning dial
179191 if (IsPointInCircle(mouseX, mouseY, 150, 200, 60)) {
180192 g_radio.isDraggingDial = 1;
···227239 return 0;
228240 }
229241242242+ case WM_KEYDOWN: {
243243+ switch (wParam) {
244244+ case VK_UP: {
245245+ // Increase frequency by 0.1 MHz (fine tuning)
246246+ g_radio.frequency += 0.1f;
247247+ if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f;
248248+249249+ // Update signal strength for new frequency
250250+ RadioStation* station = FindNearestStation(g_radio.frequency);
251251+ if (station) {
252252+ g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f);
253253+ if (g_radio.signalStrength > 50 && station != g_audio.currentStation) {
254254+ StopBassStreaming();
255255+ StartBassStreaming(station);
256256+ }
257257+ } else {
258258+ g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency));
259259+ StopBassStreaming();
260260+ }
261261+262262+ if (g_radio.signalStrength < 0) g_radio.signalStrength = 0;
263263+ if (g_radio.signalStrength > 100) g_radio.signalStrength = 100;
264264+265265+ InvalidateRect(hwnd, NULL, TRUE);
266266+ break;
267267+ }
268268+269269+ case VK_DOWN: {
270270+ // Decrease frequency by 0.1 MHz (fine tuning)
271271+ g_radio.frequency -= 0.1f;
272272+ if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f;
273273+274274+ // Update signal strength for new frequency
275275+ RadioStation* station = FindNearestStation(g_radio.frequency);
276276+ if (station) {
277277+ g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f);
278278+ if (g_radio.signalStrength > 50 && station != g_audio.currentStation) {
279279+ StopBassStreaming();
280280+ StartBassStreaming(station);
281281+ }
282282+ } else {
283283+ g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency));
284284+ StopBassStreaming();
285285+ }
286286+287287+ if (g_radio.signalStrength < 0) g_radio.signalStrength = 0;
288288+ if (g_radio.signalStrength > 100) g_radio.signalStrength = 100;
289289+290290+ InvalidateRect(hwnd, NULL, TRUE);
291291+ break;
292292+ }
293293+294294+ case VK_RIGHT: {
295295+ // Increase frequency by 1.0 MHz (coarse tuning)
296296+ g_radio.frequency += 1.0f;
297297+ if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f;
298298+299299+ // Update signal strength for new frequency
300300+ RadioStation* station = FindNearestStation(g_radio.frequency);
301301+ if (station) {
302302+ g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f);
303303+ if (g_radio.signalStrength > 50 && station != g_audio.currentStation) {
304304+ StopBassStreaming();
305305+ StartBassStreaming(station);
306306+ }
307307+ } else {
308308+ g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency));
309309+ StopBassStreaming();
310310+ }
311311+312312+ if (g_radio.signalStrength < 0) g_radio.signalStrength = 0;
313313+ if (g_radio.signalStrength > 100) g_radio.signalStrength = 100;
314314+315315+ InvalidateRect(hwnd, NULL, TRUE);
316316+ break;
317317+ }
318318+319319+ case VK_LEFT: {
320320+ // Decrease frequency by 1.0 MHz (coarse tuning)
321321+ g_radio.frequency -= 1.0f;
322322+ if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f;
323323+324324+ // Update signal strength for new frequency
325325+ RadioStation* station = FindNearestStation(g_radio.frequency);
326326+ if (station) {
327327+ g_radio.signalStrength = (int)(GetStationSignalStrength(station, g_radio.frequency) * 100.0f);
328328+ if (g_radio.signalStrength > 50 && station != g_audio.currentStation) {
329329+ StopBassStreaming();
330330+ StartBassStreaming(station);
331331+ }
332332+ } else {
333333+ g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency));
334334+ StopBassStreaming();
335335+ }
336336+337337+ if (g_radio.signalStrength < 0) g_radio.signalStrength = 0;
338338+ if (g_radio.signalStrength > 100) g_radio.signalStrength = 100;
339339+340340+ InvalidateRect(hwnd, NULL, TRUE);
341341+ break;
342342+ }
343343+ }
344344+ return 0;
345345+ }
346346+230347 case WM_COMMAND:
231348 switch (LOWORD(wParam)) {
232349 case ID_ABOUT: {
···238355 "Features:\n"
239356 "- Realistic tuning interface\n"
240357 "- Internet radio streaming\n"
241241- "- Authentic static noise";
358358+ "- Authentic static noise\n\n"
359359+ "Controls:\n"
360360+ "- Drag tuning dial to change frequency\n"
361361+ "- UP/DOWN arrows: Fine tuning (0.1 MHz)\n"
362362+ "- LEFT/RIGHT arrows: Coarse tuning (1.0 MHz)\n"
363363+ "- Click power button to turn on/off\n"
364364+ "- Drag volume knob to adjust volume";
242365 MessageBox(hwnd, aboutText, "About Shortwave Radio",
243366 MB_OK | MB_ICONINFORMATION);
244367 break;
···268391 // Draw panel border (raised effect)
269392 HPEN lightPen = CreatePen(PS_SOLID, 2, RGB(140, 100, 60));
270393 HPEN darkPen = CreatePen(PS_SOLID, 2, RGB(40, 25, 15));
271271-394394+272395 SelectObject(hdc, lightPen);
273396 MoveToEx(hdc, panel.left, panel.bottom, NULL);
274397 LineTo(hdc, panel.left, panel.top);
275398 LineTo(hdc, panel.right, panel.top);
276276-399399+277400 SelectObject(hdc, darkPen);
278401 LineTo(hdc, panel.right, panel.bottom);
279402 LineTo(hdc, panel.left, panel.bottom);
280280-403403+281404 DeleteObject(lightPen);
282405 DeleteObject(darkPen);
283406···303426 HBRUSH stationBrush = CreateSolidBrush(RGB(0, 0, 0));
304427 FillRect(hdc, &stationRect, stationBrush);
305428 DeleteObject(stationBrush);
306306-429429+307430 HPEN stationPen = CreatePen(PS_SOLID, 1, RGB(100, 100, 100));
308431 SelectObject(hdc, stationPen);
309432 Rectangle(hdc, stationRect.left, stationRect.top, stationRect.right, stationRect.bottom);
310433 DeleteObject(stationPen);
311311-434434+312435 SetTextColor(hdc, RGB(0, 255, 0));
313436 HFONT stationFont = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
314437 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
315438 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
316439 DEFAULT_PITCH | FF_SWISS, "Arial");
317440 SelectObject(hdc, stationFont);
318318-441441+319442 char stationText[256];
320320- sprintf(stationText, "%.3f MHz - %s: %s",
443443+ sprintf(stationText, "%.3f MHz - %s: %s",
321444 currentStation->frequency, currentStation->name, currentStation->description);
322322-445445+323446 SetTextAlign(hdc, TA_LEFT);
324447 TextOut(hdc, stationRect.left + 5, stationRect.top + 5, stationText, strlen(stationText));
325325-448448+326449 DeleteObject(stationFont);
327450 }
328451···359482 // Draw frequency text
360483 char freqText[32];
361484 sprintf(freqText, "%.3f MHz", frequency);
362362-485485+363486 SetBkMode(hdc, TRANSPARENT);
364487 SetTextColor(hdc, RGB(0, 255, 0)); // Green LCD color
365488 HFONT lcdFont = CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
···367490 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
368491 FIXED_PITCH | FF_MODERN, "Courier New");
369492 SelectObject(hdc, lcdFont);
370370-493493+371494 SetTextAlign(hdc, TA_CENTER);
372495 TextOut(hdc, x, y - 8, freqText, strlen(freqText));
373373-496496+374497 DeleteObject(lcdFont);
375498}
376499···400523 float angle = (float)i * 3.14159f / 6.0f;
401524 int markX = x + (int)((radius - 15) * cos(angle));
402525 int markY = y + (int)((radius - 15) * sin(angle));
403403-526526+404527 char mark[8];
405528 sprintf(mark, "%d", 10 + i * 2);
406529 TextOut(hdc, markX, markY - 5, mark, strlen(mark));
···410533 float angle = (frequency - 10.0f) / 24.0f * 3.14159f;
411534 int pointerX = x + (int)((radius - 10) * cos(angle));
412535 int pointerY = y + (int)((radius - 10) * sin(angle));
413413-536536+414537 HPEN pointerPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
415538 SelectObject(hdc, pointerPen);
416539 MoveToEx(hdc, x, y, NULL);
···437560 float angle = volume * 3.14159f * 1.5f - 3.14159f * 0.75f;
438561 int indicatorX = x + (int)((radius - 5) * cos(angle));
439562 int indicatorY = y + (int)((radius - 5) * sin(angle));
440440-563563+441564 HPEN indicatorPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
442565 SelectObject(hdc, indicatorPen);
443566 MoveToEx(hdc, x, y, NULL);
···462585 int barWidth = 8;
463586 int numBars = strength / 10;
464587 for (int i = 0; i < numBars && i < 10; i++) {
465465- RECT bar = {x + 2 + i * barWidth, y + 2,
588588+ RECT bar = {x + 2 + i * barWidth, y + 2,
466589 x + 2 + (i + 1) * barWidth - 1, y + 18};
467467-590590+468591 COLORREF barColor;
469592 if (i < 3) barColor = RGB(0, 255, 0); // Green
470593 else if (i < 7) barColor = RGB(255, 255, 0); // Yellow
471594 else barColor = RGB(255, 0, 0); // Red
472472-595595+473596 HBRUSH barBrush = CreateSolidBrush(barColor);
474597 FillRect(hdc, &bar, barBrush);
475598 DeleteObject(barBrush);
···494617 if (power) {
495618 HPEN symbolPen = CreatePen(PS_SOLID, 3, RGB(255, 255, 255));
496619 SelectObject(hdc, symbolPen);
497497-620620+498621 // Draw power symbol (circle with line)
499622 Arc(hdc, x - 8, y - 8, x + 8, y + 8, x + 6, y - 6, x - 6, y - 6);
500623 MoveToEx(hdc, x, y - 10, NULL);
501624 LineTo(hdc, x, y - 2);
502502-625625+503626 DeleteObject(symbolPen);
504627 }
505628}
···516639517640void UpdateFrequencyFromMouse(int mouseX, int mouseY) {
518641 float angle = GetAngleFromPoint(mouseX, mouseY, 150, 200);
519519-642642+520643 // Convert angle to frequency (10-34 MHz range)
521644 // Normalize angle from -PI to PI to 0-1 range
522645 float normalizedAngle = (angle + 3.14159f) / (2.0f * 3.14159f);
523523-646646+524647 // Map to frequency range
525648 g_radio.frequency = 10.0f + normalizedAngle * 24.0f;
526526-649649+527650 // Clamp frequency
528651 if (g_radio.frequency < 10.0f) g_radio.frequency = 10.0f;
529652 if (g_radio.frequency > 34.0f) g_radio.frequency = 34.0f;
530530-653653+531654 // Calculate signal strength based on nearest station
532655 RadioStation* nearestStation = FindNearestStation(g_radio.frequency);
533656 if (nearestStation) {
534657 g_radio.signalStrength = (int)(GetStationSignalStrength(nearestStation, g_radio.frequency) * 100.0f);
658658+659659+ // Start streaming if signal is strong enough and station changed
660660+ if (g_radio.signalStrength > 50 && nearestStation != g_audio.currentStation) {
661661+ StopBassStreaming();
662662+ StartBassStreaming(nearestStation);
663663+ }
535664 } else {
536665 g_radio.signalStrength = 5 + (int)(15.0f * sin(g_radio.frequency));
666666+ StopBassStreaming();
537667 }
538538-668668+539669 if (g_radio.signalStrength < 0) g_radio.signalStrength = 0;
540670 if (g_radio.signalStrength > 100) g_radio.signalStrength = 100;
541671}
542672543673void UpdateVolumeFromMouse(int mouseX, int mouseY) {
544674 float angle = GetAngleFromPoint(mouseX, mouseY, 350, 200);
545545-675675+546676 // Convert angle to volume (0-1 range)
547677 // Map from -135 degrees to +135 degrees
548678 float normalizedAngle = (angle + 3.14159f * 0.75f) / (3.14159f * 1.5f);
549549-679679+550680 g_radio.volume = normalizedAngle;
551551-681681+552682 // Clamp volume
553683 if (g_radio.volume < 0.0f) g_radio.volume = 0.0f;
554684 if (g_radio.volume > 1.0f) g_radio.volume = 1.0f;
555685}
556686557687int InitializeAudio() {
558558- WAVEFORMATEX waveFormat;
559559- waveFormat.wFormatTag = WAVE_FORMAT_PCM;
560560- waveFormat.nChannels = CHANNELS;
561561- waveFormat.nSamplesPerSec = SAMPLE_RATE;
562562- waveFormat.wBitsPerSample = BITS_PER_SAMPLE;
563563- waveFormat.nBlockAlign = (waveFormat.nChannels * waveFormat.wBitsPerSample) / 8;
564564- waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
565565- waveFormat.cbSize = 0;
566566-567567- MMRESULT result = waveOutOpen(&g_audio.hWaveOut, WAVE_MAPPER, &waveFormat,
568568- (DWORD_PTR)WaveOutProc, 0, CALLBACK_FUNCTION);
688688+ // Initialize BASS with more detailed error reporting
689689+ printf("Initializing BASS audio system...\n");
569690570570- if (result != MMSYSERR_NOERROR) {
571571- return -1;
572572- }
573573-574574- // Initialize audio buffers
575575- for (int i = 0; i < NUM_BUFFERS; i++) {
576576- memset(&g_audio.waveHeaders[i], 0, sizeof(WAVEHDR));
577577- g_audio.waveHeaders[i].lpData = (LPSTR)g_audio.audioBuffers[i];
578578- g_audio.waveHeaders[i].dwBufferLength = BUFFER_SIZE * sizeof(short);
579579- g_audio.waveHeaders[i].dwFlags = 0;
691691+ if (!BASS_Init(-1, 44100, 0, 0, NULL)) {
692692+ DWORD error = BASS_ErrorGetCode();
693693+ printf("BASS initialization failed (Error: %lu)\n", error);
580694581581- result = waveOutPrepareHeader(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR));
582582- if (result != MMSYSERR_NOERROR) {
695695+ // Try alternative initialization methods
696696+ printf("Trying alternative audio device...\n");
697697+ if (!BASS_Init(0, 44100, 0, 0, NULL)) {
698698+ error = BASS_ErrorGetCode();
699699+ printf("Alternative BASS init also failed (Error: %lu)\n", error);
700700+ printf("BASS Error meanings:\n");
701701+ printf(" 1 = BASS_ERROR_MEM (memory error)\n");
702702+ printf(" 2 = BASS_ERROR_FILEOPEN (file/URL error)\n");
703703+ printf(" 3 = BASS_ERROR_DRIVER (no audio driver)\n");
704704+ printf(" 8 = BASS_ERROR_ALREADY (already initialized)\n");
705705+ printf(" 14 = BASS_ERROR_DEVICE (invalid device)\n");
583706 return -1;
584707 }
585708 }
586586-587587- g_audio.currentBuffer = 0;
709709+710710+ printf("BASS initialized successfully\n");
711711+712712+ // Get BASS version info
713713+ DWORD version = BASS_GetVersion();
714714+ printf("BASS version: %d.%d.%d.%d\n",
715715+ HIBYTE(HIWORD(version)), LOBYTE(HIWORD(version)),
716716+ HIBYTE(LOWORD(version)), LOBYTE(LOWORD(version)));
717717+718718+ g_audio.currentStream = 0;
719719+ g_audio.staticStream = 0;
588720 g_audio.isPlaying = 0;
589589- g_audio.staticVolume = 0.3f;
721721+ g_audio.staticVolume = 0.8f;
590722 g_audio.radioVolume = 0.0f;
723723+ g_audio.currentStation = NULL;
591724592725 return 0;
593726}
594727595728void CleanupAudio() {
596596- if (g_audio.hWaveOut) {
597597- waveOutReset(g_audio.hWaveOut);
598598-599599- for (int i = 0; i < NUM_BUFFERS; i++) {
600600- waveOutUnprepareHeader(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR));
601601- }
602602-603603- waveOutClose(g_audio.hWaveOut);
604604- g_audio.hWaveOut = NULL;
605605- }
606606-}
607607-608608-void GenerateStaticBuffer(short* buffer, int size) {
609609- for (int i = 0; i < size; i++) {
610610- // Generate white noise
611611- float noise = ((float)rand() / RAND_MAX) * 2.0f - 1.0f;
612612-613613- // Apply volume and convert to 16-bit
614614- float volume = g_audio.staticVolume * g_radio.volume;
615615- buffer[i] = (short)(noise * volume * 32767.0f);
616616- }
617617-}
618618-619619-void FillAudioBuffer(short* buffer, int size) {
620620- // Only generate audio if radio is powered on
621621- if (!g_radio.power) {
622622- memset(buffer, 0, size * sizeof(short));
623623- return;
624624- }
729729+ StopBassStreaming();
625730626626- // Generate static
627627- GenerateStaticBuffer(buffer, size);
628628-629629- // Find nearest station and mix in signal
630630- RadioStation* station = FindNearestStation(g_radio.frequency);
631631- if (station && g_radio.signalStrength > 20) {
632632- float signalStrength = GetStationSignalStrength(station, g_radio.frequency);
633633- float radioVolume = signalStrength * g_radio.volume * 0.7f;
634634-635635- for (int i = 0; i < size; i++) {
636636- // Generate different tones for different stations
637637- float time = (float)i / SAMPLE_RATE;
638638- float tone1 = sin(2.0f * 3.14159f * (station->frequency * 50.0f) * time);
639639- float tone2 = sin(2.0f * 3.14159f * (station->frequency * 75.0f) * time) * 0.5f;
640640- float tone = (tone1 + tone2) * 0.5f;
641641-642642- // Add some modulation to simulate voice/music
643643- float modulation = sin(2.0f * 3.14159f * 3.0f * time) * 0.3f + 0.7f;
644644- tone *= modulation;
645645-646646- // Mix tone with existing static
647647- float mixed = (float)buffer[i] / 32767.0f;
648648- mixed = mixed * (1.0f - radioVolume) + tone * radioVolume;
649649-650650- buffer[i] = (short)(mixed * 32767.0f);
651651- }
652652- }
653653-}
654654-655655-void CALLBACK WaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
656656- DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
657657- if (uMsg == WOM_DONE && g_audio.isPlaying) {
658658- WAVEHDR* waveHeader = (WAVEHDR*)dwParam1;
659659-660660- // Refill the buffer
661661- FillAudioBuffer((short*)waveHeader->lpData, BUFFER_SIZE);
662662-663663- // Queue the buffer for playback
664664- waveOutWrite(g_audio.hWaveOut, waveHeader, sizeof(WAVEHDR));
665665- }
731731+ // Free BASS
732732+ BASS_Free();
733733+ printf("BASS cleaned up\n");
666734}
667735668736void StartAudio() {
669737 if (!g_audio.isPlaying) {
670738 g_audio.isPlaying = 1;
671671-672672- // Fill and queue all buffers
673673- for (int i = 0; i < NUM_BUFFERS; i++) {
674674- FillAudioBuffer(g_audio.audioBuffers[i], BUFFER_SIZE);
675675- waveOutWrite(g_audio.hWaveOut, &g_audio.waveHeaders[i], sizeof(WAVEHDR));
676676- }
739739+ printf("Audio started\n");
677740 }
678741}
679742680743void StopAudio() {
681744 if (g_audio.isPlaying) {
682745 g_audio.isPlaying = 0;
683683- waveOutReset(g_audio.hWaveOut);
746746+ StopBassStreaming();
747747+ printf("Audio stopped\n");
684748 }
685749}
686750687751RadioStation* FindNearestStation(float frequency) {
688752 RadioStation* nearest = NULL;
689753 float minDistance = 999.0f;
690690-754754+691755 for (int i = 0; i < NUM_STATIONS; i++) {
692756 float distance = fabs(g_stations[i].frequency - frequency);
693757 if (distance < minDistance) {
···695759 nearest = &g_stations[i];
696760 }
697761 }
698698-762762+699763 // Only return station if we're close enough (within 0.5 MHz)
700764 if (minDistance <= 0.5f) {
701765 return nearest;
702766 }
703703-767767+704768 return NULL;
705769}
706770707771float GetStationSignalStrength(RadioStation* station, float currentFreq) {
708772 if (!station) return 0.0f;
709709-773773+710774 float distance = fabs(station->frequency - currentFreq);
711711-775775+712776 // Signal strength drops off with distance from exact frequency
713777 if (distance < 0.05f) {
714778 return 0.9f; // Very strong signal
···719783 } else if (distance < 0.5f) {
720784 return 0.2f; // Weak signal
721785 }
722722-786786+723787 return 0.0f; // No signal
724788}
789789+790790+int StartBassStreaming(RadioStation* station) {
791791+ if (!station) {
792792+ printf("StartBassStreaming failed: no station\n");
793793+ return 0;
794794+ }
795795+796796+ StopBassStreaming();
797797+798798+ printf("Attempting to stream: %s at %s\n", station->name, station->streamUrl);
799799+800800+ // Check if BASS is initialized
801801+ if (!BASS_GetVersion()) {
802802+ printf("BASS not initialized - cannot stream\n");
803803+ return 0;
804804+ }
805805+806806+ // Create BASS stream from URL with more options
807807+ printf("Creating BASS stream...\n");
808808+ g_audio.currentStream = BASS_StreamCreateURL(station->streamUrl, 0,
809809+ BASS_STREAM_BLOCK | BASS_STREAM_STATUS | BASS_STREAM_AUTOFREE, NULL, 0);
810810+811811+ if (g_audio.currentStream) {
812812+ printf("Successfully connected to stream: %s\n", station->name);
813813+814814+ // Get stream info
815815+ BASS_CHANNELINFO info;
816816+ if (BASS_ChannelGetInfo(g_audio.currentStream, &info)) {
817817+ printf("Stream info: %lu Hz, %lu channels, type=%lu\n",
818818+ info.freq, info.chans, info.ctype);
819819+ }
820820+821821+ // Set volume based on signal strength and radio volume
822822+ float volume = g_radio.volume * (g_radio.signalStrength / 100.0f);
823823+ BASS_ChannelSetAttribute(g_audio.currentStream, BASS_ATTRIB_VOL, volume);
824824+ printf("Set volume to: %.2f\n", volume);
825825+826826+ // Start playing
827827+ if (BASS_ChannelPlay(g_audio.currentStream, FALSE)) {
828828+ printf("Stream playback started\n");
829829+ } else {
830830+ DWORD error = BASS_ErrorGetCode();
831831+ printf("Failed to start playback (BASS Error: %lu)\n", error);
832832+ }
833833+834834+ g_audio.currentStation = station;
835835+ return 1;
836836+ } else {
837837+ DWORD error = BASS_ErrorGetCode();
838838+ printf("Failed to connect to stream: %s (BASS Error: %lu)\n", station->name, error);
839839+ printf("BASS Error meanings:\n");
840840+ printf(" 1 = BASS_ERROR_MEM (out of memory)\n");
841841+ printf(" 2 = BASS_ERROR_FILEOPEN (file/URL cannot be opened)\n");
842842+ printf(" 3 = BASS_ERROR_DRIVER (no audio driver available)\n");
843843+ printf(" 6 = BASS_ERROR_FORMAT (unsupported format)\n");
844844+ printf(" 7 = BASS_ERROR_POSITION (invalid position)\n");
845845+ printf(" 14 = BASS_ERROR_DEVICE (invalid device)\n");
846846+ printf(" 21 = BASS_ERROR_TIMEOUT (connection timeout)\n");
847847+ printf(" 41 = BASS_ERROR_SSL (SSL/HTTPS not supported)\n");
848848+ }
849849+850850+ return 0;
851851+}
852852+853853+void StopBassStreaming() {
854854+ if (g_audio.currentStream) {
855855+ BASS_StreamFree(g_audio.currentStream);
856856+ g_audio.currentStream = 0;
857857+ printf("Stopped streaming\n");
858858+ }
859859+860860+ g_audio.currentStation = NULL;
861861+}
862862+