Ejemplo n.º 1
0
static SfiTokenType
bse_wave_restore_private (BseObject  *object,
			  BseStorage *storage,
                          GScanner   *scanner)
{
  BseWave *wave = BSE_WAVE (object);
  GTokenType expected_token;
  GQuark quark;

  /* chain parent class' handler */
  if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER)
    return BSE_OBJECT_CLASS (parent_class)->restore_private (object, storage, scanner);

  /* parse storage commands */
  quark = g_quark_try_string (scanner->next_value.v_identifier);
  if (quark == quark_xinfos)
    {
      g_scanner_get_next_token (scanner); /* eat identifier */
      gchar **xinfos = NULL;
      GTokenType token = bse_storage_parse_xinfos (storage, &xinfos);
      if (token != G_TOKEN_NONE)
        return token;
      guint i = 0;
      for (i = 0; xinfos && xinfos[i]; i++)
        wave->xinfos = bse_xinfos_parse_assignment (wave->xinfos, xinfos[i]);
      g_strfreev (xinfos);
      parse_or_return (scanner, ')');
      expected_token = G_TOKEN_NONE; /* got ')' */
    }
  else if (quark == quark_load_wave)
    {
      BseFreqArray *skip_list, *load_list, *array;
      gchar *file_name, *wave_name;
      BseErrorType error;
      
      g_scanner_get_next_token (scanner); /* eat quark identifier */
      parse_or_return (scanner, G_TOKEN_STRING);
      file_name = g_strdup (scanner->value.v_string);
      if (g_scanner_get_next_token (scanner) != G_TOKEN_STRING)
	{
	  g_free (file_name);
	  return G_TOKEN_STRING;
	}
      wave_name = g_strdup (scanner->value.v_string);
      skip_list = bse_freq_array_new (1024);
      load_list = bse_freq_array_new (1024);
      if (BSE_STORAGE_COMPAT (storage, 0, 6, 4))
        while (g_scanner_get_next_token (scanner) != ')')
          {
            if (scanner->token == G_TOKEN_IDENTIFIER)
              {
                if (strcmp (scanner->value.v_identifier, "list") == 0)
                  array = load_list;
                else if (strcmp (scanner->value.v_identifier, "skip") == 0)
                  array = skip_list;
                else
                  {
                    expected_token = G_TOKEN_IDENTIFIER; /* want _valid_ identifier */
                    goto out_of_load_wave;
                  }
                g_scanner_peek_next_token (scanner);
                if (scanner->next_token != G_TOKEN_INT && scanner->next_token != G_TOKEN_FLOAT)
                  {
                    g_scanner_get_next_token (scanner); /* eat invalid token */
                    expected_token = G_TOKEN_FLOAT;
                    goto out_of_load_wave;
                  }
                while (g_scanner_peek_next_token (scanner) == G_TOKEN_INT ||
                       g_scanner_peek_next_token (scanner) == G_TOKEN_FLOAT)
                  {
                    g_scanner_get_next_token (scanner); /* int or float */
                    bse_freq_array_append (array, scanner->token == G_TOKEN_FLOAT ? scanner->value.v_float : scanner->value.v_int64);
                  }
              }
            else
              {
                expected_token = ')';
                goto out_of_load_wave;
              }
          }
      else
        parse_or_return (scanner, ')');
      error = bse_wave_load_wave_file (wave, file_name, wave_name,
                                       bse_freq_array_n_values (load_list) ? load_list : 0, skip_list,
                                       FALSE);
      if (error)
	bse_storage_warn (storage, "failed to load wave \"%s\" from \"%s\": %s",
			  wave_name, file_name, bse_error_blurb (error));
      expected_token = G_TOKEN_NONE; /* got ')' */
    out_of_load_wave:
      g_free (file_name);
      g_free (wave_name);
      bse_freq_array_free (skip_list);
      bse_freq_array_free (load_list);
    }
  else if (BSE_STORAGE_COMPAT (storage, 0, 6, 4) && quark == quark_set_locator)
    {
      g_scanner_get_next_token (scanner); /* eat quark identifier */
      parse_or_return (scanner, G_TOKEN_STRING);
      gchar *file_name = g_strdup (scanner->value.v_string);
      if (g_scanner_get_next_token (scanner) != G_TOKEN_STRING)
	{
	  g_free (file_name);
	  return G_TOKEN_STRING;
	}
      gchar *wave_name = g_strdup (scanner->value.v_string);
      if (g_scanner_get_next_token (scanner) != ')')
	{
	  g_free (file_name);
	  g_free (wave_name);
	  return ')';
	}
      // g_print ("set-locator \"%s\" \"%s\"\n", file_name, wave_name);
      bse_wave_set_locator (wave, file_name, wave_name);
      expected_token = G_TOKEN_NONE; /* got ')' */
    }
  else if (quark == quark_wave_chunk)
    {
      ParsedWaveChunk parsed_wchunk = { NULL, NULL, 0, 0, 0 };

      g_scanner_get_next_token (scanner); /* eat quark identifier */
      g_scanner_peek_next_token (scanner);
      bse_storage_compat_dhreset (storage); /* VERSION-FIXME: needed for <= 0.5.1 */
      if (scanner->next_token == G_TOKEN_FLOAT || scanner->next_token == G_TOKEN_INT)
        {
          g_scanner_get_next_token (scanner);
          bse_storage_compat_dhoscf (storage, /* VERSION-FIXME: needed for <= 0.5.1 */
                                     (scanner->token == G_TOKEN_INT ?
                                      scanner->value.v_int64 : scanner->value.v_float));
          g_scanner_peek_next_token (scanner);

          if (scanner->next_token == G_TOKEN_FLOAT || scanner->next_token == G_TOKEN_INT)
            {
              g_scanner_get_next_token (scanner);
              bse_storage_compat_dhmixf (storage, /* VERSION-FIXME: needed for <= 0.5.1 */
                                         (scanner->token == G_TOKEN_INT ?
                                          scanner->value.v_int64 : scanner->value.v_float));
            }
        }

      expected_token = bse_storage_parse_rest (storage, wave,
					       (BseTryStatement) parse_wave_chunk,
                                               &parsed_wchunk);
      bse_storage_compat_dhreset (storage); /* VERSION-FIXME: needed for <= 0.5.1 */

      if (expected_token == G_TOKEN_NONE && parsed_wchunk.data_handle)
	{
	  if (0)
	    g_printerr ("restore-wave-chunk: nch=%u of=%f mf=%f dh=%p\n",
                        parsed_wchunk.wh_n_channels,
                        parsed_wchunk.wh_osc_freq, parsed_wchunk.wh_mix_freq,
                        parsed_wchunk.data_handle);
          if (parsed_wchunk.data_handle && parsed_wchunk.xinfos)
            {
              GslDataHandle *tmp_handle = parsed_wchunk.data_handle;
              parsed_wchunk.data_handle = gsl_data_handle_new_add_xinfos (parsed_wchunk.data_handle, parsed_wchunk.xinfos);
              gsl_data_handle_unref (tmp_handle);
            }
	  GslDataCache *dcache = gsl_data_cache_from_dhandle (parsed_wchunk.data_handle,
                                                              BSE_CONFIG (wave_chunk_padding) * parsed_wchunk.wh_n_channels);
          const gchar *ltype = bse_xinfos_get_value (parsed_wchunk.xinfos, "loop-type");
          GslWaveLoopType loop_type = ltype ? gsl_wave_loop_type_from_string (ltype) : GSL_WAVE_LOOP_NONE;
          SfiNum loop_start = bse_xinfos_get_num (parsed_wchunk.xinfos, "loop-start");
          SfiNum loop_end = bse_xinfos_get_num (parsed_wchunk.xinfos, "loop-end");
          SfiNum loop_count = bse_xinfos_get_num (parsed_wchunk.xinfos, "loop-count");
          if (loop_end <= loop_start)
            {
              loop_start = loop_end = 0;
              loop_type = GSL_WAVE_LOOP_NONE;
              loop_count = 0;
            }
          GslWaveChunk *wchunk = gsl_wave_chunk_new (dcache, parsed_wchunk.wh_mix_freq, parsed_wchunk.wh_osc_freq,
                                                     loop_type, loop_start, loop_end, loop_count);
	  gsl_data_cache_unref (dcache);
          /* we need to keep inlined data handles open to protect against storage (.bse file) overwriting */
          BseErrorType error = bse_wave_add_inlined_wave_chunk (wave, wchunk);
          if (!error)
            bse_wave_add_chunk (wave, wchunk);
          else
            {
              bse_storage_error (storage, "failed to reopen inlined data handle (%s): %s",
                                 gsl_data_handle_name (wchunk->dcache->dhandle), bse_error_blurb (error));
              gsl_wave_chunk_unref (wchunk);
            }
	}
      if (parsed_wchunk.data_handle)
	gsl_data_handle_unref (parsed_wchunk.data_handle);
      g_strfreev (parsed_wchunk.xinfos);
    }
  else /* chain parent class' handler */
    expected_token = BSE_OBJECT_CLASS (parent_class)->restore_private (object, storage, scanner);
  
  return expected_token;
}
Ejemplo n.º 2
0
static guint
gslwave_parse_wave_dsc (GScanner    *scanner,
			WaveDsc     *dsc,
			const gchar *wave_name)
{
  parse_or_return (scanner, '{');
  do
    switch (g_scanner_get_next_token (scanner))
      {
	guint i, token;
      case '}':
	return G_TOKEN_NONE;
      default:
	return '}';
      case GSL_WAVE_TOKEN_NAME:
	if (dsc->wdsc.name)
	  return '}';
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_STRING);
	if (wave_name)
	  {
	    if (strcmp (wave_name, scanner->value.v_string) == 0)
	      dsc->wdsc.name = g_strdup (scanner->value.v_string);
	    else
	      return gslwave_skip_rest_statement (scanner, 1);
	  }
	else
	  dsc->wdsc.name = g_strdup (scanner->value.v_string);
	break;
      case GSL_WAVE_TOKEN_CHUNK:
	if (g_scanner_peek_next_token (scanner) != '{')
	  parse_or_return (scanner, '{');
	i = dsc->wdsc.n_chunks++;
	dsc->wdsc.chunks = g_realloc (dsc->wdsc.chunks, sizeof (dsc->wdsc.chunks[0]) * dsc->wdsc.n_chunks);
	memset (dsc->wdsc.chunks + i, 0, sizeof (dsc->wdsc.chunks[0]) * 1);
	dsc->wdsc.chunks[i].mix_freq = dsc->dfl_mix_freq;
	dsc->wdsc.chunks[i].osc_freq = dsc->dfl_mix_freq;	/* we check this later */
	dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_JUMP;
	dsc->wdsc.chunks[i].loop_start = GSL_MAXLONG;
	dsc->wdsc.chunks[i].loop_end = -1;
	dsc->wdsc.chunks[i].loop_count = 1000000; /* FIXME */
	dsc->wdsc.chunks[i].loader_offset = 0;			/* offset in bytes */
	dsc->wdsc.chunks[i].loader_length = 0;			/* length in n_values */
	dsc->wdsc.chunks[i].loader_data1 = NULL;		/* file_name */
	dsc->wdsc.chunks[i].loader_data2 = NULL;		/* wave_name */
	token = gslwave_parse_chunk_dsc (scanner, dsc->wdsc.chunks + i);
	if (token != G_TOKEN_NONE)
	  return token;
	if (dsc->wdsc.chunks[i].loop_end < dsc->wdsc.chunks[i].loop_start)
	  {
	    dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_NONE;
	    dsc->wdsc.chunks[i].loop_start = 0;
	    dsc->wdsc.chunks[i].loop_end = 0;
	    dsc->wdsc.chunks[i].loop_count = 0;
	  }
	if (dsc->wdsc.chunks[i].osc_freq >= dsc->wdsc.chunks[i].mix_freq / 2.)
	  g_scanner_error (scanner, "wave chunk \"%s\" mixing frequency is invalid: mix_freq=%f osc_freq=%f",
			   dsc->wdsc.chunks[i].loader_data1 ? (gchar*) dsc->wdsc.chunks[i].loader_data1 : "",
			   dsc->wdsc.chunks[i].mix_freq,
			   dsc->wdsc.chunks[i].osc_freq);
	break;
      case GSL_WAVE_TOKEN_BYTE_ORDER:
	parse_or_return (scanner, '=');
	token = g_scanner_get_next_token (scanner);
	switch (token)
	  {
	  case GSL_WAVE_TOKEN_LITTLE_ENDIAN:
	  case GSL_WAVE_TOKEN_LITTLE:		dsc->byte_order = G_LITTLE_ENDIAN; break;
	  case GSL_WAVE_TOKEN_BIG_ENDIAN:
	  case GSL_WAVE_TOKEN_BIG:		dsc->byte_order = G_BIG_ENDIAN;    break;
	  default:				return GSL_WAVE_TOKEN_LITTLE_ENDIAN;
	  }
	break;
      case GSL_WAVE_TOKEN_FORMAT:
	parse_or_return (scanner, '=');
	token = g_scanner_get_next_token (scanner);
	switch (token)
	  {
	  case GSL_WAVE_TOKEN_SIGNED_8:		dsc->format = GSL_WAVE_FORMAT_SIGNED_8;    break;
	  case GSL_WAVE_TOKEN_SIGNED_12:	dsc->format = GSL_WAVE_FORMAT_SIGNED_12;   break;
	  case GSL_WAVE_TOKEN_SIGNED_16:	dsc->format = GSL_WAVE_FORMAT_SIGNED_16;   break;
	  case GSL_WAVE_TOKEN_UNSIGNED_8:	dsc->format = GSL_WAVE_FORMAT_UNSIGNED_8;  break;
	  case GSL_WAVE_TOKEN_UNSIGNED_12:	dsc->format = GSL_WAVE_FORMAT_UNSIGNED_12; break;
	  case GSL_WAVE_TOKEN_UNSIGNED_16:	dsc->format = GSL_WAVE_FORMAT_UNSIGNED_16; break;
	  case GSL_WAVE_TOKEN_FLOAT:		dsc->format = GSL_WAVE_FORMAT_FLOAT;	   break;
	  default:				return GSL_WAVE_TOKEN_SIGNED_16;
	  }
	break;
      case GSL_WAVE_TOKEN_N_CHANNELS:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	dsc->wdsc.n_channels = scanner->value.v_int;
	if (dsc->wdsc.n_channels < 1)
	  return G_TOKEN_INT;
	break;
      case GSL_WAVE_TOKEN_MIX_FREQ:
	parse_or_return (scanner, '=');
	switch (g_scanner_get_next_token (scanner))
	  {
	  case G_TOKEN_FLOAT:   dsc->dfl_mix_freq = scanner->value.v_float;    break;
	  case G_TOKEN_INT:     dsc->dfl_mix_freq = scanner->value.v_int;      break;
	  default:		return G_TOKEN_FLOAT;
	  }
	break;
      }
  while (TRUE);
}
Ejemplo n.º 3
0
static SfiTokenType
parse_wave_chunk (BseWave         *wave,
		  BseStorage      *storage,
                  GScanner        *scanner,
		  ParsedWaveChunk *pwchunk)
     
