Ejemplo n.º 1
0
/**
 * \brief read data from buffer and splitting it into channels
 * \param bufs num_bufs float buffers, each will contain the data of one channel
 * \param cnt number of samples to read per channel
 * \param num_bufs number of channels to split the data into
 * \return number of samples read per channel, equals cnt unless there was too
 *         little data in the buffer
 *
 * Assumes the data in the buffer is of type float, the number of bytes
 * read is res * num_bufs * sizeof(float), where res is the return value.
 * If there is not enough data in the buffer remaining parts will be filled
 * with silence.
 */
static int read_buffer(float **bufs, int cnt, int num_bufs) {
  struct deinterleave di = {bufs, num_bufs, 0, 0};
  int buffered = av_fifo_size(buffer);
  if (cnt * sizeof(float) * num_bufs > buffered) {
    silence(bufs, cnt, num_bufs);
    cnt = buffered / sizeof(float) / num_bufs;
  }
  av_fifo_generic_read(buffer, &di, cnt * num_bufs * sizeof(float), deinterleave);
  return cnt;
}
Ejemplo n.º 2
0
/**
 * \brief read data from buffer and splitting it into channels
 * \param bufs num_bufs float buffers, each will contain the data of one channel
 * \param cnt number of samples to read per channel
 * \param num_bufs number of channels to split the data into
 * \return number of samples read per channel, equals cnt unless there was too
 *         little data in the buffer
 *
 * Assumes the data in the buffer is of type float, the number of bytes
 * read is res * num_bufs * sizeof(float), where res is the return value.
 * If there is not enough data in the buffer remaining parts will be filled
 * with silence.
 */
static int read_buffer(struct mp_ring *ring, float **bufs, int cnt, int num_bufs)
{
    struct deinterleave di = {
        bufs, num_bufs, 0, 0
    };
    int buffered = mp_ring_buffered(ring);
    if (cnt * sizeof(float) * num_bufs > buffered) {
        silence(bufs, cnt, num_bufs);
        cnt = buffered / sizeof(float) / num_bufs;
    }
    mp_ring_read_cb(ring, &di, cnt * num_bufs * sizeof(float), deinterleave);
    return cnt;
}
Ejemplo n.º 3
0
void Step::
        test()
{
    // It should keep a cache for a signal processing step (defined by an OpertionDesc).
    //
    // The cache description should contain information about what's out_of_date
    // and what's currently being updated.
    {
        // Create an OperationDesc
        pBuffer b(new Buffer(Interval(60,70), 40, 7));
        for (unsigned c=0; c<b->number_of_channels (); ++c)
        {
            float *p = b->getChannel (c)->waveform_data ()->getCpuMemory ();
            for (int i=0; i<b->number_of_samples (); ++i)
                p[i] = c + 1+i/(float)b->number_of_samples ();
        }

        // Create a Step
        Step::ptr s2( new Step(OperationDesc::ptr()));

        shared_state<Step>::weak_ptr ws = s2;
        Step::ptr s = ws.lock ();

        // It should contain information about what's out_of_date and what's currently being updated.
        int taskid = s->registerTask(b->getInterval ());
        EXCEPTION_ASSERT_EQUALS(s->not_started (), ~Intervals(b->getInterval ()));
        EXCEPTION_ASSERT_EQUALS(s->out_of_date(), Intervals::Intervals_ALL);
        Step::finishTask(s, taskid, b);
        EXCEPTION_ASSERT_EQUALS(s->out_of_date(), ~Intervals(b->getInterval ()));

        EXCEPTION_ASSERT( *b == *Step::readFixedLengthFromCache (s, b->getInterval ()) );
    }

    // A crashed signal processing step should behave as a transparent operation.
    {
        OperationDesc::ptr silence(new Signal::OperationSetSilent(Signal::Interval(2,3)));
        Step s(silence);
        EXCEPTION_ASSERT(!s.get_crashed ());
        EXCEPTION_ASSERT(s.operation_desc ());
        EXCEPTION_ASSERT(s.operation_desc ().read ()->createOperation (0));
        EXCEPTION_ASSERT(!dynamic_cast<Test::TransparentOperationDesc*>(s.operation_desc ().raw ()));
        EXCEPTION_ASSERT(!dynamic_cast<Test::TransparentOperation*>(s.operation_desc ().read ()->createOperation (0).get ()));
        s.mark_as_crashed_and_get_invalidator ();
        EXCEPTION_ASSERT(s.get_crashed ());
        EXCEPTION_ASSERT(s.operation_desc ());
        EXCEPTION_ASSERT(s.operation_desc ().read ()->createOperation (0));
        EXCEPTION_ASSERT(dynamic_cast<Test::TransparentOperationDesc*>(s.operation_desc ().raw ()));
        EXCEPTION_ASSERT(dynamic_cast<Test::TransparentOperation*>(s.operation_desc ().read ()->createOperation (0).get ()));
    }
}
Ejemplo n.º 4
0
/**
 * \brief JACK Callback function
 * \param nframes number of frames to fill into buffers
 * \param arg unused
 * \return currently always 0
 *
 * Write silence into buffers if paused or an underrun occured
 */
