Exemple #1
0
SoundDecoder_Sample* SoundDecoder_NewSampleFromFile(const char* file_name,
                                      SoundDecoder_AudioInfo* desired_format,
                                      size_t buffer_size)
{
    const char* file_extension;
    ALmixer_RWops* rw_ops;
	SoundDecoder_Sample* new_sample;
	if(0 == s_isInitialized)
	{
		SoundDecoder_SetError(ERR_NOT_INITIALIZED);
		return NULL;
	}
	if(NULL == file_name)
	{
		SoundDecoder_SetError("No file specified");
		return NULL;
	}

	file_extension = strrchr(file_name, '.');
	if(NULL != file_extension)
	{
		file_extension++;
	}

	rw_ops = ALmixer_RWFromFile(file_name, "rb");

	new_sample = SoundDecoder_NewSample(rw_ops, file_extension, desired_format, buffer_size);
	return new_sample;
 }
Exemple #2
0
int SoundDecoder_Init()
{
	size_t total_number_of_decoders;
	size_t i;
	size_t current_pos = 0;	
	if(1 == s_isInitialized)
	{
		return 1;
	}
	if(NULL == s_errorPool)
	{
		s_errorPool = TError_CreateErrorPool();
	}
	if(NULL == s_errorPool)
	{
		return 0;
	}

	total_number_of_decoders = sizeof(s_linkedDecoders) / sizeof(s_linkedDecoders[0]);
	s_availableDecoders = (const SoundDecoder_DecoderInfo **)malloc((total_number_of_decoders) * sizeof(SoundDecoder_DecoderInfo*));
	if(NULL == s_availableDecoders)
	{
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return 0;
	}

	/* Allocate memory for linked list of sound samples. */
	s_listOfLoadedSamples = LinkedList_Create();
	if(NULL == s_listOfLoadedSamples)
	{
		free(s_availableDecoders);
		s_availableDecoders = NULL;
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return 0;
	}

	for(i = 0; s_linkedDecoders[i].funcs != NULL; i++)
	{
		s_linkedDecoders[i].available = s_linkedDecoders[i].funcs->init();
		if(s_linkedDecoders[i].available)
		{
			s_availableDecoders[current_pos] = &(s_linkedDecoders[i].funcs->info);
			current_pos++;
		}
	}

	s_availableDecoders[current_pos] = NULL;
	s_isInitialized = 1;
	return 1;
}
Exemple #3
0
int SoundDecoder_Seek(SoundDecoder_Sample* sound_sample, size_t ms)
{
    SoundDecoder_SampleInternal* internal_sample;
	int ret_val;

    BAIL_IF_MACRO(!s_isInitialized, ERR_NOT_INITIALIZED, 0);
	BAIL_IF_MACRO(NULL == sound_sample, ERR_NULL_SAMPLE, 0);
	
	BAIL_IF_MACRO(!(sound_sample->flags & SOUND_SAMPLEFLAG_CANSEEK), "Sound sample is not seekable", 0);

    internal_sample = (SoundDecoder_SampleInternal*)sound_sample->opaque;
	ret_val = internal_sample->funcs->seek(sound_sample, ms);
	if(0 == ret_val)
	{
        sound_sample->flags |= SOUND_SAMPLEFLAG_ERROR;		
		SoundDecoder_SetError("Seek failed");
		return 0;
	}
	/* reset flags */
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_ERROR;
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_EOF;

    return 1;
}
Exemple #4
0
void SoundDecoder_FreeSample(SoundDecoder_Sample* sound_sample)
{
	SoundDecoder_SampleInternal* sample_internal;
	LinkedListNode* the_node;

	/* Quit unloads all samples, so it is not possible to free a sample
	 * when not initialized.
	 */
	if(0 == s_isInitialized)
	{
		return;
	}

	if(sound_sample == NULL)
	{
		return;
	}

	/* SDL_sound keeps a linked list of all the loaded samples.
	 * We want to remove the current sample from that list.
	 */
	the_node = LinkedList_Find(s_listOfLoadedSamples, sound_sample, NULL);
	if(NULL == the_node)
	{
		SoundDecoder_SetError("SoundDecoder_FreeSample: Internal Error, sample does not exist in linked list.");
		return;
	}
	LinkedList_Remove(s_listOfLoadedSamples, the_node);

	sample_internal = (SoundDecoder_SampleInternal*)sound_sample->opaque;

	/* Ugh...SDL_sound has a lot of pointers. 
	 * I hope I didn't miss any dynamic memory.
	 */

	/* Call close on the decoder */
	sample_internal->funcs->close(sound_sample);

	if(NULL != sample_internal->rw)
	{
		sample_internal->rw->close(sample_internal->rw);
	}

	/* Ooops. The public buffer might be shared with the internal buffer.
	 * Make sure to not accidentally double delete.
	 */
	if((NULL != sample_internal->buffer)
		&& (sample_internal->buffer != sound_sample->buffer)
	)
	{
		free(sample_internal->buffer);
	}
	free(sample_internal);

	if(NULL != sound_sample->buffer)
	{
		free(sound_sample->buffer);
	}
	free(sound_sample);
}
Exemple #5
0
size_t SoundDecoder_DecodeAll(SoundDecoder_Sample* sound_sample)
{
    SoundDecoder_SampleInternal* internal_sample = NULL;
    void* data_buffer = NULL;
    size_t updated_buffer_size = 0;

    BAIL_IF_MACRO(!s_isInitialized, ERR_NOT_INITIALIZED, 0);
	BAIL_IF_MACRO(NULL == sound_sample, ERR_NULL_SAMPLE, 0);

	/* My original thought was to call SetBufferSize and resize to 
	 * the size needed to hold the entire decoded file utilizing total_time,
	 * but it appears SDL_sound simply loops on SoundDecoder_Decode.
	 * I suppose it is possible to partially decode or seek a file, and then
	 * call DecodeAll so you won't have the whole thing in which case
	 * my idea would waste memory.
	 */
    while( (0 == (sound_sample->flags & SOUND_SAMPLEFLAG_EOF) )
		&& (0 == (sound_sample->flags & SOUND_SAMPLEFLAG_ERROR))
	)
    {
        size_t bytes_decoded = SoundDecoder_Decode(sound_sample);
        void* realloced_ptr = realloc(data_buffer, updated_buffer_size + bytes_decoded);
        if(NULL == realloced_ptr)
        {
            sound_sample->flags |= SOUND_SAMPLEFLAG_ERROR;
            SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
			if(NULL != data_buffer)
			{
				free(data_buffer);
			}
			return bytes_decoded;
        }
		data_buffer = realloced_ptr;
		/* copy the chunk of decoded PCM to the end of our new data buffer */
		memcpy( ((char*)data_buffer) + updated_buffer_size, sound_sample->buffer, bytes_decoded );
		updated_buffer_size += bytes_decoded;
    }

    internal_sample = (SoundDecoder_SampleInternal*)sound_sample->opaque;
	if(internal_sample->buffer != sound_sample->buffer)
	{
		free(internal_sample->buffer);
	}
    free(sound_sample->buffer);

	sound_sample->buffer = data_buffer;
	sound_sample->buffer_size = updated_buffer_size;
	internal_sample->buffer = sound_sample->buffer;
	internal_sample->buffer_size = sound_sample->buffer_size;

    return sound_sample->buffer_size;
}
Exemple #6
0
int SoundDecoder_Init()
{
	size_t total_number_of_decoders;
	size_t i;
	size_t current_pos = 0;	
	if(1 == s_isInitialized)
	{
		return 1;
	}
	if(NULL == s_errorPool)
	{
		s_errorPool = TError_CreateErrorPool();
	}
	if(NULL == s_errorPool)
	{
		return 0;
	}
	s_errorPool = TError_CreateErrorPool();

	total_number_of_decoders = sizeof(s_linkedDecoders) / sizeof(s_linkedDecoders[0]);
	s_availableDecoders = (const SoundDecoder_DecoderInfo **)malloc((total_number_of_decoders) * sizeof(SoundDecoder_DecoderInfo*));
	if(NULL == s_availableDecoders)
	{
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return 0;
	}

	for(i = 0; s_linkedDecoders[i].funcs != NULL; i++)
	{
		s_linkedDecoders[i].available = s_linkedDecoders[i].funcs->init();
		if(s_linkedDecoders[i].available)
		{
			s_availableDecoders[current_pos] = &(s_linkedDecoders[i].funcs->info);
			current_pos++;
		}
	}

	s_availableDecoders[current_pos] = NULL;
	s_isInitialized = 1;
	return 1;
}
Exemple #7
0
int SoundDecoder_Rewind(SoundDecoder_Sample* sound_sample)
{
    SoundDecoder_SampleInternal* internal_sample;
	int ret_val;
	
    BAIL_IF_MACRO(!s_isInitialized, ERR_NOT_INITIALIZED, 0);
	BAIL_IF_MACRO(NULL == sound_sample, ERR_NULL_SAMPLE, 0);

    internal_sample = (SoundDecoder_SampleInternal*)sound_sample->opaque;
	ret_val = internal_sample->funcs->rewind(sound_sample);
    if(0 == ret_val)
    {
        sound_sample->flags |= SOUND_SAMPLEFLAG_ERROR;
		SoundDecoder_SetError("Rewind failed");		
        return 0;
    }
	/* reset flags */
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_ERROR;
    sound_sample->flags &= ~SOUND_SAMPLEFLAG_EOF;

    return 1;
}
Exemple #8
0
SoundDecoder_Sample* SoundDecoder_NewSample(ALmixer_RWops* rw_ops, const char* file_extension, SoundDecoder_AudioInfo* desired_format, size_t buffer_size)
{
    SoundDecoder_Sample* new_sample;
    SoundDecoder_SampleInternal* internal_sample;
    SoundElement* current_decoder;

	if(0 == s_isInitialized)
	{
		SoundDecoder_SetError(ERR_NOT_INITIALIZED);
		return NULL;
	}
	if(NULL == rw_ops)
	{
		SoundDecoder_SetError("No file specified");
		return NULL;
	}

	new_sample = (SoundDecoder_Sample*)calloc(1, sizeof(SoundDecoder_Sample));
	if(NULL == new_sample)
	{
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return NULL;
	}
	internal_sample = (SoundDecoder_SampleInternal*)calloc(1, sizeof(SoundDecoder_SampleInternal));
	if(NULL == internal_sample)
	{
		free(new_sample);
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return NULL;
	}
	new_sample->buffer = calloc(1, buffer_size);
	if(NULL == new_sample->buffer)
	{
		free(internal_sample);
		free(new_sample);
		SoundDecoder_SetError(ERR_OUT_OF_MEMORY);
		return NULL;
	}

	new_sample->buffer_size = buffer_size;

    if(NULL != desired_format)
	{
		memcpy(&new_sample->desired, desired_format, sizeof(SoundDecoder_AudioInfo));
	}

	internal_sample->rw = rw_ops;
	new_sample->opaque = internal_sample;
/*
	if (rw_ops->file_name != NULL) {
		SoundDecoderInternal_SetOptionalFileName(new_sample->opaque, rw_ops->file_name);
	}
*/
    if(NULL != file_extension)
    {
        for(current_decoder = &s_linkedDecoders[0]; current_decoder->funcs != NULL; current_decoder++)
        {
            if(current_decoder->available)
            {
                const char** decoder_file_extension = current_decoder->funcs->info.extensions;
                while(*decoder_file_extension)
                {
                    if(0 == (SoundDecoder_strcasecmp(*decoder_file_extension, file_extension)))
                    {
                        if(Internal_LoadSample(current_decoder->funcs, new_sample, file_extension))
						{
							return(new_sample);
						}
                        break;  /* go to the next decoder */ 
                    }
					decoder_file_extension++;
                }
            }
        }
    }

    /* no direct file_extensionension match? Try everything we've got... */
	for(current_decoder = &s_linkedDecoders[0]; current_decoder->funcs != NULL; current_decoder++)
	{
		if(current_decoder->available)
		{
			int already_tried_decoder = 0;
			const char** decoder_file_extension = current_decoder->funcs->info.extensions;

			/* skip decoders we already tried from the above loop */
			while(*decoder_file_extension)
			{
				if(SoundDecoder_strcasecmp(*decoder_file_extension, file_extension) == 0)
				{
					already_tried_decoder = 1;
					break;
				}
				decoder_file_extension++;
			}

			if(0 == already_tried_decoder)
			{
				if (Internal_LoadSample(current_decoder->funcs, new_sample, file_extension))
				{
					return new_sample;
				}
			}
		}
	}

	/* could not find a decoder */
	SoundDecoder_SetError(ERR_UNSUPPORTED_FORMAT);
	/* clean up the memory */
	free(new_sample->opaque);
	if(NULL != new_sample->buffer)
	{
		free(new_sample->buffer);
	}
	free(new_sample);
	
	rw_ops->close(rw_ops);
	return NULL;
}