{
  if (g_scanner_peek_next_token (scanner) != G_TOKEN_IDENTIFIER)
    return SFI_TOKEN_UNMATCHED;
  
  GQuark quark = g_quark_try_string (scanner->next_value.v_string);
  if (quark == quark_xinfos)
    {
      g_scanner_get_next_token (scanner); /* eat identifier */
      g_strfreev (pwchunk->xinfos);
      pwchunk->xinfos = NULL;
      GTokenType token = bse_storage_parse_xinfos (storage, &pwchunk->xinfos);
      if (token != G_TOKEN_NONE)
        return token;
    }
  else if (bse_storage_match_data_handle (storage, quark))
    {
      guint expected_token;
      if (pwchunk->data_handle)
	return bse_storage_warn_skip (storage, "duplicate wave data reference");
      expected_token = bse_storage_parse_data_handle_rest (storage,
                                                           &pwchunk->data_handle,
                                                           &pwchunk->wh_n_channels,
                                                           &pwchunk->wh_mix_freq,
                                                           &pwchunk->wh_osc_freq);
      if (expected_token != G_TOKEN_NONE)
	return expected_token;
      if (!pwchunk->data_handle)
        bse_storage_warn (storage, "invalid wave data reference");
      /* closing brace already parsed by bse_storage_parse_data_handle_rest() */
      return G_TOKEN_NONE;
    }
  else if (BSE_STORAGE_COMPAT (storage, 0, 5, 1) && quark == quark_wave_handle)
    {
      guint expected_token;
      g_scanner_get_next_token (scanner); /* eat identifier */
      if (pwchunk->data_handle)
	return bse_storage_warn_skip (storage, "duplicate wave data reference");
      expected_token = bse_storage_parse_data_handle (storage,
                                                      &pwchunk->data_handle,
                                                      &pwchunk->wh_n_channels,
                                                      &pwchunk->wh_mix_freq,
                                                      &pwchunk->wh_osc_freq);
      if (expected_token != G_TOKEN_NONE)
	return expected_token;
      if (!pwchunk->data_handle)
        bse_storage_warn (storage, "invalid wave data reference");
    }
  else if (BSE_STORAGE_COMPAT (storage, 0, 5, 1) && quark == quark_n_channels)
    {
      g_scanner_get_next_token (scanner); /* eat quark identifier */
      parse_or_return (scanner, G_TOKEN_INT);
      bse_storage_compat_dhchannels (storage, scanner->value.v_int64);
    }
  else if (BSE_STORAGE_COMPAT (storage, 0, 6, 4) && (quark == quark_loop || quark == quark_ping_pong_loop))
    {
      g_scanner_get_next_token (scanner); /* eat quark identifier */
      if (quark == quark_loop)
        pwchunk->xinfos = bse_xinfos_add_value (pwchunk->xinfos, "loop-type", gsl_wave_loop_type_to_string (GSL_WAVE_LOOP_JUMP));
      if (quark == quark_ping_pong_loop)
        pwchunk->xinfos = bse_xinfos_add_value (pwchunk->xinfos, "loop-type", gsl_wave_loop_type_to_string (GSL_WAVE_LOOP_PINGPONG));
      parse_or_return (scanner, G_TOKEN_INT);
      pwchunk->xinfos = bse_xinfos_add_num (pwchunk->xinfos, "loop-count", scanner->value.v_int64);
      parse_or_return (scanner, G_TOKEN_INT);
      pwchunk->xinfos = bse_xinfos_add_num (pwchunk->xinfos, "loop-start", scanner->value.v_int64);
      parse_or_return (scanner, G_TOKEN_INT);
      pwchunk->xinfos = bse_xinfos_add_num (pwchunk->xinfos, "loop-end", scanner->value.v_int64);
    }
  else
    return SFI_TOKEN_UNMATCHED;
  return g_scanner_get_next_token (scanner) == ')' ? G_TOKEN_NONE : ')';
}
Ejemplo n.º 4
0
static guint
gslwave_parse_chunk_dsc (GScanner        *scanner,
			 GslWaveChunkDsc *chunk)
{
  parse_or_return (scanner, '{');
  do
    switch (g_scanner_get_next_token (scanner))
      {
      case '}':
	return G_TOKEN_NONE;
      default:
	return '}';
      case GSL_WAVE_TOKEN_FILE:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_STRING);
	g_free (chunk->loader_data1);	/* file_name */
	chunk->loader_data1 = g_strdup (scanner->value.v_string);
	break;
      case GSL_WAVE_TOKEN_INDEX:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_STRING);
	g_free (chunk->loader_data2);	/* wave_name */
	chunk->loader_data2 = g_strdup (scanner->value.v_string);
	break;
      case GSL_WAVE_TOKEN_MIX_FREQ:
	parse_or_return (scanner, '=');
	switch (g_scanner_get_next_token (scanner))
	  {
	  case G_TOKEN_FLOAT:	chunk->mix_freq = scanner->value.v_float;	break;
	  case G_TOKEN_INT:	chunk->mix_freq = scanner->value.v_int;		break;
	  default:		return G_TOKEN_FLOAT;
	  }
	break;
      case GSL_WAVE_TOKEN_OSC_FREQ:
	parse_or_return (scanner, '=');
	switch (g_scanner_get_next_token (scanner))
	  {
	  case G_TOKEN_FLOAT:	chunk->osc_freq = scanner->value.v_float;	break;
	  case G_TOKEN_INT:	chunk->osc_freq = scanner->value.v_int;		break;
	  default:		return G_TOKEN_FLOAT;
	  }
	break;
      case GSL_WAVE_TOKEN_MIDI_NOTE:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->osc_freq = gsl_temp_freq (gsl_get_config ()->kammer_freq,
					 scanner->value.v_int - gsl_get_config ()->midi_kammer_note);
	break;
      case GSL_WAVE_TOKEN_BOFFSET:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->loader_offset = scanner->value.v_int;	/* byte_offset */
	break;
      case GSL_WAVE_TOKEN_N_VALUES:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->loader_length = scanner->value.v_int;	/* n_values */
	break;
      case GSL_WAVE_TOKEN_LOOP_TYPE:
	parse_or_return (scanner, '=');
	switch (g_scanner_get_next_token (scanner))
	  {
	  case GSL_WAVE_TOKEN_NONE:	chunk->loop_type = GSL_WAVE_LOOP_NONE;		break;
	  case GSL_WAVE_TOKEN_JUMP:	chunk->loop_type = GSL_WAVE_LOOP_JUMP;		break;
	  case GSL_WAVE_TOKEN_PINGPONG:	chunk->loop_type = GSL_WAVE_LOOP_PINGPONG;	break;
	  default:			return GSL_WAVE_TOKEN_JUMP;
	  }
	break;
      case GSL_WAVE_TOKEN_LOOP_START:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->loop_start = scanner->value.v_int;
	break;
      case GSL_WAVE_TOKEN_LOOP_END:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->loop_end = scanner->value.v_int;
	break;
      case GSL_WAVE_TOKEN_LOOP_COUNT:
	parse_or_return (scanner, '=');
	parse_or_return (scanner, G_TOKEN_INT);
	chunk->loop_count = scanner->value.v_int;
	break;
      }
  while (TRUE);
}