static int outputaudio(jack_nframes_t nframes, void *arg) {
    float *bufs[MAX_CHANS];
    int i;
    for (i = 0; i < num_ports; i++)
        bufs[i] = jack_port_get_buffer(ports[i], nframes);
    if (paused || underrun)
        silence(bufs, nframes, num_ports);
    else if (read_buffer(bufs, nframes, num_ports) < nframes)
        underrun = 1;
    if (estimate) {
        float now = (float)GetTimer() / 1000000.0;
        float diff = callback_time + callback_interval - now;
        if ((diff > -0.002) && (diff < 0.002))
            callback_time += callback_interval;
        else
            callback_time = now;
        callback_interval = (float)nframes / (float)ao_data.samplerate;
    }
    return 0;
}
Ejemplo n.º 5
0
void
LADSPAPluginInstance::setIdealChannelCount(size_t channels)
{
    if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) {
        silence();
        return ;
    }

    if (isOK()) {
        deactivate();
    }

    //!!! don't we need to reallocate inputBuffers and outputBuffers?

    cleanup();
    m_instanceCount = channels;
    instantiate(m_sampleRate);
    if (isOK()) {
        connectPorts();
        activate();
    }
}
Ejemplo n.º 6
0
/**
 * \brief JACK Callback function
 * \param nframes number of frames to fill into buffers
 * \param arg unused
 * \return currently always 0
 *
 * Write silence into buffers if paused or an underrun occured
 */
static int outputaudio(jack_nframes_t nframes, void *arg)
{
    struct ao *ao = arg;
    struct priv *p = ao->priv;
    float *bufs[MAX_CHANS];
    int i;
    for (i = 0; i < p->num_ports; i++)
        bufs[i] = jack_port_get_buffer(p->ports[i], nframes);
    if (p->paused || p->underrun || !p->ring)
        silence(bufs, nframes, p->num_ports);
    else if (read_buffer(p->ring, bufs, nframes, p->num_ports) < nframes)
        p->underrun = 1;
    if (p->estimate) {
        float now = mp_time_us() / 1000000.0;
        float diff = p->callback_time + p->callback_interval - now;
        if ((diff > -0.002) && (diff < 0.002))
            p->callback_time += p->callback_interval;
        else
            p->callback_time = now;
        p->callback_interval = (float)nframes / (float)ao->samplerate;
    }
    return 0;
}
Ejemplo n.º 7
0
	PlayScene::PlayScene() : Scene(), lastDrawTicks(0), lastBlockMove(0), lastTickEvent(0), level(1), lines(0), score(0), blocks(NULL), background(NULL), fallingBlock(NULL), nextBlock(NULL)
	{
		Player * player = Player::get( "Player" );
		
		if( player != NULL )
			player->setEventHandler( new PlaySceneEventHandler( this ) );
			
		else
		{
			#ifdef DEBUG1
			Logger::get() << "[PlayScene] No player found. Exiting." << Logger::endl;
			#endif
			
			this->running = false;
		}
		
		// Initializing random seed
		srand( time(NULL) );
		
		// Creating game song
		Sine instrument( Mixer::get()->getSamplingFrequency(), Mixer::get()->getChannels() );
		Silence silence( Mixer::get()->getSamplingFrequency(), Mixer::get()->getChannels() );
		Song * song = new Song( 120, Mixer::get()->getSamplingFrequency(), Mixer::get()->getChannels() );
	
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Blanche );
		
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'F', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'G', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'F', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Noire, true );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'B', false, 4 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Croche );
		song->mixNote( instrument, Note::getFrequency( 'D', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'E', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'C', false, 5 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Noire );
		song->mixNote( instrument, Note::getFrequency( 'A', false, 4 ), Note::Blanche );
		
		Mixer::get()->add( "BlockgameSong", song );
		delete song;
		Mixer::get()->setRepeat( "BlockgameSong", true );
		
		// Creating grid
		this->blocks = new Grid( GRID_WIDTH, GRID_HEIGHT );
		this->blocks->getOrigin().moveTo( GRID_X, GRID_Y, 0.0f );
		
		this->background = new Grid( GRID_WIDTH, GRID_HEIGHT );
		this->background->getOrigin().moveTo( GRID_X, GRID_Y, -0.5f );
		
		// Generating pieces
		this->fallingBlock = Piece::generate();
		this->fallingBlock->getOrigin().moveTo( GRID_X, GRID_Y, 0.0f );
		
		this->nextBlock = Piece::generate();
		this->nextBlock->getOrigin().moveTo( NEXT_X, NEXT_Y, 0.0f );
	
		// Fill background vector
		Point2D position( 0.0f, 0.0f );
		Color backgroundColor( "ffffff" );
		backgroundColor.setAlpha( 0.2f );
	
		for( unsigned int y = 0 ; y < 20 ; y++ )
		{
			for( unsigned int x = 0 ; x < 10 ; x++ )
			{
				position.moveTo( x, y );
				this->background->insert( new Block( position, backgroundColor ) );
			}
		}
	
		this->updateLabels();
		this->lastBlockMove = SDL_GetTicks();
		
		Mixer::get()->play( "BlockgameSong" );
	}
