Initial import
This commit is contained in:
22
sfxr/ChangeLog
Normal file
22
sfxr/ChangeLog
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
sfxr-sdl-1.0
|
||||||
|
------------
|
||||||
|
* Initial SDL port of sfxr by mjau/GerryJJ
|
||||||
|
|
||||||
|
sfxr-sdl-1.1
|
||||||
|
------------
|
||||||
|
* Various small improvements and 1 bugfix by Hans de Goede
|
||||||
|
<hdegoede@redhat.com>:
|
||||||
|
* Fix a small bug in the audio setup which could cause a quite noticable
|
||||||
|
delay between pressing a button and hearing the sound
|
||||||
|
* Add an icon and .desktop file
|
||||||
|
* Add a make install target, note: hardcoded to /usr but it does understand
|
||||||
|
the DESTDIR make parameter
|
||||||
|
|
||||||
|
sfxr-sdl-1.2.0
|
||||||
|
-------------
|
||||||
|
* Changed version number convention: <major>.<minor>.<bugfix>
|
||||||
|
* Added checkbox: Drag bars (the old default)
|
||||||
|
* Clicking sets the value of a slider
|
||||||
|
* Sound now plays when an attribute is clicked (a more involved change, like looping, would be needed for dragging)
|
||||||
|
* Sound now plays on waveform change
|
||||||
|
* Very simple undo (one slider change) with Z
|
||||||
9
sfxr/Ideas
Normal file
9
sfxr/Ideas
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
Make the undo into an array or list (very easy the way I have it set up, just plug it into the undo functions)
|
||||||
|
Make undo use a full state struct, so everything can be restored.
|
||||||
|
Add redo (push old undos to the redo list, clear redo list when something is changed)
|
||||||
|
List of open sounds
|
||||||
|
|
||||||
|
What's up with the file save? If I click Save, then Cancel, it creates a messed up file.
|
||||||
|
|
||||||
|
How would I draw the waveform? It'd be nice to see, but probably a hassle to do.
|
||||||
21
sfxr/Makefile
Normal file
21
sfxr/Makefile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
CFLAGS=-ggdb
|
||||||
|
CXXFLAGS=$(CFLAGS) `sdl-config --cflags` `pkg-config gtk+-2.0 --cflags`
|
||||||
|
LDFLAGS=`sdl-config --libs` `pkg-config gtk+-2.0 --libs`
|
||||||
|
|
||||||
|
sfxr: main.cpp tools.h sdlkit.h
|
||||||
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@
|
||||||
|
|
||||||
|
install: sfxr
|
||||||
|
mkdir -p $(DESTDIR)/usr/bin
|
||||||
|
mkdir -p $(DESTDIR)/usr/share/sfxr
|
||||||
|
mkdir -p $(DESTDIR)/usr/share/applications
|
||||||
|
mkdir -p $(DESTDIR)/usr/share/icons/hicolor/48x48/apps
|
||||||
|
install -m 755 sfxr $(DESTDIR)/usr/bin
|
||||||
|
install -m 644 -p *.tga *.bmp $(DESTDIR)/usr/share/sfxr
|
||||||
|
install -p -m 644 sfxr.png \
|
||||||
|
$(DESTDIR)/usr/share/icons/hicolor/48x48/apps
|
||||||
|
desktop-file-install --vendor "" \
|
||||||
|
--dir $(DESTDIR)/usr/share/applications sfxr.desktop
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm sfxr
|
||||||
371
sfxr/ddrawkit.h
Normal file
371
sfxr/ddrawkit.h
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Porting notes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Need to provide window/framebuffer setup at program start
|
||||||
|
|
||||||
|
ddkUnlock() is called when the window should be redrawn
|
||||||
|
|
||||||
|
WinMain() at the bottom of this file is the entry point and main loop
|
||||||
|
which handles messages and calling the app update function ddkCalcFrame()
|
||||||
|
|
||||||
|
ddkscreen32 = pointer to 640x480 DWORD pixel buffer
|
||||||
|
mouse_* = mouse info, only need x/y/px/py/left/right/leftclick/rightclick
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _WIN32_WINDOWS 0xBAD
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
extern "C" long _ftol( double ); //defined by VC6 C libs
|
||||||
|
extern "C" long _ftol2( double dblSource ) { return _ftol( dblSource ); }
|
||||||
|
|
||||||
|
void ddkInit(); // Will be called on startup
|
||||||
|
bool ddkCalcFrame(); // Will be called every frame, return true to continue running or false to quit
|
||||||
|
void ddkFree(); // Will be called on shutdown
|
||||||
|
bool ddkLock(); // Call immediately before drawing (once per frame)
|
||||||
|
void ddkUnlock(); // Call immediately after drawing (once per frame)
|
||||||
|
void ddkDrawPixel(int x, int y, int red, int green, int blue); // Draw a pixel
|
||||||
|
void ddkSetMode(int width, int height, int bpp, int refreshrate, int fullscreen, char *title);
|
||||||
|
#define DDK_WINDOW 0 // Run in a normal resizable window (stretch to fit)
|
||||||
|
#define DDK_FULLSCREEN 1 // Change display mode to the one specified, use vsync
|
||||||
|
#define DDK_STRETCH 2 // Run in a maximized window, looks like fullscreen
|
||||||
|
int ddkGetBpp(); // Use this to find out the current color depth
|
||||||
|
DWORD *ddkscreen32; // Use this for 32 bit modes
|
||||||
|
WORD *ddkscreen16; // Use this for 16 bit modes
|
||||||
|
int ddkpitch; // Offset in pixels from the start of one horizontal line to the start of the next
|
||||||
|
|
||||||
|
bool ddrawkit_initialised;
|
||||||
|
bool ddrawkit_released;
|
||||||
|
bool ddrawkit_fullscreen;
|
||||||
|
bool ddrawkit_fullwindow;
|
||||||
|
int ddrawkit_width;
|
||||||
|
int ddrawkit_height;
|
||||||
|
int ddrawkit_bpp;
|
||||||
|
int ddrawkit_refresh;
|
||||||
|
bool ddrawkit_timeravailable;
|
||||||
|
|
||||||
|
HWND hWndMain;
|
||||||
|
HINSTANCE hInstanceMain;
|
||||||
|
|
||||||
|
HCURSOR cursor_arrow;
|
||||||
|
int mouse_x, mouse_y, mouse_px, mouse_py;
|
||||||
|
bool mouse_left=false, mouse_right=false, mouse_middle=false;
|
||||||
|
bool mouse_leftclick=false, mouse_rightclick=false, mouse_middleclick=false;
|
||||||
|
bool mouse_doubleclick=false;
|
||||||
|
int mouse_wheel=0;
|
||||||
|
|
||||||
|
|
||||||
|
// --- DDB implementation
|
||||||
|
|
||||||
|
struct pBITMAPINFO
|
||||||
|
{
|
||||||
|
BITMAPINFOHEADER bmiHeader;
|
||||||
|
RGBQUAD bmiColors[256];
|
||||||
|
} BMInfo;
|
||||||
|
|
||||||
|
HBITMAP hBM;
|
||||||
|
|
||||||
|
HDC hDC_comp;
|
||||||
|
DWORD* image_bitmap;
|
||||||
|
|
||||||
|
void InitImageBuffer()
|
||||||
|
{
|
||||||
|
HPALETTE PalHan;
|
||||||
|
HWND ActiveWindow;
|
||||||
|
HDC hDC;
|
||||||
|
|
||||||
|
image_bitmap=(DWORD*)malloc(ddrawkit_width*ddrawkit_height*sizeof(DWORD));
|
||||||
|
|
||||||
|
ActiveWindow=hWndMain;
|
||||||
|
hDC=GetDC(ActiveWindow);
|
||||||
|
|
||||||
|
BMInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
||||||
|
BMInfo.bmiHeader.biWidth=ddrawkit_width;
|
||||||
|
BMInfo.bmiHeader.biHeight=-abs(ddrawkit_height);
|
||||||
|
BMInfo.bmiHeader.biPlanes=1;
|
||||||
|
BMInfo.bmiHeader.biBitCount=32;
|
||||||
|
BMInfo.bmiHeader.biCompression=BI_RGB;
|
||||||
|
BMInfo.bmiHeader.biSizeImage=ddrawkit_width*ddrawkit_height*4;
|
||||||
|
BMInfo.bmiHeader.biXPelsPerMeter=0;
|
||||||
|
BMInfo.bmiHeader.biYPelsPerMeter=0;
|
||||||
|
|
||||||
|
hBM=CreateDIBSection(hDC, (BITMAPINFO*)&BMInfo, DIB_RGB_COLORS, (void**)&image_bitmap, 0, 0);
|
||||||
|
ReleaseDC(ActiveWindow, hDC);
|
||||||
|
|
||||||
|
ddkscreen32=image_bitmap;
|
||||||
|
ddkpitch=ddrawkit_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyImageBuffer()
|
||||||
|
{
|
||||||
|
free(image_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddrawkit_BlitWindowDDB()
|
||||||
|
{
|
||||||
|
HDC hDC;
|
||||||
|
HBITMAP DefaultBitmap;
|
||||||
|
|
||||||
|
hDC=GetDC(hWndMain);
|
||||||
|
DefaultBitmap=(HBITMAP)SelectObject(hDC_comp, hBM);
|
||||||
|
// BitBlt(hDC, x1, y1, x2-x1, y2-y1, hDC_comp, x1, y1, SRCCOPY);
|
||||||
|
BitBlt(hDC, 0, 0, ddrawkit_width, ddrawkit_height, hDC_comp, 0, 0, SRCCOPY);
|
||||||
|
SelectObject(hDC_comp, DefaultBitmap);
|
||||||
|
DeleteDC(hDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- DDB implementation
|
||||||
|
|
||||||
|
|
||||||
|
void ddrawkit_SafeDestroy()
|
||||||
|
{
|
||||||
|
if(!ddrawkit_released)
|
||||||
|
{
|
||||||
|
ddrawkit_released=true;
|
||||||
|
ddkFree();
|
||||||
|
DestroyWindow(hWndMain);
|
||||||
|
DestroyImageBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_CLOSE:
|
||||||
|
ddrawkit_SafeDestroy();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_SETCURSOR:
|
||||||
|
if(ddrawkit_fullscreen || ddrawkit_fullwindow)
|
||||||
|
{
|
||||||
|
SetCursor(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetCursor(cursor_arrow);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
int curwidth, curheight;
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(hWndMain, &rect);
|
||||||
|
curwidth=rect.right-rect.left;
|
||||||
|
curheight=rect.bottom-rect.top;
|
||||||
|
mouse_x=(int)((float)LOWORD(lParam)/curwidth*ddrawkit_width);
|
||||||
|
mouse_y=(int)((float)HIWORD(lParam)/curheight*ddrawkit_height);
|
||||||
|
return 0;
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
if((wParam>>16)&0x7FFF)
|
||||||
|
{
|
||||||
|
if((wParam>>16)&0x8000)
|
||||||
|
mouse_wheel=-1;
|
||||||
|
else
|
||||||
|
mouse_wheel=1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case WM_LBUTTONDBLCLK:
|
||||||
|
mouse_doubleclick=true;
|
||||||
|
return 0;
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
mouse_left=true;
|
||||||
|
mouse_leftclick=true;
|
||||||
|
return 0;
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
mouse_left=false;
|
||||||
|
return 0;
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
mouse_right=true;
|
||||||
|
mouse_rightclick=true;
|
||||||
|
return 0;
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
mouse_right=false;
|
||||||
|
return 0;
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
mouse_middle=true;
|
||||||
|
mouse_middleclick=true;
|
||||||
|
return 0;
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
mouse_middle=false;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddrawkit_RegisterWindowClass()
|
||||||
|
{
|
||||||
|
WNDCLASSEX wcx;
|
||||||
|
|
||||||
|
ZeroMemory(&wcx, sizeof(WNDCLASSEX));
|
||||||
|
wcx.cbSize=sizeof(WNDCLASSEX);
|
||||||
|
wcx.lpfnWndProc=MainWindowProc;
|
||||||
|
wcx.hInstance=GetModuleHandle(NULL);
|
||||||
|
wcx.hIcon=LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
wcx.hCursor=NULL;
|
||||||
|
// wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||||
|
wcx.hbrBackground=NULL;
|
||||||
|
wcx.lpszMenuName=NULL;
|
||||||
|
wcx.lpszClassName="DDrawKitClass";
|
||||||
|
RegisterClassEx(&wcx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ddkLock()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddkUnlock()
|
||||||
|
{
|
||||||
|
ddrawkit_BlitWindowDDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddkDrawPixel(int x, int y, int red, int green, int blue)
|
||||||
|
{
|
||||||
|
if(x<0 || y<0 || x>=ddrawkit_width || y>=ddrawkit_height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(ddrawkit_bpp==32)
|
||||||
|
{
|
||||||
|
DWORD color=(red<<16)|(green<<8)|blue;
|
||||||
|
ddkscreen32[y*ddkpitch+x]=color;
|
||||||
|
}
|
||||||
|
if(ddrawkit_bpp==16)
|
||||||
|
{
|
||||||
|
WORD color=((red>>3)<<11)|((green>>2)<<5)|(blue>>3);
|
||||||
|
ddkscreen16[y*ddkpitch+x]=color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddkSetMode(int width, int height, int bpp, int refreshrate, int fullscreen, char *title)
|
||||||
|
{
|
||||||
|
if(!ddrawkit_initialised)
|
||||||
|
{
|
||||||
|
ddrawkit_width=width;
|
||||||
|
ddrawkit_height=height;
|
||||||
|
ddrawkit_bpp=bpp;
|
||||||
|
ddrawkit_refresh=refreshrate;
|
||||||
|
switch(fullscreen)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ddrawkit_fullscreen=false;
|
||||||
|
ddrawkit_fullwindow=false;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ddrawkit_fullscreen=true;
|
||||||
|
ddrawkit_fullwindow=false;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ddrawkit_fullscreen=false;
|
||||||
|
ddrawkit_fullwindow=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddrawkit_RegisterWindowClass();
|
||||||
|
|
||||||
|
if(ddrawkit_fullscreen || ddrawkit_fullwindow)
|
||||||
|
{
|
||||||
|
// Screen sized window (possibly stretched)
|
||||||
|
hWndMain=CreateWindowEx(WS_EX_APPWINDOW,
|
||||||
|
"DDrawKitClass", title, WS_POPUP,
|
||||||
|
0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
|
||||||
|
NULL, NULL, hInstanceMain, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal window
|
||||||
|
// hWndMain=CreateWindow("DDrawKitClass", title, WS_OVERLAPPEDWINDOW,
|
||||||
|
hWndMain=CreateWindow("DDrawKitClass", title, WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
|
||||||
|
// 0, 0, ddrawkit_width+GetSystemMetrics(SM_CXSIZEFRAME)*2,
|
||||||
|
// ddrawkit_height+GetSystemMetrics(SM_CYSIZEFRAME)*2+GetSystemMetrics(SM_CYCAPTION),
|
||||||
|
GetSystemMetrics(SM_CXSCREEN)/2-320, GetSystemMetrics(SM_CYSCREEN)/2-300,
|
||||||
|
ddrawkit_width+GetSystemMetrics(SM_CXEDGE)*2,
|
||||||
|
ddrawkit_height+GetSystemMetrics(SM_CYEDGE)*2+GetSystemMetrics(SM_CYCAPTION),
|
||||||
|
NULL, NULL, hInstanceMain, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init DDB implementation
|
||||||
|
hDC_comp=CreateCompatibleDC(NULL);
|
||||||
|
InitImageBuffer();
|
||||||
|
|
||||||
|
ShowWindow(hWndMain, SW_SHOW);
|
||||||
|
|
||||||
|
ddrawkit_initialised=true;
|
||||||
|
ddrawkit_released=false;
|
||||||
|
|
||||||
|
// Clear screen
|
||||||
|
ddkLock();
|
||||||
|
for(int y=0;y<ddrawkit_height;y++)
|
||||||
|
for(int x=0;x<ddrawkit_width;x++)
|
||||||
|
{
|
||||||
|
if(ddrawkit_bpp==32)
|
||||||
|
ddkscreen32[y*ddkpitch+x]=0;
|
||||||
|
else
|
||||||
|
ddkscreen16[y*ddkpitch+x]=0;
|
||||||
|
}
|
||||||
|
ddkUnlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ddkGetBpp()
|
||||||
|
{
|
||||||
|
return ddrawkit_bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
hInstanceMain=hInstance;
|
||||||
|
|
||||||
|
cursor_arrow=LoadCursor(NULL, IDC_ARROW);
|
||||||
|
|
||||||
|
ddkInit();
|
||||||
|
|
||||||
|
LARGE_INTEGER startTime;
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
|
||||||
|
if(!QueryPerformanceFrequency(&frequency))
|
||||||
|
ddrawkit_timeravailable=false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ddrawkit_timeravailable=true;
|
||||||
|
QueryPerformanceCounter(&startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
|
||||||
|
{
|
||||||
|
if(!GetMessage(&msg, NULL, 0, 0))
|
||||||
|
break;
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ddrawkit_released)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(!ddkCalcFrame())
|
||||||
|
{
|
||||||
|
ddrawkit_SafeDestroy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mouse_px=mouse_x;
|
||||||
|
mouse_py=mouse_y;
|
||||||
|
|
||||||
|
mouse_leftclick=false;
|
||||||
|
mouse_rightclick=false;
|
||||||
|
mouse_middleclick=false;
|
||||||
|
mouse_doubleclick=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
sfxr/font.tga
Normal file
BIN
sfxr/font.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
8
sfxr/install.txt
Normal file
8
sfxr/install.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
To build and install under Linux do:
|
||||||
|
make
|
||||||
|
su -c "make install"
|
||||||
|
|
||||||
|
Note the install is hardcoded to /usr, you can also run sfxr from the build
|
||||||
|
dir after make (./sfxr).
|
||||||
|
|
||||||
|
The Makefile understands the usual CFLAGS and DESTDIR parameters
|
||||||
BIN
sfxr/ld48.tga
Normal file
BIN
sfxr/ld48.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
1419
sfxr/main.cpp
Normal file
1419
sfxr/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
163
sfxr/readme.txt
Normal file
163
sfxr/readme.txt
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
-----------------------------
|
||||||
|
sfxr - sound effect generator
|
||||||
|
-----------------------------
|
||||||
|
by DrPetter, 2007-12-14
|
||||||
|
developed for LD48#10
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Basic usage:
|
||||||
|
|
||||||
|
Start the application, then hit
|
||||||
|
some of the buttons on the left
|
||||||
|
side to generate random sounds
|
||||||
|
matching the button descriptions.
|
||||||
|
|
||||||
|
Press "Export .WAV" to save the
|
||||||
|
current sound as a WAV audio file.
|
||||||
|
Click the buttons below to change
|
||||||
|
WAV format in terms of bits per
|
||||||
|
sample and sample rate.
|
||||||
|
|
||||||
|
If you find a sound that is sort
|
||||||
|
of interesting but not quite what
|
||||||
|
you want, you can drag some sliders
|
||||||
|
around until it sounds better.
|
||||||
|
|
||||||
|
The Randomize button generates
|
||||||
|
something completely random.
|
||||||
|
|
||||||
|
Mutate slightly alters the current
|
||||||
|
parameters to automatically create
|
||||||
|
a variation of the sound.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Advanced usage:
|
||||||
|
|
||||||
|
Figure out what each slider does and
|
||||||
|
use them to adjust particular aspects
|
||||||
|
of the current sound...
|
||||||
|
|
||||||
|
Press the right mouse button on a slider
|
||||||
|
to reset it to a value of zero.
|
||||||
|
|
||||||
|
Press Space or Enter to play the current sound.
|
||||||
|
|
||||||
|
The Save/Load sound buttons allow saving
|
||||||
|
and loading of program parameters to work
|
||||||
|
on a sound over several sessions.
|
||||||
|
|
||||||
|
Volume setting is saved with the sound and
|
||||||
|
exported to WAV. If you increase it too much
|
||||||
|
there's a risk of clipping.
|
||||||
|
|
||||||
|
Some parameters influence the sound during
|
||||||
|
playback (particularly when using a non-zero
|
||||||
|
repeat speed), and dragging these sliders
|
||||||
|
can cause some interesting effects.
|
||||||
|
To record this you will need to use an external
|
||||||
|
recording application, for instance Audacity.
|
||||||
|
Set the recording source in that application
|
||||||
|
to "Wave", "Stereo Mix", "Mixed Output" or similar.
|
||||||
|
|
||||||
|
Using an external sound editor to capture and edit
|
||||||
|
sound can also be used to string several sounds
|
||||||
|
together for more complex results.
|
||||||
|
|
||||||
|
Parameter description:
|
||||||
|
- The top four buttons select base waveform
|
||||||
|
- First four parameters control the volume envelope
|
||||||
|
Attack is the beginning of the sound,
|
||||||
|
longer attack means a smoother start.
|
||||||
|
Sustain is how long the volume is held constant
|
||||||
|
before fading out.
|
||||||
|
Increase Sustain Punch to cause a popping
|
||||||
|
effect with increased (and falling) volume
|
||||||
|
during the sustain phase.
|
||||||
|
Decay is the fade-out time.
|
||||||
|
- Next six are for controlling the sound pitch or
|
||||||
|
frequency.
|
||||||
|
Start frequency is pretty obvious. Has a large
|
||||||
|
impact on the overall sound.
|
||||||
|
Min frequency represents a cutoff that stops all
|
||||||
|
sound if it's passed during a downward slide.
|
||||||
|
Slide sets the speed at which the frequency should
|
||||||
|
be swept (up or down).
|
||||||
|
Delta slide is the "slide of slide", or rate of change
|
||||||
|
in the slide speed.
|
||||||
|
Vibrato depth/speed makes for an oscillating
|
||||||
|
frequency effect at various strengths and rates.
|
||||||
|
- Then we have two parameters for causing an abrupt
|
||||||
|
change in pitch after a ceratin delay.
|
||||||
|
Amount is pitch change (up or down)
|
||||||
|
and Speed indicates time to wait before changing
|
||||||
|
the pitch.
|
||||||
|
- Following those are two parameters specific to the
|
||||||
|
squarewave waveform.
|
||||||
|
The duty cycle of a square describes its shape
|
||||||
|
in terms of how large the positive vs negative
|
||||||
|
sections are. It can be swept up or down by
|
||||||
|
changing the second parameter.
|
||||||
|
- Repeat speed, when not zero, causes the frequency
|
||||||
|
and duty parameters to be reset at regular intervals
|
||||||
|
while the envelope and filter continue unhindered.
|
||||||
|
This can make for some interesting pulsating effects.
|
||||||
|
- Phaser offset overlays a delayed copy of the audio
|
||||||
|
stream on top of itself, resulting in a kind of tight
|
||||||
|
reverb or sci-fi effect.
|
||||||
|
This parameter can also be swept like many others.
|
||||||
|
- Finally, the bottom five sliders control two filters
|
||||||
|
which are applied after all other effects.
|
||||||
|
The first one is a resonant lowpass filter which has
|
||||||
|
a sweepable cutoff frequency.
|
||||||
|
The other is a highpass filter which can be used to
|
||||||
|
remove undesired low frequency hum in "light" sounds.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Basically, I don't care what you do with it, anything goes.
|
||||||
|
|
||||||
|
To please all the troublesome folks who request a formal license,
|
||||||
|
I attach the "MIT license" as follows:
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
Copyright (c) 2007 Tomas Pettersson
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
http://www.drpetter.se
|
||||||
|
|
||||||
|
drpetter@gmail.com
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
|
||||||
174
sfxr/sdlkit.h
Normal file
174
sfxr/sdlkit.h
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#ifndef SDLKIT_H
|
||||||
|
#define SDLKIT_H
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#define ERROR(x) error(__FILE__, __LINE__, #x)
|
||||||
|
#define VERIFY(x) do { if (!(x)) ERROR(x); } while (0)
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void error (const char *file, unsigned int line, const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[!] %s:%u %s\n", file, line, msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Uint32 DWORD;
|
||||||
|
typedef Uint16 WORD;
|
||||||
|
|
||||||
|
#define DIK_SPACE SDLK_SPACE
|
||||||
|
#define DIK_RETURN SDLK_RETURN
|
||||||
|
#define DIK_Z SDLK_z
|
||||||
|
#define DDK_WINDOW 0
|
||||||
|
|
||||||
|
#define hWndMain 0
|
||||||
|
#define hInstanceMain 0
|
||||||
|
|
||||||
|
#define Sleep(x) SDL_Delay(x)
|
||||||
|
|
||||||
|
static bool keys[SDLK_LAST];
|
||||||
|
|
||||||
|
void ddkInit(); // Will be called on startup
|
||||||
|
bool ddkCalcFrame(); // Will be called every frame, return true to continue running or false to quit
|
||||||
|
void ddkFree(); // Will be called on shutdown
|
||||||
|
|
||||||
|
class DPInput {
|
||||||
|
public:
|
||||||
|
DPInput(int,int) {}
|
||||||
|
~DPInput() {}
|
||||||
|
static void Update () {}
|
||||||
|
|
||||||
|
static bool KeyPressed(SDLKey key)
|
||||||
|
{
|
||||||
|
bool r = keys[key];
|
||||||
|
keys[key] = false;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static Uint32 *ddkscreen32;
|
||||||
|
static Uint16 *ddkscreen16;
|
||||||
|
static int ddkpitch;
|
||||||
|
static int mouse_x, mouse_y, mouse_px, mouse_py;
|
||||||
|
static bool mouse_left = false, mouse_right = false, mouse_middle = false;
|
||||||
|
static bool mouse_leftclick = false, mouse_rightclick = false, mouse_middleclick = false;
|
||||||
|
|
||||||
|
static SDL_Surface *sdlscreen = NULL;
|
||||||
|
|
||||||
|
static void sdlupdate ()
|
||||||
|
{
|
||||||
|
mouse_px = mouse_x;
|
||||||
|
mouse_py = mouse_y;
|
||||||
|
Uint8 buttons = SDL_GetMouseState(&mouse_x, &mouse_y);
|
||||||
|
bool mouse_left_p = mouse_left;
|
||||||
|
bool mouse_right_p = mouse_right;
|
||||||
|
bool mouse_middle_p = mouse_middle;
|
||||||
|
mouse_left = buttons & SDL_BUTTON(1);
|
||||||
|
mouse_right = buttons & SDL_BUTTON(3);
|
||||||
|
mouse_middle = buttons & SDL_BUTTON(2);
|
||||||
|
mouse_leftclick = mouse_left && !mouse_left_p;
|
||||||
|
mouse_rightclick = mouse_right && !mouse_right_p;
|
||||||
|
mouse_middleclick = mouse_middle && !mouse_middle_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ddkLock ()
|
||||||
|
{
|
||||||
|
SDL_LockSurface(sdlscreen);
|
||||||
|
ddkpitch = sdlscreen->pitch / (sdlscreen->format->BitsPerPixel == 32 ? 4 : 2);
|
||||||
|
ddkscreen16 = (Uint16*)(sdlscreen->pixels);
|
||||||
|
ddkscreen32 = (Uint32*)(sdlscreen->pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ddkUnlock ()
|
||||||
|
{
|
||||||
|
SDL_UnlockSurface(sdlscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ddkSetMode (int width, int height, int bpp, int refreshrate, int fullscreen, const char *title)
|
||||||
|
{
|
||||||
|
VERIFY(sdlscreen = SDL_SetVideoMode(width, height, bpp, fullscreen ? SDL_FULLSCREEN : 0));
|
||||||
|
SDL_WM_SetCaption(title, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
static char *gtkfilename;
|
||||||
|
|
||||||
|
static void selected_file (GtkWidget *button, GtkFileSelection *fs)
|
||||||
|
{
|
||||||
|
strncpy(gtkfilename, gtk_file_selection_get_filename(fs), 255);
|
||||||
|
gtkfilename[255] = 0;
|
||||||
|
gtk_widget_destroy(GTK_WIDGET(fs));
|
||||||
|
gtk_main_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool select_file (char *buf)
|
||||||
|
{
|
||||||
|
gtkfilename = buf;
|
||||||
|
GtkWidget *dialog = gtk_file_selection_new("It's file selection time!");
|
||||||
|
g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dialog)->ok_button), "clicked", G_CALLBACK(selected_file), G_OBJECT(dialog));
|
||||||
|
g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(dialog)->cancel_button), "clicked", G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog));
|
||||||
|
gtk_widget_show(GTK_WIDGET(dialog));
|
||||||
|
gtk_main();
|
||||||
|
return *gtkfilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FileSelectorLoad(x,file,y) select_file(file)
|
||||||
|
#define FileSelectorSave(x,file,y) select_file(file)
|
||||||
|
|
||||||
|
static void sdlquit ()
|
||||||
|
{
|
||||||
|
ddkFree();
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sdlinit ()
|
||||||
|
{
|
||||||
|
SDL_Surface *icon;
|
||||||
|
VERIFY(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO));
|
||||||
|
icon = SDL_LoadBMP("/usr/share/sfxr/sfxr.bmp");
|
||||||
|
if (!icon)
|
||||||
|
icon = SDL_LoadBMP("sfxr.bmp");
|
||||||
|
if (icon)
|
||||||
|
SDL_WM_SetIcon(icon, NULL);
|
||||||
|
atexit(sdlquit);
|
||||||
|
memset(keys, 0, sizeof(keys));
|
||||||
|
ddkInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loop (void)
|
||||||
|
{
|
||||||
|
SDL_Event e;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
SDL_PollEvent(&e);
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
keys[e.key.keysym.sym] = true;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
sdlupdate();
|
||||||
|
if (!ddkCalcFrame())
|
||||||
|
return;
|
||||||
|
SDL_Flip(sdlscreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
sdlinit();
|
||||||
|
loop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
sfxr/sfxr.bmp
Normal file
BIN
sfxr/sfxr.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
9
sfxr/sfxr.desktop
Normal file
9
sfxr/sfxr.desktop
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=sfxr
|
||||||
|
Comment=Generate sound effects
|
||||||
|
Exec=sfxr
|
||||||
|
Icon=sfxr
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=false
|
||||||
|
Type=Application
|
||||||
|
Categories=AudioVideo;Audio;AudioVideoEditing;
|
||||||
BIN
sfxr/sfxr.png
Normal file
BIN
sfxr/sfxr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 890 B |
134
sfxr/tools.h
Normal file
134
sfxr/tools.h
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
int LoadTGA(Spriteset& tiles, const char *filename)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
unsigned char byte, crap[16], id_length;
|
||||||
|
int n, width, height, channels, x, y;
|
||||||
|
file=fopen(filename, "rb");
|
||||||
|
if (!file)
|
||||||
|
return -1;
|
||||||
|
fread(&id_length, 1, 1, file);
|
||||||
|
fread(crap, 1, 11, file);
|
||||||
|
width=0;
|
||||||
|
height=0;
|
||||||
|
fread(&width, 1, 2, file); // width
|
||||||
|
fread(&height, 1, 2, file); // height
|
||||||
|
fread(&byte, 1, 1, file); // bits
|
||||||
|
channels=byte/8;
|
||||||
|
fread(&byte, 1, 1, file); // image descriptor byte (per-bit info)
|
||||||
|
for(n=0;n<id_length;n++)
|
||||||
|
fread(&byte, 1, 1, file); // image description
|
||||||
|
tiles.data=(DWORD*)malloc(width*height*sizeof(DWORD));
|
||||||
|
for(y=height-1;y>=0;y--)
|
||||||
|
for(x=0;x<width;x++)
|
||||||
|
{
|
||||||
|
DWORD pixel=0;
|
||||||
|
fread(&byte, 1, 1, file);
|
||||||
|
pixel|=byte;
|
||||||
|
fread(&byte, 1, 1, file);
|
||||||
|
pixel|=byte<<8;
|
||||||
|
fread(&byte, 1, 1, file);
|
||||||
|
pixel|=byte<<16;
|
||||||
|
tiles.data[y*width+x]=pixel;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
tiles.height=height;
|
||||||
|
tiles.width=height;
|
||||||
|
tiles.pitch=width;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearScreen(DWORD color)
|
||||||
|
{
|
||||||
|
for(int y=0;y<480;y++)
|
||||||
|
{
|
||||||
|
int offset=y*ddkpitch;
|
||||||
|
for(int x=0;x<640;x+=8)
|
||||||
|
{
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawBar(int sx, int sy, int w, int h, DWORD color)
|
||||||
|
{
|
||||||
|
for(int y=sy;y<sy+h;y++)
|
||||||
|
{
|
||||||
|
int offset=y*ddkpitch+sx;
|
||||||
|
int x1=0;
|
||||||
|
if(w>8)
|
||||||
|
for(x1=0;x1<w-8;x1+=8)
|
||||||
|
{
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
}
|
||||||
|
for(int x=x1;x<w;x++)
|
||||||
|
ddkscreen32[offset++]=color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawBox(int sx, int sy, int w, int h, DWORD color)
|
||||||
|
{
|
||||||
|
DrawBar(sx, sy, w, 1, color);
|
||||||
|
DrawBar(sx, sy, 1, h, color);
|
||||||
|
DrawBar(sx+w, sy, 1, h, color);
|
||||||
|
DrawBar(sx, sy+h, w+1, 1, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSprite(Spriteset& sprites, int sx, int sy, int i, DWORD color)
|
||||||
|
{
|
||||||
|
for(int y=0;y<sprites.height;y++)
|
||||||
|
{
|
||||||
|
int offset=(sy+y)*ddkpitch+sx;
|
||||||
|
int spoffset=y*sprites.pitch+i*sprites.width;
|
||||||
|
if(color&0xFF000000)
|
||||||
|
for(int x=0;x<sprites.width;x++)
|
||||||
|
{
|
||||||
|
DWORD p=sprites.data[spoffset++];
|
||||||
|
if(p!=0x300030)
|
||||||
|
ddkscreen32[offset+x]=p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(int x=0;x<sprites.width;x++)
|
||||||
|
{
|
||||||
|
DWORD p=sprites.data[spoffset++];
|
||||||
|
if(p!=0x300030)
|
||||||
|
ddkscreen32[offset+x]=color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawText(int sx, int sy, DWORD color, const char *string, ...)
|
||||||
|
{
|
||||||
|
char string2[256];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, string);
|
||||||
|
vsprintf(string2, string, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
int len=strlen(string2);
|
||||||
|
for(int i=0;i<len;i++)
|
||||||
|
DrawSprite(font, sx+i*8, sy, string2[i]-' ', color);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseInBox(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if(mouse_x>=x && mouse_x<x+w && mouse_y>=y && mouse_y<y+h)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user