Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 50 additions & 45 deletions .depend
Original file line number Diff line number Diff line change
@@ -1,50 +1,55 @@
# DO NOT DELETE

raw2disk.o: sample.h
readsample.o: conv_ieee_ext.h sample.h voncendian.h
controls.o: gpm-xterm.h semaphore.h controls.h radio.h
fileselect.o: placement.h sample.h controls.h radio.h alert.h fileselect.h
alert.o: controls.h radio.h alert.h
raw2disk.o: config.h sample.h
readsample.o: conv_ieee_ext.h config.h sample.h voncendian.h
controls.o: config.h gpm-xterm.h semaphore.h controls.h radio.h
fileselect.o: config.h placement.h sample.h controls.h radio.h alert.h
fileselect.o: fileselect.h
alert.o: config.h controls.h radio.h alert.h
tokenio.o: tokenio.h controls.h radio.h voncendian.h
grov_io.o: sample.h readsample.h tokenio.h grov_io.h grpattern.h radio.h
grov_io.o: grevents.h grsequence.h granalogik.h resoanlog.h grdyfilter.h
grov_io.o: grdelay.h constants.h controls.h groovit.h menu_board.h grmixeur.h
grov_io.o: voncendian.h
grov_io.o: config.h sample.h readsample.h tokenio.h grov_io.h grpattern.h
grov_io.o: radio.h grevents.h grsequence.h granalogik.h resoanlog.h
grov_io.o: grdyfilter.h grdelay.h constants.h controls.h groovit.h
grov_io.o: menu_board.h grmixeur.h voncendian.h
gpm-xterm.o: gpm-xterm.h
settings.o: sample.h grov_io.h placement.h controls.h radio.h fileselect.h
settings.o: settings.h
dialogs.o: sample.h placement.h controls.h radio.h alert.h fileselect.h
dialogs.o: grsel.h menu_board.h resoanlog.h grpattern.h grevents.h
dialogs.o: grsequence.h grdyfilter.h settings.h groovit.h constants.h
grsel.o: sample.h placement.h controls.h radio.h alert.h fileselect.h
grsel.o: readsample.h grov_io.h raw2disk.h menu_board.h resoanlog.h
grsel.o: grpattern.h grevents.h grsequence.h grdyfilter.h groovit.h
grsel.o: constants.h
grpattern.o: controls.h radio.h sample.h readsample.h placement.h groovit.h
grpattern.o: constants.h grlevels.h grmixeur.h menu_board.h resoanlog.h
grpattern.o: grpattern.h grevents.h grsequence.h grdyfilter.h
granalogik.o: controls.h radio.h sample.h placement.h grlevels.h grmixeur.h
granalogik.o: groovit.h constants.h menu_board.h resoanlog.h grpattern.h
granalogik.o: grevents.h grsequence.h grdyfilter.h granalogik.h
menu_board.o: sample.h placement.h controls.h radio.h dialogs.h grsel.h
menu_board.o: settings.h grpattern.h grevents.h grsequence.h granalogik.h
menu_board.o: resoanlog.h grdyfilter.h grdelay.h constants.h grlevels.h
menu_board.o: grderiv.h groovit.h menu_board.h
resoanlog.o: resoanlog.h radio.h sample.h placement.h groovit.h constants.h
grdelay.o: controls.h radio.h sample.h placement.h grlevels.h grmixeur.h
grdelay.o: groovit.h constants.h grdelay.h
grmixeur.o: grlevels.h grmixeur.h
grlevels.o: sample.h placement.h controls.h radio.h grmixeur.h grlevels.h
grdyfilter.o: controls.h radio.h sample.h placement.h groovit.h constants.h
grdyfilter.o: menu_board.h resoanlog.h grpattern.h grevents.h grsequence.h
grdyfilter.o: grdyfilter.h grmixeur.h grlevels.h granalogik.h
groovit.o: placement.h tokenio.h grov_io.h raw2disk.h sample.h readsample.h
groovit.o: controls.h radio.h menu_board.h resoanlog.h grpattern.h grevents.h
groovit.o: grsequence.h grdyfilter.h settings.h dialogs.h grsel.h grmixeur.h
groovit.o: granalogik.h grdelay.h constants.h grderiv.h groovit.h
grderiv.o: controls.h radio.h sample.h placement.h grlevels.h grmixeur.h
grderiv.o: groovit.h constants.h grderiv.h
settings.o: config.h sample.h grov_io.h placement.h controls.h radio.h
settings.o: fileselect.h settings.h
dialogs.o: config.h sample.h placement.h controls.h radio.h alert.h
dialogs.o: fileselect.h grsel.h menu_board.h resoanlog.h grpattern.h
dialogs.o: grevents.h grsequence.h grdyfilter.h settings.h groovit.h
dialogs.o: constants.h
grsel.o: config.h sample.h placement.h controls.h radio.h alert.h
grsel.o: fileselect.h readsample.h grov_io.h raw2disk.h menu_board.h
grsel.o: resoanlog.h grpattern.h grevents.h grsequence.h grdyfilter.h
grsel.o: groovit.h constants.h
grpattern.o: config.h controls.h radio.h sample.h readsample.h placement.h
grpattern.o: groovit.h constants.h grlevels.h grmixeur.h menu_board.h
grpattern.o: resoanlog.h grpattern.h grevents.h grsequence.h grdyfilter.h
granalogik.o: config.h controls.h radio.h sample.h placement.h grlevels.h
granalogik.o: grmixeur.h groovit.h constants.h menu_board.h resoanlog.h
granalogik.o: grpattern.h grevents.h grsequence.h grdyfilter.h granalogik.h
menu_board.o: config.h sample.h placement.h controls.h radio.h dialogs.h
menu_board.o: grsel.h settings.h grpattern.h grevents.h grsequence.h
menu_board.o: granalogik.h resoanlog.h grdyfilter.h grdelay.h constants.h
menu_board.o: grlevels.h grderiv.h groovit.h menu_board.h
resoanlog.o: config.h resoanlog.h radio.h sample.h placement.h groovit.h
resoanlog.o: constants.h
grdelay.o: config.h controls.h radio.h sample.h placement.h grlevels.h
grdelay.o: grmixeur.h groovit.h constants.h grdelay.h
grmixeur.o: config.h grlevels.h grmixeur.h
grlevels.o: config.h sample.h placement.h controls.h radio.h grmixeur.h
grlevels.o: grlevels.h
grdyfilter.o: config.h controls.h radio.h sample.h placement.h groovit.h
grdyfilter.o: constants.h menu_board.h resoanlog.h grpattern.h grevents.h
grdyfilter.o: grsequence.h grdyfilter.h grmixeur.h grlevels.h granalogik.h
groovit.o: config.h placement.h tokenio.h grov_io.h raw2disk.h sample.h
groovit.o: readsample.h controls.h radio.h menu_board.h resoanlog.h
groovit.o: grpattern.h grevents.h grsequence.h grdyfilter.h settings.h
groovit.o: dialogs.h grsel.h grmixeur.h granalogik.h grdelay.h constants.h
groovit.o: grderiv.h groovit.h
grderiv.o: config.h controls.h radio.h sample.h placement.h grlevels.h
grderiv.o: grmixeur.h groovit.h constants.h grderiv.h
grevents.o: grevents.h
grsequence.o: placement.h controls.h radio.h groovit.h constants.h sample.h
grsequence.o: grpattern.h grevents.h grsequence.h granalogik.h resoanlog.h
grsequence.o: grdyfilter.h
grsequence.o: config.h placement.h controls.h radio.h groovit.h constants.h
grsequence.o: sample.h grpattern.h grevents.h grsequence.h granalogik.h
grsequence.o: resoanlog.h grdyfilter.h
27 changes: 4 additions & 23 deletions Configure
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ echo "a few question to Configure it all good..."
echo "in a pintch just press RETURN for the default answer in [bracket]."
echo

