Esempio n. 1
0
gn_error playringtone(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
{
	gn_ringtone ringtone;
	gn_tone tone;
	gn_error error;
	char *filename = optarg;
	int i, ulen;
	struct timeval dt;
#if (defined HAVE_TIMEOPS) && (defined HAVE_GETTIMEOFDAY)
	struct timeval t1, t2;
#endif

	int volume = 5;
	struct option options[] = {
		{ "volume", required_argument, NULL, 'v'},
		{ NULL,     0,                 NULL, 0}
	};

	while ((i = getopt_long(argc, argv, "v:", options, NULL)) != -1) {
		switch (i) {
		case 'v':
			volume = gnokii_atoi(optarg);
			if (errno || volume < 0)
				return playringtone_usage(stderr, -1);
			break;
		default:
			return playringtone_usage(stderr, -1);
		}
	}
	if (argc > optind) {
		/* There are too many arguments that don't start with '-' */
		return playringtone_usage(stderr, -1);
	}

	memset(&ringtone, 0, sizeof(ringtone));
	memset(&tone, 0, sizeof(tone));
	gn_data_clear(data);
	data->ringtone = &ringtone;
	data->tone = &tone;

	if (!filename) {
		fprintf(stderr, _("Internal gnokii error: null filename\n"));
		return GN_ERR_FAILED;
	}

	if ((error = gn_file_ringtone_read(filename, &ringtone))) {
		fprintf(stderr, _("Failed to load ringtone: %s\n"), gn_error_print(error));
		return error;
	}

#if (defined HAVE_TIMEOPS) && (defined HAVE_GETTIMEOFDAY)
	gettimeofday(&t1, NULL);
	tone.frequency = 0;
	tone.volume = 0;
	gn_sm_functions(GN_OP_PlayTone, data, state);
	gettimeofday(&t2, NULL);
	timersub(&t2, &t1, &dt);
#else
	dt.tv_sec = 0;
	dt.tv_usec = 20000;
#endif

	signal(SIGINT, interrupted);
	for (i = 0; !bshutdown && i < ringtone.notes_count; i++) {
		tone.volume = volume;
		gn_ringtone_get_tone(&ringtone, i, &tone.frequency, &ulen);
		if ((error = gn_sm_functions(GN_OP_PlayTone, data, state)) != GN_ERR_NONE) break;
		if (ulen > 2 * dt.tv_usec + 20000)
			usleep(ulen - 2 * dt.tv_usec - 20000);
		tone.volume = 0;
		if ((error = gn_sm_functions(GN_OP_PlayTone, data, state)) != GN_ERR_NONE) break;
		usleep(20000);
	}
	tone.frequency = 0;
	tone.volume = 0;
	gn_sm_functions(GN_OP_PlayTone, data, state);

	if (error == GN_ERR_NONE)
		fprintf(stderr, _("Play succeeded!\n"));
	else
		fprintf(stderr, _("Play failed: %s\n"), gn_error_print(error));

	return error;
}
Esempio n. 2
0
gn_error pnok_ringtone_to_raw(char *raw, int *rawlen, const gn_ringtone *ringtone, int dct4)
{
	int i, c, p, l, freq, base;
	int rleft, vtime, vstat;
	const gn_ringtone_note *note;
	char header[] = {0x00, 0x02, 0xfc, 0x0a, 0x01};
	char tailer[] = {0x0a, 0x0a, 0x0a, 0xfe, 0x40, 0x20, 0x07, 0x0b, 0xff, 0xff, 0xff, 0xff};
	char vibr_on[] = {0x0a, 0x01};
	char vibr_off[] = {0x0a, 0xfe};
	int notes[] = {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11};

	rleft = *rawlen;
	vtime = 0;
	vstat = 1;
	base = dct4 ? 90 : 114;

	if (rleft < sizeof(header)) return GN_ERR_MEMORYFULL;
	memcpy(raw, header, sizeof(header));
	raw += sizeof(header);
	rleft -= sizeof(header);

	for (i = 0; i < ringtone->notes_count; i++) {
		if (vtime >= 300) {
			if (rleft < 2) return GN_ERR_MEMORYFULL;
			memcpy(raw, vstat ? vibr_off : vibr_on, 2);
			vtime = 0;
			vstat = !vstat;
			raw += 2;
			rleft -= 2;
		}

		note = ringtone->notes + i;
		gn_ringtone_get_tone(ringtone, i, &freq, &p);
		p /= 8000;
		vtime += p;
		if (note->note == 0xff) {
			c = 0x40;
			p++;
		} else {
			c = 12 * (note->note / 14) + notes[note->note % 14] + base;
		}
		while (p > 1) {
			if (rleft < 2) return GN_ERR_MEMORYFULL;
			l = (p > 0xff) ? 0xff : p - 1;
			*raw++ = c;
			*raw++ = l;
			p -= l;
			rleft -= 2;
		}
		if (c != 0x40) {
			if (rleft < 2) return GN_ERR_MEMORYFULL;
			*raw++ = 0x40;
			*raw++ = 1;
			rleft -= 2;
		}
	}

	if (rleft < sizeof(tailer)) return GN_ERR_MEMORYFULL;
	memcpy(raw, tailer, sizeof(tailer));
	rleft -= sizeof(tailer);
	*rawlen = (*rawlen - rleft) & ~3;

	return GN_ERR_NONE;
}