Example #1
0
/**
 * Compute command
 */
void command_compute(char* line) {

    char cmd[MAX_BUFFER];
    char key[MAX_BUFFER];
    char func[MAX_BUFFER];
    char arg1[MAX_BUFFER];

    int argc = sscanf(line, "%s %s %s %s", cmd, func, key, arg1);
    if (argc < 3) {
        goto invalid;
    }

    MATRIX_GUARD(key);
    uint32_t result = 0;

    if (strcasecmp(func, "sum") == 0) {
        result = get_sum(m);
    } else if (strcasecmp(func, "trace") == 0) {
        result = get_trace(m);
    } else if (strcasecmp(func, "minimum") == 0) {
        result = get_minimum(m);
    } else if (strcasecmp(func, "maximum") == 0) {
        result = get_maximum(m);
    } else if (strcasecmp(func, "frequency") == 0) {
        result = get_frequency(m, atoll(arg1));
    } else {
        goto invalid;
    }

    printf("%" PRIu32 "\n", result);
    return;

invalid:
    puts("invalid arguments");
}
Example #2
0
static int
handle_event(struct measurements *m, const struct input_event *ev)
{
	if (ev->type == EV_SYN) {
		const int idle_reset = 3000000; /* us */
		uint64_t last_us = m->us;

		m->us = tv2us(&ev->time);

		/* reset after pause */
		if (last_us + idle_reset < m->us) {
			m->max_frequency = 0.0;
			m->distance = 0;
		} else {
			double freq = get_frequency(last_us, m->us);
			push_frequency(m, freq);
			m->max_frequency = max(freq, m->max_frequency);
			return print_current_values(m);
		}

		return 0;
	} else if (ev->type != EV_REL)
		return 0;

	switch(ev->code) {
		case REL_X:
			m->distance += ev->value;
			break;
	}

	return 0;
}
Example #3
0
void create_note(synth_note * sn, int note, int octave, float start_time, float len)
{
	sn->note = note;
	sn->octave = octave;
	sn->start_time = start_time;
	sn->end_time = start_time + len;

	printf("Start Time: %f\n", sn->start_time);
	printf("End Time: %f\n", sn->end_time);

	//create sin waves
	sin_wave base;
	init(&base, 0.15, 0.0, get_frequency(note, octave));


	create_envelope(&(sn->env), 0.1, len);

	sn->num_waves = 8;
	sn->waves = (sin_wave *) malloc(sizeof(sin_wave) * sn->num_waves);
	sn->waves[0] = base;
	harmonic(&(sn->waves[1]), &(sn->waves[0]), 2);
	harmonic(&(sn->waves[2]), &(sn->waves[0]), 3);
	harmonic(&(sn->waves[3]), &(sn->waves[0]), 4);
	harmonic(&(sn->waves[4]), &(sn->waves[0]), 5);
	harmonic(&(sn->waves[5]), &(sn->waves[0]), 6);
	harmonic(&(sn->waves[6]), &(sn->waves[0]), 7);
	harmonic(&(sn->waves[7]), &(sn->waves[0]), 8);
}
 uint64_t query(factor Factor) const
 {
     const auto Diff = call_function(QueryPerformanceCounter) - m_StartTime;
     const auto Frequency = get_frequency();
     const auto Whole = Diff / Frequency;
     const auto Fraction = Diff % Frequency;
     return Whole * Factor + (Fraction * Factor) / Frequency;
 }
Example #5
0
static void wireless_frequency(RESULT * result, RESULT * arg1)
{
    char *dev = R2S(arg1);
    if (check_socket() != 0)
	return;

    save_result(result, dev, KEY_FREQUENCY, get_frequency(dev, KEY_FREQUENCY));
}
Example #6
0
namespace stopwatch
{
#if defined(_MSC_VER)
  inline double get_frequency()
  {
    LARGE_INTEGER proc_freq;
    ::QueryPerformanceFrequency(&proc_freq);
    return 1000.*1000.*1000./(double)proc_freq.QuadPart;
  }
  static const double frequency = get_frequency();
#endif