VERSION='1.5'
VERSION=`echo $Id: Configure,v 1.2 2003/03/19 16:45:47 jd Exp $ | cut -d' ' -f3`
FINAL=groovit
PREFIX=/usr/local
LIBDIR=$PREFIX/lib/groovit
Expand Down Expand Up @@ -687,18 +687,6 @@ else
CURSESLIB=" "
fi

echo looking for jack ...
if pkg-config --exists jack
then
echo will build with jack.
JACKLIBS=" "`pkg-config --cflags --libs jack`" "
HAVE_JACK='Y'
else
echo pkg-config didn"'"t find jack.
JACKLIBS=" "
HAVE_JACK='N'
fi

echo -n "checking termios, "
rm -f testtermios.c testtermios.out testtermios
echo -e "#include <termios.h>\n#define JDCTRL(x) (x&037)\nint main (void)\n{ char c;\nstruct termios caracs;\ntcgetattr (0, &caracs);\nc=caracs.c_cc[3];\ncaracs.c_cc[3]=JDCTRL('H');\nif(tcsetattr (0, TCSANOW, &caracs))return 1;\ncaracs.c_cc[3]=c;\nif(tcsetattr (0, TCSANOW, &caracs))return 1;\nreturn 0;\n}"> testtermios.c
Expand Down Expand Up @@ -849,7 +837,7 @@ then
fi
fi

