UINT CSoundFile::Read( LPVOID lpBuffer, UINT cbBuffer ) {
	mpcpplog();
	if ( !mod ) {
		return 0;
	}
	mpcpplog();
	if ( !lpBuffer ) {
		return 0;
	}
	mpcpplog();
	if ( cbBuffer <= 0 ) {
		return 0;
	}
	mpcpplog();
	if ( get_samplerate() <= 0 ) {
		return 0;
	}
	mpcpplog();
	if ( get_sample_size() != 1 && get_sample_size() != 2 && get_sample_size() != 4 ) {
		return 0;
	}
	mpcpplog();
	if ( get_num_channels() != 1 && get_num_channels() != 2 && get_num_channels() != 4 ) {
		return 0;
	}
	mpcpplog();
	std::memset( lpBuffer, 0, cbBuffer );
	const std::size_t frames_torender = cbBuffer / get_frame_size();
	std::int16_t * out = (std::int16_t*)lpBuffer;
	std::vector<std::int16_t> tmpbuf;
	if ( get_sample_size() == 1 || get_sample_size() == 4 ) {
		tmpbuf.resize( frames_torender * get_num_channels() );
		out = &tmpbuf[0];
	}

	mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, get_filter_length() );
	std::size_t frames_rendered = 0;
	if ( get_num_channels() == 1 ) {
		frames_rendered = mod->read( get_samplerate(), frames_torender, out );
	} else if ( get_num_channels() == 4 ) {
		frames_rendered = mod->read_interleaved_quad( get_samplerate(), frames_torender, out );
	} else {
		frames_rendered = mod->read_interleaved_stereo( get_samplerate(), frames_torender, out );
	}

	if ( get_sample_size() == 1 ) {
		std::uint8_t * dst = (std::uint8_t*)lpBuffer;
		for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
			dst[sample] = ( tmpbuf[sample] / 0x100 ) + 0x80;
		}
	} else if ( get_sample_size() == 4 ) {
		std::int32_t * dst = (std::int32_t*)lpBuffer;
		for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
			dst[sample] = tmpbuf[sample] << (32-16-1-MIXING_ATTENUATION);
		}
	}
	return frames_rendered * get_frame_size();
}
Esempio n. 2
0
/**
 * \brief Sets the volume of a channel.
 * \param channel A channel index.
 * \param volume The volume to set.
 */
void ItDecoder::set_channel_volume(int channel, int volume) {

  const unsigned int num_channels = get_num_channels();
  const unsigned int num_patterns = ModPlug_NumPatterns(modplug_file);

  for (unsigned int pattern = 0; pattern < num_patterns; ++pattern) {
    unsigned int num_rows;
    ModPlugNote* notes = ModPlug_GetPattern(modplug_file, pattern, &num_rows);
    for (unsigned int j = channel; j < num_rows * num_channels; j += num_channels) {
      notes[j].Volume = volume;
    }
  }
}
Esempio n. 3
0
File: chls.cpp Progetto: d-zenju/aws
bool c_chls::send_cmd(int argc, char ** argv)
{
  int num_channels = get_num_channels();
  if(num_channels < 0){
    cerr << "Channel List cannot be enumerated." << endl;
    return false;
  }
  cout << "#Channel List (" << num_channels << ") channels found." << endl;

  for(int ichannel = 0; ichannel < num_channels; ichannel++){
    if(!get_channel_inf(ichannel)){
      cerr << "Failed to list channels." << endl;
    }
  }
  return true;
}
Esempio n. 4
0
/**
 * \brief Returns the volume of a channel.
 * \param channel A channel index.
 * \return The volume of this channel.
 */