  unsigned int depth = 0;
  unsigned int counter = 0;


  // function to get current time
  inline double current_time()
  {
#if defined(__GNUC__)
    timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    double t = ts.tv_sec * 1000 * 1000 * 1000;
    t += ts.tv_nsec;
    return t;
#elif defined(_MSC_VER)
    LARGE_INTEGER ts;
    ::QueryPerformanceCounter(&ts);
    return (double)ts.QuadPart/(double)frequency;
#endif
  }
  
  struct stopwatch_object
  {
    stopwatch_object() : name_(0), depth_(0), timestamp_(0.0) {}
    stopwatch_object(const char *& name) : 
    name_(name), depth_(depth), timestamp_(current_time()) 
    {}
    
    const char * name_;
    unsigned int depth_;
    double timestamp_;
  };
  
  struct map_entry
  {
    stopwatch::stopwatch_object swo;
    bool even;
    unsigned int invocations;
    double timestamp_buff;
    unsigned int num;
  };
  
  // this initialization may cause the stopwatch to segfault if more than
  // data.size()/2 different measurements are taken
  std::vector<stopwatch_object> data(500000);
}
Example #7
0
/*****************************************************************
 * \brief public wrapper for get_frequency
 * \parameter frequency pointer to float, which will contain frequency in MHz
 * \return 1 if success,0 - otherwise
 */
int radio_get_freq(struct stream *stream, float *frequency) {
    radio_priv_t* priv=(radio_priv_t*)stream->priv;

    if (!frequency)
        return 0;
    if (get_frequency(priv,frequency)!=STREAM_OK) {
        return 0;
    }
    return 1;
}
Example #8
0
void Group::generate(float *buf, size_t samples)
{
   Waveform type = (Waveform) list.get_cur_value();
   float frequency = get_frequency();
   float phase = get_phase();

   generate_wave(type, buf, samples, t, frequency, phase);

   t += dt * samples;
}
Example #9
0
void synth_run_16bit(synth_state* synth, short* audiobuffer, long nframes)
{
  for(int c=0;c < synth->num_channels;++c) {
    float freq = get_frequency(c);
    float phase_inc = 2.0 * M_PI * freq / synth->sample_rate;
    for(long n=0;n < nframes;++n) {
      audiobuffer[n*synth->num_channels+c] = sin(synth->phase[c]) * VOLUME * 32767.0f;
      synth->phase[c] += phase_inc;
    }
  }
}
/*****************************************************************
 * \brief public wrapper for set_frequency
 * \parameter frequency frequency in MHz
 * \return 1 if success,0 - otherwise
 */
int radio_set_freq(struct stream_st *stream, float frequency){
    radio_priv_t* priv=(radio_priv_t*)stream->priv;

    if (set_frequency(priv,frequency)!=STREAM_OK){
        return 0;
    }
    if (get_frequency(priv,&frequency)!=STREAM_OK){
        return 0;
    }
    mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_CurrentFreq,frequency);
    return 1;
}
Example #11
0
void Group::update_labels()
{
   char buf[32];
   float frequency = get_frequency();
   float phase = get_phase();

   sprintf(buf, "%4.0f Hz", frequency);
   freq_val_label.set_text(buf);

   sprintf(buf, "%.2f π", phase/PI);
   phase_val_label.set_text(buf);
}
Example #12
0
/*****************************************************************
 * \brief public wrapper for set_frequency
 * \parameter frequency frequency in MHz
 * \return 1 if success,0 - otherwise
 */
