Exemplo n.º 1
0
static status_t
multi_audio_control_generic(cookie_type* cookie, uint32 op, void* arg, size_t len)
{
	status_t status;
	switch (op) {
		case B_MULTI_GET_DESCRIPTION:
		{
			multi_description description;
			multi_channel_info channels[16];
			multi_channel_info* originalChannels;

			if (user_memcpy(&description, arg, sizeof(multi_description))
					!= B_OK)
				return B_BAD_ADDRESS;

			originalChannels = description.channels;
			description.channels = channels;
			if (description.request_channel_count > 16)
				description.request_channel_count = 16;

			status = get_description(cookie, &description);
			if (status != B_OK)
				return status;

			description.channels = originalChannels;
			if (user_memcpy(arg, &description, sizeof(multi_description))
					!= B_OK)
				return B_BAD_ADDRESS;
			return user_memcpy(originalChannels, channels,
				sizeof(multi_channel_info) * description.request_channel_count);
		}

		case B_MULTI_GET_ENABLED_CHANNELS:
		{
			multi_channel_enable* data = (multi_channel_enable*)arg;
			multi_channel_enable enable;
			uint32 enable_bits;
			uchar* orig_enable_bits;

			if (user_memcpy(&enable, data, sizeof(enable)) != B_OK
				|| !IS_USER_ADDRESS(enable.enable_bits)) {
				return B_BAD_ADDRESS;
			}

			orig_enable_bits = enable.enable_bits;
			enable.enable_bits = (uchar*)&enable_bits;
			status = get_enabled_channels(cookie, &enable);
			if (status != B_OK)
				return status;

			enable.enable_bits = orig_enable_bits;
			if (user_memcpy(enable.enable_bits, &enable_bits,
					sizeof(enable_bits)) < B_OK
				|| user_memcpy(arg, &enable, sizeof(multi_channel_enable)) < B_OK) {
				return B_BAD_ADDRESS;
			}

			return B_OK;
		}
		case B_MULTI_SET_ENABLED_CHANNELS:
			return B_OK;

		case B_MULTI_GET_GLOBAL_FORMAT:
		{
			multi_format_info info;
			if (user_memcpy(&info, arg, sizeof(multi_format_info)) != B_OK)
				return B_BAD_ADDRESS;

			status = get_global_format(cookie, &info);
			if (status != B_OK)
				return B_OK;
			return user_memcpy(arg, &info, sizeof(multi_format_info));
		}
		case B_MULTI_SET_GLOBAL_FORMAT:
		{
			multi_format_info info;
			if (user_memcpy(&info, arg, sizeof(multi_format_info)) != B_OK)
				return B_BAD_ADDRESS;

			status = set_global_format(cookie, &info);
			if (status != B_OK)
				return B_OK;
			return user_memcpy(arg, &info, sizeof(multi_format_info));
		}
		case B_MULTI_LIST_MIX_CHANNELS:
			return list_mix_channels(cookie, (multi_mix_channel_info*)arg);
		case B_MULTI_LIST_MIX_CONTROLS:
		{
			multi_mix_control_info info;
			multi_mix_control* original_controls;
			size_t allocSize;
			multi_mix_control *controls;

			if (user_memcpy(&info, arg, sizeof(multi_mix_control_info)) != B_OK)
				return B_BAD_ADDRESS;

			original_controls = info.controls;
			allocSize = sizeof(multi_mix_control) * info.control_count;
			controls = (multi_mix_control *)malloc(allocSize);
			if (controls == NULL)
				return B_NO_MEMORY;

			if (!IS_USER_ADDRESS(info.controls)
				|| user_memcpy(controls, info.controls, allocSize) < B_OK) {
				free(controls);
				return B_BAD_ADDRESS;
			}
			info.controls = controls;

			status = list_mix_controls(cookie, &info);
			if (status != B_OK) {
				free(controls);
				return status;
			}

			info.controls = original_controls;
			status = user_memcpy(info.controls, controls, allocSize);
			if (status == B_OK)
				status = user_memcpy(arg, &info, sizeof(multi_mix_control_info));
			if (status != B_OK)
				status = B_BAD_ADDRESS;
			free(controls);
			return status;
		}
		case B_MULTI_LIST_MIX_CONNECTIONS:
			return list_mix_connections(cookie,
				(multi_mix_connection_info*)arg);
		case B_MULTI_GET_MIX:
		{
			multi_mix_value_info info;
			multi_mix_value* original_values;
			size_t allocSize;
			multi_mix_value *values;

			if (user_memcpy(&info, arg, sizeof(multi_mix_value_info)) != B_OK)
				return B_BAD_ADDRESS;

			original_values = info.values;
			allocSize = sizeof(multi_mix_value) * info.item_count;
			values = (multi_mix_value *)malloc(allocSize);
			if (values == NULL)
				return B_NO_MEMORY;

			if (!IS_USER_ADDRESS(info.values)
				|| user_memcpy(values, info.values, allocSize) < B_OK) {
				free(values);
				return B_BAD_ADDRESS;
			}
			info.values = values;

			status = get_mix(cookie, &info);
			if (status != B_OK) {
				free(values);
				return status;
			}

			info.values = original_values;
			status = user_memcpy(info.values, values, allocSize);
			if (status == B_OK)
				status = user_memcpy(arg, &info, sizeof(multi_mix_value_info));
			if (status != B_OK)
				status = B_BAD_ADDRESS;
			free(values);
			return status;
		}
		case B_MULTI_SET_MIX:
		{
			multi_mix_value_info info;
			multi_mix_value* original_values;
			size_t allocSize;
			multi_mix_value *values;

			if (user_memcpy(&info, arg, sizeof(multi_mix_value_info)) != B_OK)
				return B_BAD_ADDRESS;

			original_values = info.values;
			allocSize = sizeof(multi_mix_value) * info.item_count;
			values = (multi_mix_value *)malloc(allocSize);
			if (values == NULL)
				return B_NO_MEMORY;

			if (!IS_USER_ADDRESS(info.values)
				|| user_memcpy(values, info.values, allocSize) < B_OK) {
				free(values);
				return B_BAD_ADDRESS;
			}
			info.values = values;

			status = set_mix(cookie, &info);
			if (status != B_OK) {
				free(values);
				return status;
			}

			info.values = original_values;
			status = user_memcpy(info.values, values, allocSize);
			if (status == B_OK)
				status = user_memcpy(arg, &info, sizeof(multi_mix_value_info));
			if (status != B_OK)
				status = B_BAD_ADDRESS;
			free(values);
			return status;
		}
		case B_MULTI_GET_BUFFERS:
		{
			multi_buffer_list list;
			if (user_memcpy(&list, arg, sizeof(multi_buffer_list)) != B_OK)
				return B_BAD_ADDRESS;
			{
				buffer_desc **original_playback_descs = list.playback_buffers;
				buffer_desc **original_record_descs = list.record_buffers;

				buffer_desc *playback_descs[list.request_playback_buffers];
				buffer_desc *record_descs[list.request_record_buffers];

				if (!IS_USER_ADDRESS(list.playback_buffers)
					|| user_memcpy(playback_descs, list.playback_buffers,
						sizeof(buffer_desc*) * list.request_playback_buffers)
						< B_OK
					|| !IS_USER_ADDRESS(list.record_buffers)
					|| user_memcpy(record_descs, list.record_buffers,
						sizeof(buffer_desc*) * list.request_record_buffers)
						< B_OK) {
					return B_BAD_ADDRESS;
				}

				list.playback_buffers = playback_descs;
				list.record_buffers = record_descs;
				status = get_buffers(cookie, &list);
				if (status != B_OK)
					return status;

				list.playback_buffers = original_playback_descs;
				list.record_buffers = original_record_descs;

				if (user_memcpy(arg, &list, sizeof(multi_buffer_list)) < B_OK
					|| user_memcpy(original_playback_descs, playback_descs,
						sizeof(buffer_desc*) * list.request_playback_buffers)
						< B_OK
					|| user_memcpy(original_record_descs, record_descs,
						sizeof(buffer_desc*) * list.request_record_buffers)
						< B_OK) {
					status = B_BAD_ADDRESS;
				}
			}

			return status;
		}
		case B_MULTI_BUFFER_EXCHANGE:
			return buffer_exchange(cookie, (multi_buffer_info*)arg);
		case B_MULTI_BUFFER_FORCE_STOP:
			return buffer_force_stop(cookie);

		case B_MULTI_GET_EVENT_INFO:
		case B_MULTI_SET_EVENT_INFO:
		case B_MULTI_GET_EVENT:
		case B_MULTI_GET_CHANNEL_FORMATS:
		case B_MULTI_SET_CHANNEL_FORMATS:
		case B_MULTI_SET_BUFFERS:
		case B_MULTI_SET_START_TIME:
			return B_ERROR;
	}

	return B_BAD_VALUE;
}
Exemplo n.º 2
0
int
main (int argc, char **argv)
{

  int frequency, oversample, stereo;
  struct song *song;
  int index;
  int c;
  int opt, error_flag;


  /* supposed to make wildcard expansion */
  _wildcard(&argc,&argv);

  signal (2, nextsong);
  signal (3, goodbye);

  printf("Tracker1 V0.91 for the SBOS2 package\n");

  /* Read environment variables */
  frequency = read_env ("FREQUENCY", 0);
  oversample = read_env ("OVERSAMPLE", 1);
  transpose = read_env ("TRANSPOSE", 0);

  if (getenv ("MONO"))
    pref.stereo = 0;
  else if (getenv ("STEREO"))
    pref.stereo = 1;
  else
    pref.stereo = DEFAULT_CHANNELS - 1;
  pref.type = BOTH;
  pref.repeats = 1;
  pref.speed = 50;
  pref.tolerate = 2;
  pref.verbose = 0;
  set_mix (DEFAULT_MIX);        /* 0 = full stereo, 100 = mono */

  error_flag = 0;
  while ((opt = getopt_long_only (argc, argv, "", long_options, NULL)) != EOF)
    {
      switch (opt)
        {
        case 'H':               /* help */
          error_flag++;
          break;
        case 'Q':               /* quiet */
          quiet++;
          break;
        case 'P':               /* abort on faults (be picky) */
          pref.tolerate = 0;
          break;
        case 'N':               /* new tracker type */
          pref.type = NEW;
          break;
        case 'O':               /* old tracker type */
          pref.type = OLD;
          break;
        case 'B':               /* both tracker types */
          pref.type = BOTH;
          break;
        case 'M':               /* mono */
          pref.stereo = 0;
          break;
        case 'S':               /* stereo */
          pref.stereo = 1;
          break;
        case 'V':
          pref.verbose = 1;
          break;
        case 'f':               /* frequency */
          frequency = atoi (optarg);
          break;
        case 'o':               /* oversampling */
          oversample = atoi (optarg);
          break;
        case 't':               /* transpose half-steps*/
          transpose = atoi (optarg);
          break;
        case 'r':               /* number of repeats */
          pref.repeats = atoi (optarg);
          break;
        case 's':               /* speed */
          pref.speed = atoi (optarg);
          break;
        case 'm':               /* % of channel mix.  100=mono */
          set_mix (atoi (optarg));
          break;
        default:                /* ??? */
          error_flag++;
          break;
        }
    }
  if (error_flag || !argv[optind])
    {
      fprintf (stderr, "Usage: %s " USAGE, argv[0]);
      exit(1);
    }

  frequency = open_audio (frequency);
  init_player (oversample, frequency);

  while (argv[optind])
    {
      switch (pref.type)
        {
        case BOTH:
          song = do_read_song (argv[optind], NEW);
          if (!song)
            song = do_read_song (argv[optind], OLD);
          break;
        case OLD:
          song = do_read_song (argv[optind], pref.type);
          break;
        case NEW:
          /* this is explicitly flagged as a new module,
           * so we don't need to look for a signature.
           */
          song = do_read_song (argv[optind], NEW_NO_CHECK);
          break;
        }
      optind++;
      if (song == NULL)
        continue;

      dump_song (song);
      play_song (song, &pref);
      release_song (song);

      /* flush out anything remaining in DMA buffers */
      flush_DMA_buffers();

    }

  close_audio ();
  return 0;
}