readit "want to zero input level of all recording devices when playin' ?" "n"
readit "want to zero input level of all recording devices when playin' ?" "y"
ZEROINGINPUT=$VALUE
if [ $ZEROINGINPUT = "y" ]
then
Expand Down Expand Up @@ -1026,12 +1014,6 @@ else
echo "#define HAVECURSES"
fi
fi
if [ $HAVE_JACK = "y" ]
then
echo "#define HAVE_JACK 1"
else
echo "/* #define HAVE_JACK 1 */"
fi
if [ $HAVE_LIBGPM = "y" ]
then
echo "#define HAVE_LIBGPM 1"
Expand Down Expand Up @@ -1164,8 +1146,7 @@ echo -n "generating additlib ... "
echo -n " -lgpm "
fi

echo -n "$CURSESLIB"
echo -n "$JACKLIBS"
echo -n $CURSESLIB
) > ./additlib
echo " ...done : will link with " `cat ./additlib`
echo
Expand All @@ -1177,7 +1158,7 @@ then
mv installer installer.bak
fi
echo -n "generating installer ... "
( echo '#!/bin/bash'
( echo '#!/bin/sh'
echo 'LIBDIR'=$LIBDIR
echo 'SAMPLEDIR'=$SAMPLEDIR
echo 'DESTDIR'=$DESTDIR
Expand Down
19 changes: 6 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,14 @@
TARDIR = $(HOME)/tar
DICTDIR = $(HOME)
CC = `./.cc`
VERSION = '1.5'
# VERSION = `rlog -r RCS/$(FINAL).c,v | grep "revision " | cut -d' ' -f2 | cut -f1`
VERSION = `rlog -r RCS/$(FINAL).c,v | grep "revision " | cut -d' ' -f2 | cut -f1`
# PSEUDO =
# PSEUDO = "����-��"
PSEUDO = walden
# PSEUDO = "����-��"
PSEUDO = telaviv
CC_OBJ = -c
# CC_STAMP = -DCCUNAMED="\"`uname -n` `uname -s` `uname -r`\"" -DCCCONFEDBY="\"`whoami` `date "+%d-%m-%Y %H:%M"`\""
CC_STAMP = -DCCUNAMED="\"`./.inu`\"" -DCCCONFEDBY="\"`./.woa`\""
CC_OPTIONS = -g -Winline -Wall -O3
CC_OPTIONS = -g -Winline -Wall -O3 -fcommon

## CC_DEBUG = -g -DFAKEDSP
## CC_DEBUG = -DFAKEDSP
Expand All @@ -92,10 +91,8 @@
# CTAGS = ccproc -t
SHELL = /bin/sh

default: $(FINAL)

# .h.c:
# ls $@ | grep $@ > /dev/null 2> /dev/null || co $@
.h.c:
ls $@ | grep $@ > /dev/null 2> /dev/null || co $@

.c.o:
@echo
Expand All @@ -112,10 +109,6 @@ test: all
@echo
./$(FINAL) -fixedpos 40+40 test.grov && echo fini || ./$(FINAL) -fixedpos 40+40 test.grov -fakedsp

vimtest: all
# xterm +lc +u8 -fn 10x20 -bg black -fg white -geometry 80x25+40+40 -e ./groovit -noX
./$(FINAL) -fixedpos 40+40 -jack | tr ':' '='

$(FINAL): $(OBJ) additlib $(OBJBIS)
@echo
$(CC) $(CC_OPTIONS) $(CC_STAMP) -o $(FINAL) $(OBJ) $(ADDITLIB) $(LIB)
Expand Down
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Groovit

**Making accurate and groovy sound/noise.**

Groovit is an all-in-a-box beat-box for Linux. It runs in any ANSI terminal and its main parts are:

- **Drum matrix** — step-sequencer for sample-based drum voices
- **Analog synth voices** — oscillator-based synthesis with envelopes
- **Dynamic filter** — resonant filter with envelope control
- **Mixer** — per-voice volume and pan

Songs are stored as `.grov` files. Samples are read from WAV and AIFF files.

## Building on modern Linux

### Dependencies

```sh
sudo apt install build-essential libncurses-dev oss-compat alsa-oss
```

### Compile

```sh
make config # interactive configuration
make # compile
```

For a non-interactive build:

```sh
make fastconfig && make
```

> **GCC 10+ note:** GCC 10 changed the default to `-fno-common`, which breaks this codebase.
> The Makefile includes `-fcommon` to restore the previous behaviour.

### Run

OSS audio (`/dev/dsp`) is required. On modern ALSA-only systems, load the OSS
compatibility module first, then use `aoss`:

```sh
sudo modprobe snd-pcm-oss
aoss ./groovit myfile.grov
```

To avoid running `modprobe` on every boot, add it to your modules:

```sh
echo snd-pcm-oss | sudo tee /etc/modules-load.d/oss.conf
```

## Usage

```sh
groovit [options] [start-file.grov ...]
```

Key options:

| Option | Description |
|--------|-------------|
| `-noX` | Force terminal mode even if `DISPLAY` is set |
| `-fakedsp` | Run without audio (silent mode) |
| `-jack[=name]` | Use JACK audio instead of OSS |
| `-rc rcfile` | Use an alternate config file |
| `-raw file.wav` | Record output to a WAV file |
| `-err filename` | Redirect error messages to a file |

When `DISPLAY` is set, groovit forks into a new xterm automatically. Use `-noX` to stay in the current terminal.

## Install

```sh
sudo make install
```

Installs the binary, man pages and shared samples under `/usr/local` by default.

## File format

`.grov` files are groovit's native song format. See `man 5 grov` after installation.

## License

GNU General Public License v2 — see [GPL.txt](GPL.txt).

Copyright (C) 1998, 1999 Jean-Daniel PAUGET
49 changes: 3 additions & 46 deletions controls.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ typedef struct tjmeta /* la structure de jmeta controls */
}
JMeta;

JMeta jmeta[8]; /* les handles des jmeta */
JMeta jmeta[6]; /* les handles des jmeta */

#ifdef SIMPLE_MEMPROFILE
static long totdivs = 0;
Expand Down Expand Up @@ -651,7 +651,7 @@ void initjmeta (void)
{
int i;

for (i = 0; i < 8; i++)
for (i = 0; i < 6; i++)
clearjmeta (i);
keyhandler[CONTKEY_F1] = 0;
keyhandler[CONTKEY_F2] = 0;
Expand Down Expand Up @@ -713,49 +713,6 @@ void actionnejmeta (int m, int c)
keycontrols (jmeta[m].member[i], c);
}

void actionnedirectjmeta (int m, int val)
{
int i;

for (i = 0; i < jmeta[m].nb; i++)
keydirectcontrols (jmeta[m].member[i], val);
}

int keydirectcontrols (int h, int val) /* returns 0 if the control cannot support direct */
{
int *p = (int *) controls[h].p;

lastpressed = h;
switch (controls[h].type)
{
case CONTRVSLIDE: /* slide vertical - keycontrols */
case CONTRHSLIDE: /* slide horizontal - keycontrols */
if (p != NULL)
{
if (val > 256)
*p = 256;
else if (val < 0)
*p = 0;
else
*p = val;

controls[h].nbmodif++;
if (controls[h].pression != NULL)
controls[h].pression (controls[h].evtype, controls[h].voice, *p);

if (controls[h].associated != CONTUNDEF)
refreshcontrols (controls[h].associated);
refreshcontrols (h);
return (1);
}
break;
default:
return 0;
}

return (0);
}

int keycontrols (int h, int c) /* returns 0 if the char is NOT handled */
{
int *p = (int *) controls[h].p;
Expand Down Expand Up @@ -1165,7 +1122,7 @@ int clickcontrols (int h, int x, int y, int buttons, int focuschanged)
if (focuschanged && sauveh)
addjmeta (0, h);
else
addjmeta ((sauveh + 1) % 8, h);
addjmeta ((sauveh + 1) % 6, h);
break;
}
if (focuschanged && (buttons != 4))
Expand Down
Loading