int radio_set_freq(struct stream *stream, float frequency) {
    radio_priv_t* priv=(radio_priv_t*)stream->priv;

    if (set_frequency(priv,frequency)!=STREAM_OK) {
        return 0;
    }
    if (get_frequency(priv,&frequency)!=STREAM_OK) {
        return 0;
    }
    mp_tmsg(MSGT_RADIO, MSGL_INFO, "[radio] Current frequency: %.2f\n",frequency);
    return 1;
}
Example #13
0
static PyObject *
python_get_frequency(PyObject *self, PyObject *args ) {
	char    *usage = "Usage: _seisparams._get_frequency( magnitude, depth, distance )";
	PyObject *obj;
	double retval, magnitude, depth, distance;

	if( ! PyArg_ParseTuple( args, "ddd", &magnitude, &depth, &distance ) ) {
		USAGE;
		return NULL;
	}
	retval=get_frequency( magnitude, depth, distance);
	obj =  Py_BuildValue( "d", retval );
	return obj;
	
}
Example #14
0
/*****************************************************************
 * \brief tune current frequency by step_interval value
 * \parameter step_interval increment value
 * \return 1 if success,0 - otherwise
 *
 */
int radio_step_freq(struct stream *stream, float step_interval) {
    float frequency;
    radio_priv_t* priv=(radio_priv_t*)stream->priv;

    if (get_frequency(priv,&frequency)!=STREAM_OK)
        return 0;

    frequency+=step_interval;
    if (frequency>priv->rangehigh)
        frequency=priv->rangehigh;
    if (frequency<priv->rangelow)
        frequency=priv->rangelow;

    return radio_set_freq(stream,frequency);
}
Example #15
0
uint64_t get_time_usecs() {
    static LARGE_INTEGER frequency = get_frequency();
    static bool old_windows = is_xp_or_older();

    CRITICAL_SECTION mutex;
    LARGE_INTEGER time;

    if (old_windows) {
        InitializeCriticalSection(&mutex);
        EnterCriticalSection(&mutex);
        QueryPerformanceCounter(&time);
        LeaveCriticalSection(&mutex);
    } else {
        QueryPerformanceCounter(&time);
    }

    return (1000000 * time.QuadPart / frequency.QuadPart)
}
Example #16
0
verdict test_randomized()
{
#if !defined(NO_RANDOMIZATION)
    srand (unsigned(get_time_stamp()/get_frequency())); // Randomize pseudo random number generator
#endif
    std::cout << "=================== Randomized Test ===================" << std::endl;

    size_t a1 = 0, a2 = 0;
    std::vector<long long> mediansV(K); // Final verdict of medians for each of the K experiments with visitors
    std::vector<long long> mediansM(K); // Final verdict of medians for each of the K experiments with matching
    std::vector<long long> timingsV(M);
    std::vector<long long> timingsM(M);
    std::vector<Shape*>    shapes(N);

    for (size_t k = 0; k < K; ++k)
    {
        for (size_t i = 0; i < N; ++i)
            shapes[i] = make_shape(rand());

        run_timings(shapes, timingsV, timingsM, a1, a2);
        mediansV[k] = display("AreaVisRnd", timingsV);
        mediansM[k] = display("AreaMatRnd", timingsM);
        std::cout << "\t\t" << verdict(mediansV[k], mediansM[k]) << std::endl;

        for (size_t i = 0; i < N; ++i)
        {
            delete shapes[i];
            shapes[i] = 0;
        }
    }

    if (a1 != a2)
    {
        std::cout << "ERROR: Invariant " << a1 << "==" << a2 << " doesn't hold." << std::endl;
        exit(42);
    }

    std::sort(mediansV.begin(), mediansV.end());
    std::sort(mediansM.begin(), mediansM.end());
    return verdict(mediansV[K/2],mediansM[K/2]);
}
Example #17
0
/**
 * Compute command.
 */
