示例#1
0
文件: ffiso-fmt.c 项目: stsaz/FF
/*
Filename with extension: "NAME.EXT;1"
Filename without extension: "NAME."
Directory name: "NAME"
*/
static uint iso_ent_name_write(char *dst, const ffstr *filename, uint attr)
{
	ffstr name, ext;
	ffpath_splitname(filename->ptr, filename->len, &name, &ext);
	name.len = ffmin(name.len, 8);
	ext.len = ffmin(ext.len, 3);
	uint fnlen = name.len + ext.len;
	if (!(attr & FFUNIX_FILE_DIR) || ext.len != 0)
		fnlen += FFSLEN(".");
	if (!(attr & FFUNIX_FILE_DIR))
		fnlen += FFSLEN(";1");

	if (dst == NULL)
		return fnlen;

	char *p = dst;
	const char *end = dst + fnlen;
	p += iso_copyname(p, end, name.ptr, name.len);
	if (!(attr & FFUNIX_FILE_DIR) || ext.len != 0)
		*p++ = '.';
	p += iso_copyname(p, end, ext.ptr, ext.len);
	if (!(attr & FFUNIX_FILE_DIR))
		ffs_copyz(p, end, ";1");
	return fnlen;
}
示例#2
0
文件: ffiso-fmt.c 项目: stsaz/FF
static size_t iso_copyname(char *dst, const char *end, const char *src, size_t len)
{
	size_t i;
	len = ffmin(len, end - dst);

	for (i = 0;  i != len;  i++) {
		uint ch = (byte)src[i];

		if (ffchar_isletter(ch))
			dst[i] = ffchar_upper(ch);
		else if (ffchar_isdigit(ch))
			dst[i] = ch;
		else
			dst[i] = '_';
	}

	return i;
}
示例#3
0
文件: ffxz.c 项目: stsaz/FF
/* [(1X*)...]  0X* */
static uint64 xz_varint(const byte **_p, size_t len)
{
	uint i = 0;
	uint64 n = 0;
	const byte *p = *_p;
	len = ffmin(len, 9);
	for (;;) {
		if (i == len) {
			*_p = p + len;
			return 0;
		}
		n |= (uint64)(p[i] & ~0x80) << (i * 7);

		if (!(p[i++] & 0x80))
			break;
	}

	*_p = p + i;
	return n;
}
示例#4
0
文件: ffvorbis.c 项目: stsaz/FF
int ffvorbis_decode(ffvorbis *v, const char *pkt, size_t len)
{
	enum { R_HDR, R_TAGS, R_TAG, R_BOOK, R_DATA };
	int r;

	if (len == 0)
		return FFVORBIS_RMORE;

	ogg_packet opkt;
	ffmem_tzero(&opkt);
	opkt.packet = (void*)pkt,  opkt.bytes = len;
	opkt.packetno = v->pktno++;
	opkt.granulepos = -1;
	opkt.e_o_s = v->fin;

	switch (v->state) {
	case R_HDR:
		if (0 != vorb_info(pkt, len, &v->info.channels, &v->info.rate, &v->info.bitrate_nominal))
			return ERR(v, FFVORBIS_EPKT);

		if (0 != (r = vorbis_decode_init(&v->vctx, &opkt)))
			return ERR(v, r);
		v->state = R_TAGS;
		return FFVORBIS_RHDR;

	case R_TAGS:
		if (NULL == (v->vtag.data = vorb_comm(pkt, len, &v->vtag.datalen)))
			return ERR(v, FFVORBIS_ETAG);
		v->state = R_TAG;
		// break

	case R_TAG:
		r = ffvorbtag_parse(&v->vtag);
		if (r == FFVORBTAG_ERR)
			return ERR(v, FFVORBIS_ETAG);
		else if (r == FFVORBTAG_DONE) {
			if (!(v->vtag.datalen != 0 && v->vtag.data[0] == 1))
				return ERR(v, FFVORBIS_ETAG);
			v->state = R_BOOK;
			return FFVORBIS_RHDRFIN;
		}
		return FFVORBIS_RTAG;

	case R_BOOK:
		if (0 != (r = vorbis_decode_init(&v->vctx, &opkt)))
			return ERR(v, r);
		v->state = R_DATA;
		return FFVORBIS_RMORE;
	}

	r = vorbis_decode(v->vctx, &opkt, &v->pcm);
	if (r < 0)
		return v->err = r,  FFVORBIS_RWARN;
	else if (r == 0)
		return FFVORBIS_RMORE;

	if (v->seek_sample != (uint64)-1) {
		if (v->seek_sample < v->cursample) {
			//couldn't find the target packet within the page
			v->seek_sample = v->cursample;
		}

		uint skip = ffmin(v->seek_sample - v->cursample, r);
		v->cursample += skip;
		if (v->cursample != v->seek_sample || (uint)r == skip)
			return FFVORBIS_RMORE; //not yet reached the target packet

		v->seek_sample = (uint64)-1;
		for (uint i = 0;  i != v->info.channels;  i++) {
			v->pcm_arr[i] = v->pcm[i] + skip;
		}
		v->pcm = v->pcm_arr;
		r -= skip;
	}

	if (v->total_samples != (uint64)-1)
		r = ffmin(r, v->total_samples - v->cursample);
	v->pkt_samples = r;
	v->pcmlen = r * sizeof(float) * v->info.channels;
	v->cursample += r;
	return FFVORBIS_RDATA;
}
示例#5
0
文件: log-gz.c 项目: stsaz/fserv
static int logz_conf_end(ffparser_schem *ps, loggzip *lz)
{
	lz->gzlev = (uint)ffmin(lz->gzlev, 9);
	return 0;
}
示例#6
0
文件: ffpcm.c 项目: stsaz/FF
const char* ffpcm_channelstr(uint channels)
{
	return _ffpcm_channelstr[ffmin(channels - 1, FFCNT(_ffpcm_channelstr) - 1)];
}
示例#7
0
void handleEvents()
{
	sf::Event Event;
	const sf::Input& Input = App->GetInput();
	bool shiftDown = Input.IsKeyDown(sf::Key::LShift) || Input.IsKeyDown(sf::Key::RShift);
	while (App->GetEvent(Event))
	{
		// Close window : exit
		if (Event.Type == sf::Event::Closed)
			App->Close();
		//
		// Escape key : exit
		if (Event.Type == sf::Event::KeyPressed)
		{
			if(Event.Key.Code == sf::Key::Escape)
				App->Close();
			else if(Event.Key.Code == sf::Key::Delete)
				deleteShape();
			else if(Event.Key.Code == sf::Key::Up && selected != 0)
			{
				Shape* s = findShape(selected);
				switch(colorM)
				{
					case COLOR_R:
						s->color[0] = ffmin(1.0, s->color[0]+0.05); break;
					case COLOR_G:
						s->color[1] = ffmin(1.0, s->color[1]+0.05); break;
					case COLOR_B:
						s->color[2] = ffmin(1.0, s->color[2]+0.05); break;
				}	
			}
			else if(Event.Key.Code == sf::Key::Down && selected != 0)
			{
				Shape* s = findShape(selected);
				switch(colorM)
				{
					case COLOR_R:
						s->color[0] = ffmax(0.0, s->color[0]-0.05); break;
					case COLOR_G:
						s->color[1] = ffmax(0.0, s->color[1]-0.05); break;
					case COLOR_B:
						s->color[2] = ffmax(0.0, s->color[2]-0.05); break;
				}	
			}
		}

		// Resize event : adjust viewport
		if (Event.Type == sf::Event::Resized)
		{
			glViewport(0, 0, Event.Size.Width, Event.Size.Height);
			currentRes[0] = Event.Size.Width;
			currentRes[1] = Event.Size.Height;	
			update_perspective();
		}

		if (Event.Type == sf::Event::MouseButtonPressed)
		{	
			lastPos[0] = Event.MouseButton.X;
			lastPos[1] = Event.MouseButton.Y;
			float x = Event.MouseButton.X;
			float y = currentRes[1]-Event.MouseButton.Y;
			if(Event.MouseButton.Button == sf::Mouse::Left)
			{
				if(!handleButtons(x,y))
				{
					handleSelection(Event.MouseButton.X, Event.MouseButton.Y);
				}
			}

			if(Event.MouseButton.Button == sf::Mouse::Left && !shiftDown)
			{
				buttonDown[0] = 1;
			}
			if(Event.MouseButton.Button == sf::Mouse::Right)
				buttonDown[1] = 1;
			if(Event.MouseButton.Button == sf::Mouse::Middle)
				buttonDown[2] = 1;
			if(Event.MouseButton.Button == sf::Mouse::Left && shiftDown)
				buttonDown[2] = 1;
		}

		if (Event.Type == sf::Event::MouseButtonReleased)
		{
			if(Event.MouseButton.Button == sf::Mouse::Left && !shiftDown)
				buttonDown[0] = 0;
			if(Event.MouseButton.Button == sf::Mouse::Right)
				buttonDown[1] = 0;
			if(Event.MouseButton.Button == sf::Mouse::Middle)
				buttonDown[2] = 0;
			if(Event.MouseButton.Button == sf::Mouse::Left && shiftDown)
				buttonDown[2] = 0;
		}

		if (Event.Type == sf::Event::MouseMoved && (buttonDown[0] || buttonDown[1] || buttonDown[2]) )
		{
			int x = Event.MouseMove.X;
			int y = Event.MouseMove.Y;
			if(selected == 0)
			{
				if(buttonDown[0])
					camera.trackball_rotate(lastPos[0], lastPos[1], x, y, currentRes[0], currentRes[1]);
				if(buttonDown[1])
					camera.trackball_translate(lastPos[0], lastPos[1], x, y);
				if(buttonDown[2])
					camera.trackball_translate_z(lastPos[0], lastPos[1], x, y);
			}
			else
			{
				Shape* s = findShape(selected);
				float diff = (x-lastPos[0])-(y-lastPos[1]);
				vec3 v;
				switch(axisM)
				{
					case X_AXIS:
						v = vec3(diff,0.0,0.0); break;
					case Y_AXIS:
						v = vec3(0.0,diff,0.0); break;
					case Z_AXIS:
						v = vec3(0.0,0.0,diff); break;
				}
				switch(transM)
				{
					case TRANS_TRANSLATION:
						s->trans.trans += v*0.01; break;
					case TRANS_ROTATION:
						s->rot.trans += v*0.1; break;
					case TRANS_SCALE:
						s->scale.trans += v*0.01; break;
				}
			}
			lastPos[0] = x;
			lastPos[1] = y;
		}
	}
}
示例#8
0
文件: ffflac.c 项目: stsaz/FF
/*
Encode audio data into FLAC frames.
  An input sample must be within 32-bit container.
  To encode a frame libFLAC needs NBLOCK+1 input samples.
  flac_encode() returns a frame with NBLOCK encoded samples,
    so 1 sample always stays cached in libFLAC until we explicitly flush output data.
*/
int ffflac_encode(ffflac_enc *f)
{
	uint samples, sampsize, blksize;
	int r;

	switch (f->state) {

	case ENC_HDR:
		if (NULL == ffarr_realloc(&f->outbuf, (f->info.minblock + 1) * sizeof(int) * f->info.channels))
			return ERR(f, FLAC_ESYS);
		for (uint i = 0;  i != f->info.channels;  i++) {
			f->pcm32[i] = (void*)(f->outbuf.ptr + (f->info.minblock + 1) * sizeof(int) * i);
		}
		f->cap_pcm32 = f->info.minblock + 1;

		f->state = ENC_FRAMES;
		// break

	case ENC_FRAMES:
		break;

	case ENC_DONE: {
		flac_conf info = {0};
		flac_encode_info(f->enc, &info);
		f->info.minblock = info.min_blocksize;
		f->info.maxblock = info.max_blocksize;
		f->info.minframe = info.min_framesize;
		f->info.maxframe = info.max_framesize;
		ffmemcpy(f->info.md5, info.md5, sizeof(f->info.md5));
		return FFFLAC_RDONE;
	}
	}

	sampsize = f->info.bits/8 * f->info.channels;
	samples = ffmin(f->pcmlen / sampsize - f->off_pcm, f->cap_pcm32 - f->off_pcm32);

	if (samples == 0 && !f->fin) {
		f->off_pcm = 0;
		return FFFLAC_RMORE;
	}

	const void* src[FLAC__MAX_CHANNELS];
	int* dst[FLAC__MAX_CHANNELS];

	for (uint i = 0;  i != f->info.channels;  i++) {
		src[i] = (char*)f->pcm[i] + f->off_pcm * f->info.bits/8;
		dst[i] = f->pcm32[i] + f->off_pcm32;
	}

	if (0 != (r = pcm_to32(dst, src, f->info.bits, f->info.channels, samples)))
		return ERR(f, FLAC_EFMT);

	f->off_pcm += samples;
	f->off_pcm32 += samples;
	if (!(f->off_pcm32 == f->cap_pcm32 || f->fin)) {
		f->off_pcm = 0;
		return FFFLAC_RMORE;
	}

	samples = f->off_pcm32;
	f->off_pcm32 = 0;
	r = flac_encode(f->enc, (const int**)f->pcm32, &samples, (char**)&f->data);
	if (r < 0)
		return f->errtype = FLAC_ELIB,  f->err = r,  FFFLAC_RERR;

	blksize = f->info.minblock;
	if (r == 0 && f->fin) {
		samples = 0;
		r = flac_encode(f->enc, (const int**)f->pcm32, &samples, (char**)&f->data);
		if (r < 0)
			return f->errtype = FLAC_ELIB,  f->err = r,  FFFLAC_RERR;
		blksize = samples;
		f->state = ENC_DONE;
	}

	FF_ASSERT(r != 0);
	FF_ASSERT(samples == f->cap_pcm32 || f->fin);

	if (f->cap_pcm32 == f->info.minblock + 1)
		f->cap_pcm32 = f->info.minblock;

	f->frsamps = blksize;
	f->datalen = r;
	return FFFLAC_RDATA;
}
示例#9
0
文件: ffwav.c 项目: stsaz/FF
int ffwav_decode(ffwav *w)
{
	int r;
	struct ffwav_chunk *chunk, *parent;

	for (;;) {
	switch (w->state) {

	case R_SKIP:
		chunk = &w->chunks[w->ictx];
		r = ffmin(chunk->size, w->datalen);
		FFARR_SHIFT(w->data, w->datalen, r);
		chunk->size -= r;
		w->off += r;
		if (chunk->size != 0)
			return FFWAV_RMORE;

		w->state = R_NEXTCHUNK;
		continue;

	case R_PADDING:
		if (w->datalen == 0)
			return FFWAV_RMORE;

		if (w->data[0] == '\0') {
			// skip padding byte
			FFARR_SHIFT(w->data, w->datalen, 1);
			w->off += 1;
			parent = &w->chunks[w->ictx - 1];
			if (parent->size != 0)
				parent->size -= 1;
		}

		w->state = R_NEXTCHUNK;
		// break

	case R_NEXTCHUNK:
		chunk = &w->chunks[w->ictx];

		if (chunk->size == 0) {
			if (chunk->flags & F_PADD) {
				chunk->flags &= ~F_PADD;
				w->state = R_PADDING;
				continue;
			}

			uint id = chunk->id;
			ffmem_tzero(chunk);
			w->ictx--;

			switch (id) {
			case T_RIFF:
				return FFWAV_RDONE;
			}

			continue;
		}

		FF_ASSERT(chunk->ctx != NULL);
		// break

	case R_FIRSTCHUNK:
		w->gather_size = sizeof(struct wav_chunk);
		w->state = R_GATHER,  w->nxstate = R_CHUNKHDR;
		// break

	case R_GATHER:
		r = ffarr_append_until(&w->buf, w->data, w->datalen, w->gather_size);
		if (r == 0)
			return FFWAV_RMORE;
		else if (r == -1)
			return ERR(w, WAV_ESYS);
		FFARR_SHIFT(w->data, w->datalen, r);
		w->off += w->gather_size;
		ffstr_set2(&w->gather_buf, &w->buf);
		w->buf.len = 0;
		w->state = w->nxstate;
		continue;

	case R_CHUNKHDR: {
		parent = &w->chunks[w->ictx];
		chunk = &w->chunks[++w->ictx];
		wav_findchunk(w->gather_buf.ptr, parent->ctx, chunk, w->off - w->gather_buf.len);

		if (!(chunk->id == T_DATA && chunk->size == (uint)-1)) {
			if (chunk->size > parent->size)
				return ERR(w, WAV_ELARGE);
			parent->size -= sizeof(struct wav_chunk) + chunk->size;
		}

		if (chunk->id == 0) {
			//unknown chunk
			w->state = R_SKIP;
			continue;
		}

		if (chunk->id == T_DATA && chunk->size == (uint)-1)
			w->inf_data = 1;

		uint minsize = GET_MINSIZE(chunk->flags);
		if (minsize != 0 && chunk->size < minsize)
			return ERR(w, WAV_ESMALL);

		if ((chunk->flags & F_WHOLE) || minsize != 0) {
			w->gather_size = (minsize != 0) ? minsize : chunk->size;
			chunk->size -= w->gather_size;
			w->state = R_GATHER,  w->nxstate = R_CHUNK;
			continue;
		}

		w->state = R_CHUNK;
		continue;
	}

	case R_CHUNK:
		chunk = &w->chunks[w->ictx];

		if (chunk->id & T_TAG) {
			w->tag = chunk->id & ~T_TAG;
			ffstr_setz(&w->tagval, w->gather_buf.ptr);
			w->state = R_NEXTCHUNK;
			return FFWAV_RTAG;
		}

		switch (chunk->id) {
		case T_RIFF:
			if (!!ffs_cmp(w->gather_buf.ptr, "WAVE", 4))
				return ERR(w, WAV_ERIFF);

			w->chunks[w->ictx].ctx = wav_ctx_riff;
			break;

		case T_FMT:
			if (w->has_fmt)
				return ERR(w, WAV_EDUPFMT);
			w->has_fmt = 1;

			if (0 > (r = wav_fmt(w->gather_buf.ptr, w->gather_buf.len, &w->fmt, &w->bitrate)))
				return ERR(w, -r);

			w->sampsize = ffpcm_size1(&w->fmt);
			if (NULL == ffarr_realloc(&w->buf, w->sampsize))
				return ERR(w, WAV_ESYS);
			break;

		case T_LIST:
			if (!!ffs_cmp(w->gather_buf.ptr, "INFO", 4)) {
				w->state = R_SKIP;
				continue;
			}

			w->chunks[w->ictx].ctx = wav_ctx_list;
			break;

		case T_DATA:
			if (!w->has_fmt)
				return ERR(w, WAV_ENOFMT);

			w->dataoff = w->off;
			w->datasize = ff_align_floor(chunk->size, w->sampsize);
			if (!w->inf_data)
				w->total_samples = chunk->size / w->sampsize;
			w->state = R_DATA;
			return FFWAV_RHDR;
		}

		w->state = R_NEXTCHUNK;
		continue;

	case R_SEEK:
		w->off = w->dataoff + w->cursample * w->sampsize;
		w->state = R_DATA;
		return FFWAV_RSEEK;

	case R_DATAOK:
		w->cursample += w->pcmlen / w->sampsize;
		w->state = R_DATA;
		// break

	case R_DATA: {
		uint chunk_size = w->dataoff + w->datasize - w->off;
		if (chunk_size == 0) {
			chunk = &w->chunks[w->ictx];
			chunk->size -= w->datasize;
			w->state = R_SKIP;
			continue;
		}
		uint n = (uint)ffmin(chunk_size, w->datalen);
		n = ff_align_floor(n, w->sampsize);

		if (n == 0) {
			w->gather_size = w->sampsize;
			w->state = R_GATHER,  w->nxstate = R_BUFDATA;
			continue; //not even 1 complete PCM sample
		}
		w->pcm = (void*)w->data,  w->pcmlen = n;
		FFARR_SHIFT(w->data, w->datalen, n);
		w->off += n;
		w->state = R_DATAOK;
		return FFWAV_RDATA;
	}

	case R_BUFDATA:
		w->pcm = w->gather_buf.ptr,  w->pcmlen = w->gather_buf.len;
		w->state = R_DATAOK;
		return FFWAV_RDATA;

	}
	}
	//unreachable
}
示例#10
0
文件: gui.c 项目: stsaz/fmedia
static void corecmd_run(uint cmd, void *udata)
{
	dbglog("%s cmd:%u  udata:%p", __func__, cmd, udata);

	switch ((enum ACTION)cmd) {

	case A_SHOWPCM:
		file_showpcm();
		break;

	case A_DELFILE:
		file_del();
		break;

	case A_PLAY:
		if (gg->curtrk != NULL)
			gg->track->cmd(gg->curtrk->trk, FMED_TRACK_STOP);
		gg->qu->cmd(FMED_QUE_PLAY, (void*)gg->qu->fmed_queue_item(-1, gg->focused));
		break;

	case A_PLAYPAUSE:
		if (gg->curtrk == NULL) {
			gg->qu->cmd(FMED_QUE_PLAY, NULL);
			break;
		}

		if (gg->curtrk->paused) {
			gg->curtrk->paused = 0;
			wmain_status("");
			gg->curtrk->d->snd_output_pause = 0;
			gg->track->cmd(gg->curtrk->trk, FMED_TRACK_UNPAUSE);
			break;
		}

		gg->curtrk->d->snd_output_pause = 1;
		wmain_status("Paused");
		gg->curtrk->paused = 1;
		break;

	case A_STOP:
		gg->track->cmd(NULL, FMED_TRACK_STOPALL);
		break;

	case A_STOP_AFTER:
		gg->qu->cmd(FMED_QUE_STOP_AFTER, NULL);
		break;

	case A_NEXT:
	case A_PREV: {
		if (gg->curtrk != NULL)
			gg->track->cmd(gg->curtrk->trk, FMED_TRACK_STOP);
		uint id = (cmd == A_NEXT) ? FMED_QUE_NEXT2 : FMED_QUE_PREV2;
		gg->qu->cmd(id, (gg->curtrk != NULL) ? gg->curtrk->qent : NULL);
		break;
	}

	case A_SEEK:
	case A_FFWD:
	case A_RWND:
	case A_LEAP_FWD:
	case A_LEAP_BACK:
		gtrk_seek(cmd, (size_t)udata);
		break;
	case A_SETGOPOS:
		if (gg->curtrk != NULL) {
			gg->go_pos = gg->curtrk->time_cur;
			wmain_status("Marker: %u:%02u"
				, gg->go_pos / 60, gg->go_pos % 60);
		}
		break;
	case A_GOPOS:
		if (gg->curtrk != NULL && gg->go_pos != (uint)-1)
			gg->curtrk->time_seek = gg->go_pos;
		break;

	case A_VOL:
		gg->vol = (size_t)udata;
		gtrk_vol(gg->vol);
		break;
	case A_VOLUP:
		gg->vol = ffmin(gg->vol + 5, MAXVOL);
		gtrk_vol(gg->vol);
		break;
	case A_VOLDOWN:
		gg->vol = ffmax((int)gg->vol - 5, 0);
		gtrk_vol(gg->vol);
		break;
	case A_VOLRESET:
		gg->vol = 100;
		gtrk_vol(gg->vol);
		break;

	case A_LIST_SAVE: {
		char *list_fn = udata;
		gg->qu->fmed_queue_save(-1, list_fn);
		ffmem_free(list_fn);
		break;
	}
	case A_LIST_REMOVE:
		list_rmitems();
		break;

	case A_LIST_RMDEAD:
		gg->qu->cmd(FMED_QUE_RMDEAD, NULL);
		break;

	case A_LIST_CLEAR:
		gg->qu->cmd(FMED_QUE_CLEAR | FMED_QUE_NO_ONCHANGE, NULL);
		ffui_post_view_clear(&gg->wmain.vlist);
		break;

	case A_LIST_RANDOM:
		core->props->list_random = !core->props->list_random;
		break;

	case A_ONDROPFILE: {
		ffstr *d = udata;
		ffstr s = *d, ln;
		while (s.len != 0) {
			ffstr_nextval3(&s, &ln, '\n');
			if (!ffs_matchz(ln.ptr, ln.len, "file://"))
				continue;
			ffstr_shift(&ln, FFSLEN("file://"));
			wmain_ent_add(&ln);
		}
		ffstr_free(d);
		ffmem_free(d);
		break;
	}

	case A_URL_ADD: {
		ffstr *s = udata;
		wmain_ent_add(s);
		ffstr_free(s);
		ffmem_free(s);
		break;
	}

	case A_ONCLOSE:
		if (gg->conf.autosave_playlists)
			lists_save();
		core->sig(FMED_STOP);
		break;

	case LOADLISTS:
		lists_load();
		break;

	default:
		FF_ASSERT(0);
	}
}