int ItDecoder::get_channel_volume(int channel) {

  const int num_patterns = ModPlug_NumPatterns(modplug_file);

  Debug::check_assertion(channel >= 0 && channel < get_num_channels(),
      "Invalid channel number");

  if (num_patterns == 0) {
    return 0;
  }

  unsigned int num_rows = 0;
  ModPlugNote* notes = ModPlug_GetPattern(modplug_file, 0, &num_rows);

  if (num_rows == 0) {
    return 0;
  }

  return notes[0].Volume;
}
Esempio n. 5
0
GLenum get_suitable_internal_format(const GLenum format, const GLenum type,
        const bool use_compression) noexcept
{
    const int num_channels = get_num_channels(format);
    const bool int_format = is_integer_format(format);
    const bool snorm = is_signed(type);
    const bool has_s3tc = glewIsSupported("EXT_texture_compression_s3tc");
    const bool has_rgtc = glewIsSupported("ARB_texture_compression_rgtc");
    const bool has_bptc = glewIsSupported("ARB_texture_compression_bptc");

    GLenum internal_format;

    if (num_channels == 1) {
        if (use_compression && !int_format && has_rgtc) {
            internal_format = snorm ? GL_COMPRESSED_SIGNED_RED_RGTC1 :
                GL_COMPRESSED_RED_RGTC1;
        } else if (type == GL_FLOAT) {
            internal_format = GL_R32F;
        } else if (type == GL_INT) {
            // GL_R32_SNORM not available! Choose closest.
            internal_format = int_format ? GL_R32I : GL_R16_SNORM;
        } else if (type == GL_UNSIGNED_INT) {
            // GL_R32 not available! Choose closest.
            internal_format = int_format ? GL_R32UI : GL_R16;
        } else if (type == GL_SHORT) {
            internal_format = int_format ? GL_R16I : GL_R16_SNORM;
        } else if (type == GL_UNSIGNED_SHORT) {
            internal_format = int_format ? GL_R16UI : GL_R16;
        } else if (type == GL_BYTE) {
            internal_format = int_format ? GL_R8I : GL_R8_SNORM;
        } else {
            // just use GL_R8 for everything else
            internal_format = int_format ? GL_R8UI : GL_R8;
        }
    } else if (num_channels == 2) {
        if (use_compression && !int_format && has_rgtc) {
            internal_format = snorm ? GL_COMPRESSED_SIGNED_RG_RGTC2 :
                GL_COMPRESSED_RG_RGTC2;
        } else if (type == GL_FLOAT) {
            internal_format = GL_RG32F;
        } else if (type == GL_INT) {
            // GL_RG32_SNORM not available! Choose closest.
            internal_format = int_format ? GL_RG32I : GL_RG16_SNORM;
        } else if (type == GL_UNSIGNED_INT) {
            // GL_RG32 not available! Choose closest.
            internal_format = int_format ? GL_RG32UI : GL_RG16;
        } else if (type == GL_SHORT) {
            internal_format = int_format ? GL_RG16I : GL_RG16_SNORM;
        } else if (type == GL_UNSIGNED_SHORT) {
            internal_format = int_format ? GL_RG16UI : GL_RG16;
        } else if (type == GL_BYTE) {
            internal_format = int_format ? GL_RG8I : GL_RG8_SNORM;
        } else {
            // just use GL_RG8 for everything else
            internal_format = int_format ? GL_RG8UI : GL_RG8;
        }
    } else if (num_channels == 3) {
        if (use_compression && !int_format && has_bptc) {
            internal_format = snorm ? GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT :
                    GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
        } else if (use_compression && !int_format && !snorm && has_s3tc) {
            internal_format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
        } else if (type == GL_FLOAT) {
            internal_format = GL_RGB32F;
        } else if (type == GL_INT) {
            // GL_RGB32_SNORM not available! Choose closest.
            internal_format = int_format ? GL_RGB32I : GL_RGB16_SNORM;
        } else if (type == GL_UNSIGNED_INT) {
            // GL_RGB32 not available! Choose closest.
            internal_format = int_format ? GL_RGB32UI : GL_RGB16;
        } else if (type == GL_SHORT) {
            internal_format = int_format ? GL_RGB16I : GL_RGB16_SNORM;
        } else if (type == GL_UNSIGNED_SHORT) {
            internal_format = int_format ? GL_RGB16UI : GL_RGB16;
        } else if (type == GL_BYTE) {
            internal_format = int_format ? GL_RGB8I : GL_RGB8_SNORM;
        } else {
            // just use GL_RGB8 for everything else
            internal_format = int_format ? GL_RGB8UI : GL_RGB8;
        }
    } else if (num_channels == 4) {
        if (use_compression && !int_format && !snorm &&
                (has_bptc || has_s3tc))
        {
            internal_format = has_bptc ? GL_COMPRESSED_RGBA_BPTC_UNORM :
                GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
        } else if (type == GL_FLOAT) {
            internal_format = GL_RGBA32F;
        } else if (type == GL_INT) {
            // GL_RGBA32_SNORM not available! Choose closest.
            internal_format = int_format ? GL_RGBA32I : GL_RGBA16_SNORM;
        } else if (type == GL_UNSIGNED_INT) {
            // GL_RGBA32 not available! Choose closest.
            internal_format = int_format ? GL_RGBA32UI : GL_RGBA16;
        } else if (type == GL_SHORT) {
            internal_format = int_format ? GL_RGBA16I : GL_RGBA16_SNORM;
        } else if (type == GL_UNSIGNED_SHORT) {
            internal_format = int_format ? GL_RGBA16UI : GL_RGBA16;
        } else if (type == GL_BYTE) {
            internal_format = int_format ? GL_RGBA8I : GL_RGBA8_SNORM;
        } else {
            // just use GL_RGBA8 for everything else
            internal_format = int_format ? GL_RGBA8UI : GL_RGBA8;
        }
    } else {
        // should not be reached
        abort();
    }

    return internal_format;
}
static std::size_t get_frame_size() {
	return get_sample_size() * get_num_channels();
}
Esempio n. 7
0
/*
 * This function initialises the PNGImage struct for us in future it may be
 * a good idea to make use of stdarg.h and add a ... argument that allow us
 * to specify optional arguments such as image height and width etc.
 */