void command_compute(char* line) {

	char cmd[MAX_BUFFER];
	char key[MAX_BUFFER];
	char func[MAX_BUFFER];
	char arg1[MAX_BUFFER];

	int argc = sscanf(line, "%s %s %s %s", cmd, func, key, arg1);
	if (argc < 3) {
		goto invalid;
	}

	MATRIX_GUARD(key);
	float result = 0;

	if (strcasecmp(func, "sum") == 0) {
		result = get_sum(m);
	} else if (strcasecmp(func, "trace") == 0) {
		result = get_trace(m);
	} else if (strcasecmp(func, "minimum") == 0) {
		result = get_minimum(m);
	} else if (strcasecmp(func, "maximum") == 0) {
		result = get_maximum(m);
	} else if (strcasecmp(func, "determinant") == 0) {
		result = get_determinant(m);
	} else if (strcasecmp(func, "frequency") == 0) {
		ssize_t count = get_frequency(m, atof(arg1));
		printf("%zu\n", count);
		return;
	} else {
		goto invalid;
	}

	printf("%.2f\n", result);
	return;

invalid:
	puts("invalid arguments");
}
Example #18
0
	BoxClass::current_tone_list BoxClass::GetCurrentTones()
	{
		ScopedLock lock(mutex);
		current_tone_list retval;
		if (!box) return retval;
		struct mutabor_logic_parsed * file = box->file;
		if (!file) return retval;
		// no file means no logic (implying no current logic)

		int count = box->key_count;
		if (!count) return retval;
		retval.resize(count);

		size_t i = 0;
		for (mutabor_note_type * key = mutabor_find_key_in_box(box,0);
		     key != NULL;
		     key = mutabor_find_key_in_box(box,key->next)) {

			int index = key->number;
			mutabor_tone tone;

			switch (tone=get_frequency(index)) {
			case MUTABOR_NO_KEY:
				break;
			case MUTABOR_INVALID_KEY:
				retval[i].flag=tone_entry::invalid;
				break;
			default:
				retval[i] = current_tone_entry(index,
							       mutabor_convert_tone_to_pitch(tone),
							       key->id,
							       GetChannel(index, key->channel, key->id));
			}
			++i;
		}
		return retval;
	}
Example #19
0
int main(int argc, char *argv[]){

  // 1. Initialization
  int c;
  symbol *root;
  root=init_symbol(ROOT_NODE);
  root->frequency=NON_EXISTENT;
  root->parent=root;
  
  // 1.a. init: file pointers
  FILE *inputfile;
  FILE *outputfile;
  inputfile=NULL;
  outputfile=NULL;

  if (argc >=2)
    inputfile = fopen(argv[1],"r");
  
  if (argc >=3)
    outputfile = fopen(argv[2],"w");
  
  if (inputfile == NULL) {
    fprintf(stderr, "Can't open input file. \n");
    exit(1);
  }

  if (outputfile == NULL) {
    outputfile=stdout;
  }
  
  // 2. count the frequency of each character in inputfile 
  while((c=fgetc(inputfile))!=EOF){
    update_frequency(root,c);
  }
  update_frequency(root,-1);


  // 3. Make the huffman tree
  while(count_parentless_nodes(root) > 1){
    symbol *node1,*node2, *newnode;
    node1 = get_rarest_parentless_node(root);
    node1->parent=node1; //temporarily
    node2 = get_rarest_parentless_node(root);
    node2->parent=node2; //temporarily
    newnode = new_node(node1, node2);
    insert_symbol(root,newnode);
  }


  // 4. Output symbol mappings
  for(c=-1;c<256;c++){
    char *encodingstring;
    encodingstring=get_encoding(root,c);
    int freq=get_frequency(root,c);
    if (freq > 0){
      /*if (c <=127 && c>=32 )
	fprintf(outputfile,"%c\t%d\t%s\n", c, freq, encodingstring);    
      else */
	fprintf(outputfile,"%d\t%d\t%s\n", c, freq, encodingstring);    
    }
    free(encodingstring);
  }
  fprintf(outputfile,"\n");    

  
  // 5. Output encoding of inputfile
  rewind(inputfile);
  while((c=fgetc(inputfile))!=EOF){
    char *encodingstring;
    encodingstring=get_encoding(root,c);
    fprintf(outputfile, "%s", encodingstring);
    free(encodingstring);
  }
  char *encodingstring;
  encodingstring=get_encoding(root,EOF);
  fprintf(outputfile, "%s", encodingstring);
  free(encodingstring);
  fprintf(outputfile,"\n");    

  free_symbol(root);
  
  
  // 6. Close file pointers
  fclose(inputfile);
  fclose(outputfile);
}
Example #20
0
	GameClock::GameClock()
		: m_start_time {}, m_current_time {}, m_last_time {}, m_frequency {} {
		m_frequency = get_frequency();
		reset();
	}