Ejemplo n.º 8
0
void savesnddialog()
{
   sound_stop(); //Alone Coder
   unsigned end; //Alone Coder 0.36.7
   if (savesndtype) {
      if (savesndtype == 1) { // wave
         unsigned fsize = ftell(savesnd);
         fseek(savesnd, 0, SEEK_SET);
         fsize -= sizeof wavhdr;
         *(unsigned*)(wavhdr+4) = fsize+0x2c-8;
         *(unsigned*)(wavhdr+0x28) = fsize;
         fwrite(wavhdr, 1, sizeof wavhdr, savesnd);
         MessageBox(wnd, "WAV save done", "Save sound", MB_ICONINFORMATION);
      } else { // vtx
         savesndtype = 0;
         u8 *newb = (u8*)malloc(vtxbuffilled);
         for (/*unsigned*/ end = 0; end < (int)vtxbuffilled && silence(end); end += 14);
         vtxbuffilled -= end; memcpy(vtxbuf, vtxbuf+end, vtxbuffilled);
         for (end = vtxbuffilled; end && silence(end-14); end -= 14);
         vtxbuffilled = end;
         int nrec = vtxbuffilled/14;
         for (int i = 0; i < nrec; i++)
            for (int j = 0; j < 14; j++)
               newb[j*nrec+i] = vtxbuf[i*14+j];
         free(vtxbuf);
         FILE *ff = fopen("vtx.tmp", "wb");
         if (!ff) return;
         fwrite(newb, 1, vtxbuffilled, ff);
         fclose(ff);
         STARTUPINFO si = { sizeof si };
         si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
         PROCESS_INFORMATION pi;
         char Parh[] = "lha a vtx.lzh vtx.tmp";
         if (CreateProcess(0, Parh, 0, 0, 0, 0, 0, 0, &si, &pi))
         {
            WaitForSingleObject(pi.hProcess, 5000);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            DeleteFile("vtx.tmp");
         }
         else
         {
            DeleteFile("vtx.tmp");
            MessageBox(wnd, "LHA.EXE not found in %PATH%", 0, MB_ICONERROR);
            return;
         }
         ff = fopen("vtx.lzh", "rb"); if (!ff) return;
         fseek(ff, 0x22, SEEK_SET);
         unsigned packed = fread(newb, 1, vtxbuffilled, ff)-1;
         fclose(ff); DeleteFile("vtx.lzh");
         DialogBox(hIn, MAKEINTRESOURCE(IDD_VTX), wnd, VtxDlg);
         vtxheader.sig = (vtxchip & 1) ? WORD2('y','m') : WORD2('a','y');
         static u8 ste[] = { 1, 2, 0 };
         vtxheader.stereo = ste[vtxchip/2];
         vtxheader.ayfq = conf.sound.ayfq;
         vtxheader.intfq = 50;
         vtxheader.year = vtxyear;
         vtxheader.rawsize = vtxbuffilled;
         fwrite(&vtxheader, 1, 0x10, savesnd);
         fwrite(vtxname, 1, strlen(vtxname)+1, savesnd);
         fwrite(vtxauthor, 1, strlen(vtxauthor)+1, savesnd);
         fwrite(vtxsoft, 1, strlen(vtxsoft)+1, savesnd);
         fwrite(vtxtracker, 1, strlen(vtxtracker)+1, savesnd);
         fwrite(vtxcomm, 1, strlen(vtxcomm)+1, savesnd);
         fwrite(newb, 1, packed, savesnd);
      }
      fclose(savesnd);
      savesndtype = 0;
   } else {
      OPENFILENAME ofn = { 0 };
      char sndsavename[0x200]; *sndsavename = 0;

      ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
      ofn.lpstrFilter = "All sound (WAV)\0*.wav\0AY sound (VTX)\0*.vtx\0";
      ofn.lpstrFile = sndsavename; ofn.nMaxFile = sizeof sndsavename;
      ofn.lpstrTitle = "Save Sound";
      ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
      ofn.hwndOwner = wnd;
      ofn.nFilterIndex = 1;
      if (GetSaveFileName(&ofn)) {
         char *name = sndsavename; for (char *x = name; *x; x++) if (*x == '\\') name = x+1;
         if (!strchr(name, '.')) {
            if (ofn.nFilterIndex == 1) strcat(sndsavename, ".wav");
            else strcat(sndsavename, ".vtx");
         }
         savesnd = fopen(ofn.lpstrFile, "wb");
         if (!savesnd) MessageBox(wnd, "Can't create file", 0, MB_ICONERROR);
         else if (ofn.nFilterIndex == 2) { // vtx
            savesndtype = 2;
            vtxbuf = 0;
         } else { // wave. all params, except fq are fixed: 16bit,stereo
            *(unsigned*)(wavhdr+0x18) = conf.sound.fq; // fq
            *(unsigned*)(wavhdr+0x1C) = conf.sound.fq*4; // bitrate
            fwrite(wavhdr, 1, 44, savesnd); // header
            savesndtype = 1;
         }
      }
   }
   eat();
   sound_play(); //Alone Coder
}
Ejemplo n.º 9
0
int main(int argc, char **argv){
	SDL_AudioSpec requested, obtained;

	int quit = 0;
	int xo, yo;
	int i, j, k;
	int meter[4];

	static char chars[10] =
	{
			'+', '-', '*', '#', 'X', '@', '%', '$', 'M', 'W'
	};

	caca_display_t *dp;
	caca_canvas_t *cv;
	caca_canvas_t *pineapple;

	if(SDL_Init( SDL_INIT_AUDIO ) < 0){
		err(1, "Couldnt initialize SDL\n");
		exit(1);
	}

	cv = caca_create_canvas(80, 24);
	pineapple = caca_create_canvas(0, 0);
	if((cv == NULL) || (pineapple == NULL)){
		printf("failed to create canvas\n");
		return 1;
	}
	dp = caca_create_display(cv);
	caca_set_display_time(dp, 20000);
	if(dp == NULL){
		printf("Failed to create display\n");
		return 1;
	}

	caca_import_file(pineapple, "./pineapple", "");

	atexit(SDL_Quit);

	requested.freq = 16000;
	requested.format = AUDIO_U8;
	requested.samples = 256;
	requested.callback = audiocb;
	requested.channels = 1;

	if(SDL_OpenAudio(&requested, &obtained) == -1){
		err(1, "SDL_OpenAudio");
	}

	initchip();

	loadfile(argv[1]);

	SDL_PauseAudio(0);
	silence();
	startplaysong(0);


	while(!quit)
	{
		caca_event_t ev;
		caca_set_color_ansi(cv, CACA_DEFAULT, CACA_DEFAULT);
		caca_clear_canvas(cv);
		xo = caca_get_canvas_width(cv);
		yo = caca_get_canvas_height(cv);
		//caca_blit(cv, 0, 0, pineapple, NULL);
		caca_blit(cv, 55, 0, pineapple, NULL);
		caca_set_color_ansi(cv, caca_rand(0, 16), caca_rand(0, 16));
		caca_put_str(cv, (xo - strlen("pineapple player")) / 2, (yo / 2) - 5, "pineapple player");
		caca_set_color_ansi(cv, caca_rand(0, 16), caca_rand(0, 16));
		caca_printf(cv, (xo - strlen("song pos ->   ")) / 2, (yo / 2) - 3, "song pos -> %x", songpos);
		
		for(i = 0; i < 4; i ++)
			meter[i] = (osc[i].volume*20)/255;
		/* note visualizer */
		i = 0;
		for(j = 0; j < 25; j=j+6){
				for(k = 0; k < 4; k++){
				caca_draw_line(cv, (((xo/2)+10)-j)-k, yo, (((xo/2)+10)-j)-k, yo - meter[i], 
					chars[caca_rand(0, 9)]);
				}
			i++;
		}

		for(i = 0; i < 4; i ++)
			caca_printf(cv, 0, i, "%0x", osc[i].volume);

    while(caca_get_event(dp, CACA_EVENT_ANY, &ev, 0))
    {
    	if(caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS)
    	{
				switch(caca_get_event_key_ch(&ev))
				{
					case 'q':
					case 'Q':
					case CACA_KEY_ESCAPE:
						quit = 1;
						break;
				}
			}
		}
		caca_refresh_display(dp);
	}
	silence();
	caca_free_display(dp);
	caca_free_canvas(cv);
	return 0;
}
Ejemplo n.º 10
0
/* vi insert mode */
void insertmode(void){
	int c;
	currmode = PM_INSERT;
	drawgui();
	for(;;){
		if((c = getch()) != ERR) switch(c){
			case KEY_ESCAPE:
				currmode = PM_NORMAL;
				return;
			case 'h':
			case KEY_LEFT:
				act_mvleft();
				break;
			case 'j':
			case KEY_DOWN:
				act_mvdown();
				break;
			case 'k':
			case KEY_UP:
				act_mvup();
				break;
			case 'l':
			case KEY_RIGHT:
				act_mvright();
				break;
			/* change octave */
			case '<':
				if(octave) octave--;
				break;
			case '>':
				if(octave < 8) octave++;
				break;
			/* change instrument */
			case CTRL('J'):
				if(currtab == 2){
					act_viewinstrdec();
				}else if(currtab == 1){
					act_viewtrackdec();
				}
				break;
			case CTRL('K'):
				if(currtab == 2){
					act_viewinstrinc();
				}else if(currtab == 1){
					act_viewtrackinc();
				}
				break;
			case '[':
				act_viewinstrdec();
				break;
			case ']':
				act_viewinstrinc();
				break;
			case CTRL('H'):
				currtab--;
				if(currtab < 0)
					currtab = 2;
				break;
			case CTRL('L'):
				currtab++;
				currtab %= 3;
				break;
			case 'Z':
				c = nextchar();
				switch(c){
					case 'Z':
						lft_savefile(filename);
						erase();
						refresh();
						endwin();
						exit(0);
						break;
					case 'Q':
						erase();
						refresh();
						endwin();
						exit(0);
						break;
				}
				break;
			case ' ':
				silence();
				currmode = PM_NORMAL;
				return;
			case ENTER:
				if(currtab != 2){
					if(currtab == 1){
						silence();
						startplaytrack(currtrack);
					}else if(currtab == 0){
						silence();
						startplaysong(songy);
					}
				}
				break;
			case '`':
				if(currtab == 0){
					int t = tune->sng[songy].track[songx / 4];
					if(t) currtrack = t;
					currtab = 1;
				}else if(currtab == 1){
					currtab = 0;
				}
				break;
			default:
				_insertc(c);
				if(currtab == 1){
					tracky+=step;
					tracky %= (tune->tracklen);
				}else if(currtab == 2){
					//if(instry < instrument[currinstr].length-1) instry++;
					if(instrx < 2) instrx++;
					else instrx--;
					instry %= instrument[currinstr].length;
				}
				saved = 0;
		}
		drawgui();
		usleep(10000);
	}
}
Ejemplo n.º 11
0
/* normal mode */
void normalmode(int c){
	int i;

	// don't save the action for repeat if it's a movement or a repeat, or
	// something else that doesnt make sense to repeat
	if(c != 'h' &&
		c != 'j' &&
		c != 'k' &&
		c != 'l' &&
		c != CTRL('D') &&
		c != CTRL('U') &&
		c != CTRL('H') &&
		c != CTRL('L') &&
		c != 'H' &&
		c != 'M' &&
		c != 'L' &&
		c != 'g' &&
		c != 'G' &&
		c != '.'){
		lastaction = c;
		lastrepeatnum = cmdrepeatnum;
	}

	for(i=0; i<cmdrepeatnum; i++){
		switch(c){
		/* add line */
		case 'a':
			act_addline();
			break;
		case '.':
			// if the last command was a replace, just insert the last thing
			// inserted instead of calling insertmode()
			if(lastaction == 'r')
				_insertc(lastinsert);
			else
				normalmode(lastaction);
			cmdrepeatnum = lastrepeatnum;
			break;
		case KEY_ESCAPE:
			disptick = 0;
			jammermode();
			break;
		case CTRL('Y'):
			switch(currtab){
				case 0:
					if(songoffs>0){
						if(songy==getmaxy(stdscr)-3+songoffs)
							songy--;
						songoffs--;
					}
					break;
				case 1:
					if(trackoffs>0){
						if(tracky==getmaxy(stdscr)-3+trackoffs)
							tracky--;
						trackoffs--;
					}
					break;
				case 2:
					if(instroffs>0){
						if(instry==getmaxy(stdscr)-3+instroffs)
							instry--;
						instroffs--;
					}
					break;
			}
			break;
		case CTRL('E'):
			switch(currtab){
				case 0:
					if(songy<=tune->songlen-2){
						if(songy==songoffs)
							songy++;
						songoffs++;
					}
					break;
				case 1:
					if(tracky<=(tune->tracklen)-2){
						if(tracky==trackoffs)
							tracky++;
						trackoffs++;
					}
					break;
				case 2:
					if(instry<=instrument[currinstr].length-2){
						if(instry==instroffs)
							instry++;
						instroffs++;
					}
					break;
			}
			break;
		case 'H':
			switch(currtab){
				case 0:
					songy = songoffs;
					break;
				case 1:
					tracky = trackoffs;
					break;
				case 2:
					instry = instroffs;
					break;
			}
			break;

		// the second cases (to the right of the colon) for M and L
		// took some serious guesswork, so I'm not sure if they're
		// correct but they seem to work.
		case 'M':
			switch(currtab){
				case 0:
					songy = (tune->songlen <= getmaxy(stdscr)-2)?
							tune->songlen/2
							: ((getmaxy(stdscr)-6)/2) + songoffs;
					break;
				case 1:
					tracky = (tune->tracklen <= getmaxy(stdscr)-2)?
							tune->tracklen/2
							: ((getmaxy(stdscr)-6)/2) + trackoffs;
					break;
				case 2:
					instry = (instrument[currinstr].length <= getmaxy(stdscr)-2)?
							instrument[currinstr].length/2
							: ((getmaxy(stdscr)-6)/2) + instroffs;
					break;
			}
			break;
		case 'L':
			switch(currtab){
				case 0:
					songy = (tune->songlen <= getmaxy(stdscr)-2)?
							tune->songlen-1
							: getmaxy(stdscr)-3+songoffs;
					break;
				case 1:
					tracky = (tune->tracklen <= getmaxy(stdscr)-2)?
							tune->tracklen-1
							: getmaxy(stdscr)-3+trackoffs;
					break;
				case 2:
					instry = (instrument[currinstr].length <= getmaxy(stdscr)-2)?
							instrument[currinstr].length-1
							: getmaxy(stdscr)-3+instroffs;
					break;
			}
			break;
		case 'g':
			if(nextchar() == 'g'){
				act_mvtop();
			}
			break;
		case 'G':
			act_mvbottom();
			break;

		// yank
		case 'y':
			c = nextchar();
			switch(c){
				case 'y':
					//tclip = malloc(1);
					if(currtab == 0){
						tcliplen = 1;
						memcpy(&tclip, &tune->sng[songy], sizeof(struct songline));
					}else if(currtab == 1){
						tcliplen = 1;
						memcpy(&tclip, &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
					}else if(currtab == 2){
						icliplen = 1;
						memcpy(&iclip, &instrument[currinstr].line[instry], sizeof(struct instrline));
					}
					break;
				case 'j':
					//tclip = malloc(2);
					if(currtab == 0){
						tcliplen = 2;
						memcpy(&tclip[0], &tune->sng[songy], sizeof(struct songline));
						act_mvdown();
						memcpy(&tclip[1], &tune->sng[songy], sizeof(struct songline));
					}else if(currtab == 1){
						tcliplen = 2;
						memcpy(&tclip[0], &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
						act_mvdown();
						memcpy(&tclip[1], &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
					}else if(currtab == 2){
						icliplen = 2;
						memcpy(&iclip[0], &instrument[currinstr].line[instry], sizeof(struct instrline));
						act_mvdown();
						memcpy(&iclip[1], &instrument[currinstr].line[instry], sizeof(struct instrline));
					}
					break;
				case 'k':
					//tclip = malloc(2);
					if(currtab == 0){
						tcliplen = 2;
						memcpy(&tclip[1], &tune->sng[songy], sizeof(struct songline));
						act_mvup();
						memcpy(&tclip[0], &tune->sng[songy], sizeof(struct songline));
					}else if(currtab == 1){
						tcliplen = 2;
						memcpy(&tclip[1], &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
						act_mvup();
						memcpy(&tclip[0], &tune->trk[currtrack].line[tracky], sizeof(struct trackline));
					}else if(currtab == 2){
						icliplen = 2;
						memcpy(&iclip[1], &instrument[currinstr].line[instry], sizeof(struct instrline));
						act_mvup();
						memcpy(&iclip[0], &instrument[currinstr].line[instry], sizeof(struct instrline));
					}
					break;
			}
			break;

		//paste
		case 'p':
			if(currtab == 0){
				if(tune->songlen < 256){
					for(int i = 0; i < tcliplen; i++){
						// insert new line
						memmove(&tune->sng[songy + 2], &tune->sng[songy + 1], sizeof(struct songline) * (tune->songlen - songy - 1));
						songy++;
						tune->songlen++;
						memset(&tune->sng[songy], 0, sizeof(struct songline));

						// paste to new line
						memcpy(&tune->sng[songy], &tclip[i], sizeof(struct songline));
					}
				}
			}else if(currtab == 1){
					for(int i = 0; i < tcliplen; i++){
						memcpy(&tune->trk[currtrack].line[tracky], &tclip[i], sizeof(struct trackline));
						if(tracky < (tune->tracklen)-step) tracky += step;
						else tracky = (tune->tracklen)-1;
					}
			}else if(currtab == 2){
				if(instrument[currinstr].length < 256){
					// insert new line
					for(int i = 0; i < icliplen; i++){
						struct instrument *in = &instrument[currinstr];

						instry++;
						memmove(&in->line[instry + 1], &in->line[instry + 0], sizeof(struct instrline) * (in->length - instry));
						in->length++;
						in->line[instry].cmd = '0';
						in->line[instry].param = 0;

						// paste to new line
						memcpy(&instrument[currinstr].line[instry], &iclip[i], sizeof(struct instrline));
					}
				}
				//if(instry < instrument[currinstr].length-1) instry++;
			}
			break;

		// copy everything in the current phrase or instrument into the next free one
		case '^':
			if(currtab == 1){
				f = nextfreetrack();
				memcpy(&tune->trk[f], &tune->trk[currtrack], sizeof(struct track));
				currtrack = f;
			}else if(currtab == 2){
				f = nextfreeinstr();
				memcpy(&instrument[f], &instrument[currinstr], sizeof(struct instrument));
				currinstr = f;
			}
			break;

		// TODO: Y and P can be removed after we make visual mode
		// copy whole phrase or instrument
		case 'Y':
			if(currtab == 1){
				memcpy(&tclip, &tune->trk[currtrack], sizeof(struct track));
			}else if(currtab == 2){
				memcpy(&iclip, &instrument[currinstr], sizeof(struct instrument));
			}
			break;
		// paste whole phrase or instrument
		case 'P':
			if(currtab == 1){
				memcpy(&tune->trk[currtrack], &tclip, sizeof(struct track));
			}else if(currtab == 2){
				memcpy(&instrument[currinstr], &iclip, sizeof(struct instrument));
			}
			break;

		/* delete line */
		// TODO: clean this SHIT up
		// TODO: add an ACT_ function for delete
		case 'd':
			c = nextchar();
			switch(c){
				case 'd':
					act_delline();
					break;
				case 'k':
					if(currtab == 2){
						struct instrument *in = &instrument[currinstr];
						instry--;
						int i;
						for(i=0; i<2; i++){
							if(in->length > 1){
								memmove(&in->line[instry + 0], &in->line[instry + 1], sizeof(struct instrline) * (in->length - instry - 1));
								in->length--;
								if(instry >= in->length) instry = in->length - 1;
							}
						}
					}else if(currtab == 0){
						songy--;
						int i;
						for(i=0; i<2; i++){
							if(tune->songlen > 1){
								memmove(&tune->sng[songy + 0], &tune->sng[songy + 1], sizeof(struct songline) * (tune->songlen - songy - 1));
								tune->songlen--;
								if(songy >= tune->songlen) songy = tune->songlen - 1;
							}
						}
					}
					break;
				case 'j':
					if(currtab == 2){
						struct instrument *in = &instrument[currinstr];

						int i;
						for(i=0; i<2; i++){
							if(in->length > 1){
								memmove(&in->line[instry + 0], &in->line[instry + 1], sizeof(struct instrline) * (in->length - instry - 1));
								in->length--;
								if(instry >= in->length) instry = in->length - 1;
							}
						}
					}else if(currtab == 0){
						int i;
						for(i=0; i<2; i++){
							if(tune->songlen > 1){
								memmove(&tune->sng[songy + 0], &tune->sng[songy + 1], sizeof(struct songline) * (tune->songlen - songy - 1));
								tune->songlen--;
								if(songy >= tune->songlen) songy = tune->songlen - 1;
							}
						}
					}
					break;
			}
			break;
		/* undo */
		case 'u':
			act_undo();
		/* Clear */
		case 'x':
			act_clronething();
			break;
		case 'X':
			act_clritall();
			break;
		case ENTER:
			if(currtab != 2){
				if(currtab == 1){
					silence();
					startplaytrack(currtrack);
				}else if(currtab == 0){
					silence();
					startplaysong(songy);
				}
			}
			break;
		case 'Z':
			c = nextchar();
			switch(c){
				case 'Z':
					lft_savefile(filename);
					erase();
					refresh();
					endwin();
					exit(0);
					break;
				case 'Q':
					erase();
					refresh();
					endwin();
					exit(0);
					break;
			}
			break;
		/* Enter command mode */
		case ':':
			cmdlinemode();
			break;
		case ' ':
			silence();
			tune->plonked = 0;
			break;
		// TODO: make an act_ function for '`'
		case '`':
			if(currtab == 0){
				int t = tune->sng[songy].track[songx / 4];
				if(t) currtrack = t;
				currtab = 1;
				if(playtrack){
					startplaytrack(currtrack);
				}
			}else if((currtab == 1) && ((trackx == 2) || (trackx == 3))){
				int i = tune->trk[currtrack].line[tracky].instr;
				if(i) currinstr = i;
				currtab = 2;
			}	else if(currtab == 1){
				currtab = 0;
			}else if(currtab == 2){
				currtab = 1;
			}
			break;
		/* Enter insert mode */
		case 'i':
			insertmode();
			break;
		/* Enter visual mode */
		case 'v':
			visualmode();
			break;
		/* Enter visual line mode */
		case 'V':
			visuallinemode();
			break;
		/* enter jammer mode */
		case CTRL('A'):
			jammermode();
			break;
		/* Add new line and enter insert mode */
		case 'o':
			act_addline();
			insertmode();
			break;
		case 'h':
		case KEY_LEFT:
			act_mvleft();
			break;
		case 'j':
		case KEY_DOWN:
			act_mvdown();
			break;
		case 'k':
		case KEY_UP:
			act_mvup();
			break;
		case 'l':
		case KEY_RIGHT:
			act_mvright();
			break;
		case '<':
			if(octave) octave--;
			break;
		case '>':
			if(octave < 8) octave++;
			break;
		case '{':
			if(currtrack > 1) currtrack--;
			break;
		case '}':
			if(currtrack < 255) currtrack++;
			break;
		case 'J':
			if(currtab == 0){
				if( (songx%4) < 2){
					act_trackdec();
				}else{
					act_transpdec();
				}
			}else if(currtab == 1){
				switch(trackx){
					case 0:
						act_notedec();
						break;
					case 1:
						act_octavedec();
						break;
					case 2:
						act_instrdec();
						break;
					case 3:
						act_instrdec();
						break;
					case 4:
						act_fxdec();	
						break;
					case 5:
					case 6:
						act_paramdec();	
						break;
					case 7:
						act_fxdec();	
						break;
					case 8:
					case 9:
						act_paramdec();	
						break;
					default:
						setdisplay("in J");
						break;
					}
			}else if(currtab == 2){
				switch(instrx){
					case 0:
						act_fxdec();	
						break;
					case 1:
						if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
							act_notedec();
						}else{
							act_paramdec();	
						}
						break;
					case 2:
						if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
							act_notedec();
						}else{
							act_paramdec();	
						}
						break;
				}
			}
			break;
		case 'K':
			if(currtab == 0){
				if( (songx%4) < 2){
					act_trackinc();
				}else{
					act_transpinc();
				}
			}else if(currtab == 1){
				switch(trackx){
					case 0:
						act_noteinc();
						break;
					case 1:
						act_octaveinc();	
						break;
					case 2:
						act_instrinc();
						break;
					case 3:
						act_instrinc();
						break;
					case 4:
						act_fxinc();	
						break;
					case 5:
					case 6:
						act_paraminc();	
						break;
					case 7:
						act_fxinc();	
						break;
					case 8:
					case 9:
						act_paraminc();	
						break;
					default:
						setdisplay("in K");
						break;
				}
			}else if(currtab == 2){
				switch(instrx){
					case 0:
						act_fxinc();	
						break;
					case 1:
						if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
							act_noteinc();
						}else{
							act_paraminc();	
						}
						break;
					case 2:
						if(instrument[currinstr].line[instry].cmd == '+' || instrument[currinstr].line[instry].cmd == '='){
							act_noteinc();
						}else{
							act_paraminc();	
						}
						break;
				}
			}
			break;
		case CTRL('J'):
			if(currtab == 2){
				act_viewinstrdec();
			}else if(currtab == 1){
				act_viewtrackdec();
			}
			break;
		case CTRL('K'):
			if(currtab == 2){
				act_viewinstrinc();
			}else if(currtab == 1){
				act_viewtrackinc();
			}
			break;
		case '[':
			act_viewinstrdec();
			break;
		case ']':
			act_viewinstrinc();
			break;
		case '(':
			callbacktime++;
			break;
		case ')':
			callbacktime--;
			break;
		case '-':
			if(step > 0) 
			  step--;
			break;
		case '=':
			if(step < 0x0f) 
			  step++;
			break;
		case CTRL('H'):
			currtab--;
			if(currtab < 0)
				currtab = 2;
			break;
		case CTRL('L'):
			currtab++;
			currtab %= 3;
			break;
		case KEY_TAB:
			currtab++;
			currtab %= 3;
			break;
		case CTRL('U'):
			act_bigmvup();
			break;
		case CTRL('D'):
			act_bigmvdown();
			break;
		/*case CTRL('P'):
			vimode = false;
			break;*/

		// replace
		case 'r':
			_insertc(nextchar());
			break;

		default:
			break;
		} // end switch
	} // end for
	cmdrepeatnum = 1;
	cmdrepeat = 0;
}