bool new_png_image(PNGImage* img, IMGParams* params)
{
    // Check to see if we have been given any parameters if so use those
    // otherwise just create a blank image
    if (params != NULL)
    {
        img->width = params->width;
        img->height = params->height;
        img->color_type = params->color_type;
        img->bit_depth = 8; // We will only be able to create 8bit images for now

        int num_channels = get_num_channels(img);

        if(num_channels == -1)
        {
            fprintf(stderr, "[new_image]: Colour type not supported or invalid\n");
            return false;
        }

        img->num_channels = num_channels;

        // Now allocate the memory
        img->row_pointers = (png_bytep*) malloc(img->height * sizeof(png_bytep));

        if(!img->row_pointers)
        {
            fprintf(stderr, "[new_image]: ERROR: Unable to allocate memory for the image\n");
            return false;
        }

        unsigned int i = 0;
        unsigned int j = 0;
        for(i = 0; i < img->width ; i++)
        {
            img->row_pointers[i] = (png_byte*) malloc((img->width * img->num_channels) * sizeof(png_byte));

            if(!img->row_pointers[i])
            {
                fprintf(stderr, "[new_image]: ERROR: Unable to allocate memory for the image\n");

                for(j = 0; j < i; j++)
                {
                    free(img->row_pointers[i]);
                    img->row_pointers[i] = NULL;
                }

                return false;
            }
        }
    }
    else   
    {
        // I think we can just initialise everything to zero
        img->width = 0;
        img->height = 0;
        img->color_type = 0;
        img->num_channels = 0;
        img->bit_depth = 0;
        img->row_pointers = NULL;
    }
    
    img->number_of_passes = 0;

    // It's good practice to initialise pointers to NULL
    img->png_ptr = NULL;
    img->info_ptr = NULL;

    return true;
    
}
Esempio n. 8
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;
	}