Example #21
0
bool cpu_frequency::set_frequency(cpu_frequency_type type,unsigned long khz,unsigned long khzUpper,unsigned long khzLower)
  {
  if(!valid) return false;
  bool governorAvailable = false;
  bool freqMatched = false;
  bool upperMatched = false;
  bool lowerMatched = false;
  for(std::vector<cpu_frequency_type>::iterator i = available_governors.begin();i != available_governors.end();i++)
    {
    if(*i == type)
      {
      governorAvailable = true;
      break;
      }
    }
  for(std::vector<unsigned long>::iterator i = available_frequencies.begin();i != available_frequencies.end();i++)
    {
    if(*i == khz) freqMatched = true;
    if(*i == khzUpper) upperMatched = true;
    if(*i == khzLower) lowerMatched = true;
    }
  if(!governorAvailable || !upperMatched || !lowerMatched || !freqMatched)
    {
    last_error = PBSE_FREQUENCY_NOT_AVAILABLE;
    return false;
    }
  std::string govString;
  get_governor_string(type,govString);
  if(!set_string_in_file(path + "scaling_governor",govString))
    {
    return false;
    }
  unsigned long currKHz;
  unsigned long currKHzUpper;
  unsigned long currKHzLower;
  cpu_frequency_type currType;
  if(!get_frequency(currType,currKHz,currKHzUpper,currKHzLower))
    {
    return false;
    }
  if(khzUpper < currKHzLower)
    {
    if(!set_number_in_file(path + "scaling_min_freq",khzLower))
      {
      return false;
      }
    if(!set_number_in_file(path + "scaling_max_freq",khzUpper))
      {
      return false;
      }
    }
  else
    {
    if(!set_number_in_file(path + "scaling_max_freq",khzUpper))
      {
      return false;
      }
    if(!set_number_in_file(path + "scaling_min_freq",khzLower))
      {
      return false;
      }
    }
  if(type == UserSpace)
    {
    if(!set_number_in_file(path + "scaling_setspeed",khz))
      {
      return false;
      }
    }
  return true;
  }
