Skip to content

Commit

Permalink
a2play can now play waves with the -p switch
Browse files Browse the repository at this point in the history
a2play will now detect if -p is trying to play a wave, in which case it
generates and compiles and wrapper program that is then used in place of
the wave, so that it can be played like a simple "instrument" program.

Added a fallback to the A2_ROOTBANK module when a symbol isn't found in
the supposedly loaded module. This allows the -p switch and similar, to
use builtin programs, waves etc.

If no module is loaded, a2play creates a module "a2play empty module", so
that other operations will still work where applicable. (The -p switch
uses this module as a container, to manage any generated programs.)

Closes #310.
  • Loading branch information
olofson committed Jan 14, 2017
1 parent 5df40cb commit dd7ad12
Showing 1 changed file with 55 additions and 4 deletions.
59 changes: 55 additions & 4 deletions a2play/a2play.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,36 @@ static void load_sounds(int argc, const char *argv[])
Playing
-------------------------------------------------------------------*/

#define A2P_WPNAME "a2play_waveplayer"

static const char *waveplayer =
"export " A2P_WPNAME "(P V=1)\n"
"{\n"
" struct {\n"
" wtosc\n"
" panmix\n"
" }\n"
" w %d\n"
" @p P\n"
" @a V\n"
" 1() { a 0; ramp a 100 }\n"
"}\n";

/* Generate and compile a player program for a wave */
static A2_handle wrap_wave(A2_handle wave)
{
A2_handle wp;
int bsize = strlen(waveplayer) + 20;
char *buf = malloc(bsize);
if(!buf)
return -A2_OOMEMORY;
snprintf(buf, bsize, waveplayer, wave);
wp = a2_LoadString(iface, buf, "a2play_waveplayer_module");
a2_Assign(iface, module, wp);
return a2_Get(iface, wp, A2P_WPNAME);
}


/* Parse the body of a -p or -M switch; <name>[,pitch[,vel[,mod[,...]]]] */
static int play_sound(const char *cmd, int midihandler)
{
Expand All @@ -335,17 +365,30 @@ static int play_sound(const char *cmd, int midihandler)
}
if((h = a2_Get(iface, module, program)) < 0)
{
fprintf(stderr, "a2play: a2_Get(\"%s\"): %s\n", program,
a2_ErrorString(-h));
return -2;
/* Fall back to the root module */
if((h = a2_Get(iface, A2_ROOTBANK, program)) < 0)
{
fprintf(stderr, "a2play: a2_Get(\"%s\"): %s\n",
program, a2_ErrorString(-h));
return -2;
}
}
if(a2_TypeOf(iface, h) == A2_TWAVE)
{
if((h = wrap_wave(h)) < 0)
{
fprintf(stderr, "a2play: wrap_wave(): %s\n",
a2_ErrorString(-h));
return -3;
}
}
for(i = 0; i < cnt - 1; ++i)
ia[i] = a[i] * 65536.0f;
if((vh = a2_Starta(iface, a2_RootVoice(iface), h, cnt - 1, ia)) < 0)
{
fprintf(stderr, "a2play: a2_Starta(): %s\n",
a2_ErrorString(-vh));
return -3;
return -4;
}
if(midihandler)
a2_MIDIHandler(iface, NULL, -1, vh);
Expand Down Expand Up @@ -670,6 +713,14 @@ int main(int argc, const char *argv[])
free(buf);
}

/* If we don't have a module at this point, create an empty one */
if(module < 0)
{
module = a2_LoadString(iface, "//", "a2play empty module");
if(module >= 0)
a2_Export(iface, A2_ROOTBANK, module, NULL);
}

/* Dump exports, code etc, if requested */
dump_exports();

Expand Down

0 comments on commit dd7ad12

Please sign in to comment.