Example #22
0
	unsigned long operator()(
		SampleSource &sample_source, InputProperties const &input_properties,
		void *output, unsigned long const num_output_samples, OutputProperties const &output_properties,
		unsigned int const volume, unsigned int const max_volume
	)
	{
		// prerequisites

		unsigned int num_input_channels = get_num_channels(input_properties);
		unsigned int num_output_channels = get_num_channels(output_properties);
		unsigned int input_frequency = get_frequency(input_properties);
		unsigned int output_frequency = get_frequency(output_properties);

		if (input_frequency == 0) // if the input frequency is 0, then the sample source can adapt to the output frequency
			input_frequency = output_frequency;

		bool frequencies_match = (input_frequency == output_frequency);
		bool num_channels_match = (num_input_channels == num_output_channels);
		bool sample_types_match = get_sample_type(input_properties) == get_sample_type(output_properties);


		// if the properties fully match, no processing is necessary - just transmit the samples directly to the output and exit
		// do a volume processing if necessary, but otherwise its just one transmission
		if (frequencies_match && sample_types_match && num_channels_match)
		{
			unsigned long num_retrieved_samples = retrieve_samples(sample_source, output, num_output_samples);

			if (volume != max_volume)
			{
				sample_type output_sample_type = get_sample_type(output_properties);
				for (unsigned long i = 0; i < num_retrieved_samples * num_output_channels; ++i)
				{
					set_sample_value(
						output, i,
						adjust_sample_volume(get_sample_value(output, i, output_sample_type), volume, max_volume),
						output_sample_type
					);
				}
			}

			return num_retrieved_samples;
		}


		unsigned long num_retrieved_samples = 0;
		uint8_t *resampler_input = 0;
		sample_type dest_type = sample_unknown;
		// note that this returns true if the resampler is in an uninitialized state
		bool resampler_needed_more_input = is_more_input_needed_for(resampler, num_output_samples);



		// first processing stage: convert samples & mix channels if necessary
		// also, the resampler input is prepared here
		// if resampling is necessary, and the resampler has enough input data for now, this stage is bypassed

		if (frequencies_match || resampler_needed_more_input)
		{
			// with the adjusted value from above, retrieve samples from the sample source, and resize the buffer to the number of actually retrieved samples
			// (since the sample source may have given us less samples than we requested)
			unsigned long num_samples_to_retrieve = num_output_samples;
			source_data_buffer.resize(num_samples_to_retrieve * num_input_channels * get_sample_size(get_sample_type(input_properties)));
			num_retrieved_samples = retrieve_samples(sample_source, &source_data_buffer[0], num_samples_to_retrieve);
			source_data_buffer.resize(num_retrieved_samples * num_input_channels * get_sample_size(get_sample_type(input_properties)));

			// here, the dest and dest_type values are set, as well as the resampler input (if necessary)
			// several optimizations are done here: if the resampler is not necessary, then dest points to the output - any conversion steps will write data directly to the output then
			// if the resampler is necessary, and the sample types match, then the resampler's input is the source data buffer, otherwise it is the "dest" pointer
			// the reason for this is: if the sample types match, no conversion step is necessary, and the resampler can pull data directly from the source data buffer;
			// otherwise, the conversion step needs to convert to an intermediate buffer (the buffer the dest pointer points at), and then the resampler pulls data from this buffer
			uint8_t *dest;
			if (frequencies_match)
			{
				// frequencies match - dest is set to point at the output, meaning that the next step will directly write to the output
				dest_type = get_sample_type(output_properties);
				dest = reinterpret_cast < uint8_t* > (output);
			}
			else
			{
				// frequencies do not match, resampling is necessary - dest is set to point at an intermediate buffer, which the resampler will use

				// ask the resampler what resampling input type it needs - this may differ from the output properties' sample type, but this is ok,
				// since with resampling, an intermediate step between sample type conversion & mixing and actual output is present anyway
				dest_type = find_compatible_type(resampler, get_sample_type(input_properties));

				if (sample_types_match && num_channels_match)
				{
					// if the sample types and channel count match, then no conversion step is necessary, and the resampler can pull data from the source data buffer directly
					resampler_input = &source_data_buffer[0];
					dest = 0;
				}
				else
				{
					// if the sample types and channel count do not match, then the resampler needs to pull data from the intermediate buffer dest points to
					// the conversion step will write to dest
					resampling_input_buffer.resize(num_output_samples * num_output_channels * get_sample_size(dest_type));
					dest = &resampling_input_buffer[0];
					resampler_input = dest;
				}
			}


			// actual mixing and conversion is done here
			if (num_channels_match)
			{
				// channel counts match, no mixing necessary

				if (!sample_types_match)
				{
					assert(dest != 0);

					// sample types do not match
					// go through all the input samples, convert them, and write them to dest
					for (unsigned long i = 0; i < num_retrieved_samples * num_input_channels; ++i)
					{
						set_sample_value(
							dest, i,
							convert_sample_value(
								get_sample_value(&source_data_buffer[0], i, get_sample_type(input_properties)),
								get_sample_type(input_properties), dest_type
							),
							dest_type
						);
					}
				}

				// if the sample types match, nothing needs to be done here
			}
			else
			{
				// channels count do not match - call the mixer
				mix_channels(&source_data_buffer[0], dest, num_retrieved_samples, get_sample_type(input_properties), dest_type, get_num_channels(input_properties), get_num_channels(output_properties));
			}
		}
		else
		{
			// either resampling is not necessary, or the resampler does not need any new input for now
			// set number of retrieved samples to number of output samples, and if resampling is necessary, set the dest_type value

			num_retrieved_samples = num_output_samples;

			// the dest_type value is set, since the resampler might reset itself if it sees a change in the input type
			if (!frequencies_match)
				dest_type = find_compatible_type(resampler, get_sample_type(input_properties));
		}


		// the final stage adjusts the output volume; if the volume equals the max volume, it is unnecessary
		// this boolean conditionally enables this stage
		bool do_volume_stage = (volume != max_volume);


		// second processing stage: resample if necessary (otherwise this stage is bypassed)
		if (!frequencies_match)
		{
			sample_type resampler_input_type = dest_type;

			// the resampler may have only support for a fixed number of sample types - let it choose a suitable output one
			sample_type resampler_output_type = find_compatible_type(resampler, resampler_input_type, get_sample_type(output_properties));
			sample_type output_type = get_sample_type(output_properties);
			bool conversion_needed = (resampler_output_type != output_type);

			uint8_t *resampler_output = reinterpret_cast < uint8_t* > (output);
			if (conversion_needed)
			{
				resampling_output_buffer.resize(num_output_samples * num_output_channels * get_sample_size(resampler_output_type));
				resampler_output = &resampling_output_buffer[0];
			}

			// resampler input -can- be zero - sometimes the resampler does not need any more input
			assert(!resampler_needed_more_input || (resampler_input != 0));

			// call the actual resampler, which returns the number of samples that were actually sent to output
			// if this is the first call since the resampler was reset(), this call internally initializes the resampler
			// and sets its internal values to the given ones
			// note that the is_more_input_needed_for() call returns true if the resampler is in such an uninitialized state
			// if the resampler was initialized already, it may reinitialize itself internally if certain parameters change
			// (this is entirely implementation-dependent; from the outside, no such reinitialization is noticeable)
			num_retrieved_samples = resample(
				resampler,
				resampler_input, num_retrieved_samples,
				resampler_output, num_output_samples,
				input_frequency, output_frequency,
				resampler_input_type, resampler_output_type,
				num_output_channels
			);

			// the output type chosen by the resampler may not match the output type given by the output properties, so a final conversion step may be necessary
			if (conversion_needed)
			{
				if (do_volume_stage)
				{
					// if the volume stage is required, use the opportunity to do it together with the final conversion step
					for (unsigned long i = 0; i < num_retrieved_samples * num_output_channels; ++i)
					{
						set_sample_value(
							output, i,
							adjust_sample_volume(
								get_sample_value(resampler_output, i, resampler_output_type),
								volume, max_volume
							),
							output_type
						);
					}

					// volume adjustment was done in-line in the conversion step above -> no further volume adjustment required
					do_volume_stage = false;
				}
				else
				{
					// conversion without volume adjustment
					for (unsigned long i = 0; i < num_retrieved_samples * num_output_channels; ++i)
						set_sample_value(output, i, get_sample_value(resampler_output, i, output_type), output_type);
				}
			}
		}


		// do the volume stage if required
		if (do_volume_stage)
		{
			sample_type output_sample_type = get_sample_type(output_properties);
			for (unsigned long i = 0; i < num_retrieved_samples * num_output_channels; ++i)
			{
				set_sample_value(
					output, i,
					adjust_sample_volume(get_sample_value(output, i, output_sample_type), volume, max_volume),
					output_sample_type
				);
			}
		}


		// finally, return the number of retrieved samples, either from the resampler, or from the source directly,
		// depending on whether or not resampling was necessary
		return num_retrieved_samples;
	}