Beispiel #1
0
	void Open(std::string filename)
	{
		stream_->Open(filename);
		audio_decoder_->Open(stream_->getHandle());
		video_decoder_->Open();
		audio_renderer_->Open();
		video_renderer_->Open();
	}
AudioDecoder * AudioDecoder::CreateDecoderForInputSource(InputSource *inputSource, CFStringRef mimeType, CFErrorRef *error)
{
	if(NULL == inputSource)
		return NULL;

	AudioDecoder *decoder = NULL;

	// Open the input source if it isn't already
	if(AutomaticallyOpenDecoders() && !inputSource->IsOpen() && !inputSource->Open(error))
		return NULL;

	// As a factory this class has knowledge of its subclasses
	// It would be possible (and perhaps preferable) to switch to a generic
	// plugin interface at a later date

#if 0
	// If the input is an instance of HTTPInputSource, use the MIME type from the server
	// This code is disabled because most HTTP servers don't send the correct MIME types
	HTTPInputSource *httpInputSource = dynamic_cast<HTTPInputSource *>(inputSource);
	bool releaseMIMEType = false;
	if(!mimeType && httpInputSource && httpInputSource->IsOpen()) {
		mimeType = httpInputSource->CopyContentMIMEType();
		if(mimeType)
			releaseMIMEType = true;
	}
#endif

	// The MIME type takes precedence over the file extension
	if(mimeType) {
#if BUILD_FOR_MAC_OSX
		if(FLACDecoder::HandlesMIMEType(mimeType)) {
			decoder = new FLACDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && WavPackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new WavPackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && MPEGDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MPEGDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && OggVorbisDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggVorbisDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && MusepackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MusepackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && MonkeysAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MonkeysAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && OggSpeexDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggSpeexDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && MODDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MODDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
		if(NULL == decoder && LibsndfileDecoder::HandlesMIMEType(mimeType)) {
			decoder = new LibsndfileDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}
#endif
		if(NULL == decoder && CoreAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new CoreAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = NULL;
				delete decoder, decoder = NULL;
			}
		}

#if 0
		if(releaseMIMEType)
			CFRelease(mimeType), mimeType = NULL;
#endif

		if(decoder)
			return decoder;
	}

	// If no MIME type was specified, use the extension-based resolvers

	CFURLRef inputURL = inputSource->GetURL();
	if(!inputURL)
		return NULL;

	CFStringRef pathExtension = CFURLCopyPathExtension(inputURL);
	if(!pathExtension) {
		if(error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);

			CFStringRef displayName = CFURLCopyLastPathComponent(inputURL);
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The type of the file “%@” could not be determined."), ""), 
															   displayName);

			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);

			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Unknown file type"), ""));

			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may be missing or may not match the file's type."), ""));

			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;

			*error = CFErrorCreate(kCFAllocatorDefault, 
								   InputSourceErrorDomain, 
								   InputSourceFileNotFoundError,
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;				
		}

		return NULL;
	}

	// TODO: Some extensions (.oga for example) support multiple audio codecs (Vorbis, FLAC, Speex)
	// and if openDecoder is false the wrong decoder type may be returned, since the file isn't analyzed
	// until Open() is called
	
#if BUILD_FOR_MAC_OSX
	if(FLACDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new FLACDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && WavPackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new WavPackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && MPEGDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MPEGDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && OggVorbisDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggVorbisDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && MusepackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MusepackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && MonkeysAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MonkeysAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && OggSpeexDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggSpeexDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && MODDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MODDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
	if(NULL == decoder && LibsndfileDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new LibsndfileDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}
#endif
	if(NULL == decoder && CoreAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new CoreAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = NULL;
			delete decoder, decoder = NULL;
		}
	}

	CFRelease(pathExtension), pathExtension = NULL;

	return decoder;
}
AudioDecoder * AudioDecoder::CreateDecoderForInputSource(InputSource *inputSource, CFStringRef mimeType, CFErrorRef *error)
{
	if(nullptr == inputSource)
		return nullptr;

	AudioDecoder *decoder = nullptr;

	// Open the input source if it isn't already
	if(AutomaticallyOpenDecoders() && !inputSource->IsOpen() && !inputSource->Open(error))
		return nullptr;

	// As a factory this class has knowledge of its subclasses
	// It would be possible (and perhaps preferable) to switch to a generic
	// plugin interface at a later date

#if 0
	// If the input is an instance of HTTPInputSource, use the MIME type from the server
	// This code is disabled because most HTTP servers don't send the correct MIME types
	HTTPInputSource *httpInputSource = dynamic_cast<HTTPInputSource *>(inputSource);
	bool releaseMIMEType = false;
	if(!mimeType && httpInputSource && httpInputSource->IsOpen()) {
		mimeType = httpInputSource->CopyContentMIMEType();
		if(mimeType)
			releaseMIMEType = true;
	}
#endif

	// The MIME type takes precedence over the file extension
	if(mimeType) {
		if(FLACDecoder::HandlesMIMEType(mimeType)) {
			decoder = new FLACDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && WavPackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new WavPackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MPEGDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MPEGDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && OggVorbisDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggVorbisDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && OggSpeexDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggSpeexDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
#if !TARGET_OS_IPHONE
		if(nullptr == decoder && MusepackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MusepackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MonkeysAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MonkeysAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MODDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MODDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && TrueAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new TrueAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && LibsndfileDecoder::HandlesMIMEType(mimeType)) {
			decoder = new LibsndfileDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
#endif
		if(nullptr == decoder && CoreAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new CoreAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}

#if 0
		if(releaseMIMEType)
			CFRelease(mimeType), mimeType = nullptr;
#endif

		if(decoder)
			return decoder;
	}

	// If no MIME type was specified, use the extension-based resolvers

	CFURLRef inputURL = inputSource->GetURL();
	if(!inputURL)
		return nullptr;

	// Determining the extension isn't as simple as using CFURLCopyPathExtension (wouldn't that be nice?),
	// because although the behavior on Lion works like one would expect, on Snow Leopard it returns
	// a number that I believe is part of the inode number, but is definitely NOT the extension
	CFStringRef pathExtension = nullptr;
#if !TARGET_OS_IPHONE
	CFURLRef filePathURL = CFURLCreateFilePathURL(kCFAllocatorDefault, inputURL, nullptr);
	if(filePathURL) {
		pathExtension = CFURLCopyPathExtension(filePathURL);
		CFRelease(filePathURL), filePathURL = nullptr;
	}
	else
#endif
		pathExtension = CFURLCopyPathExtension(inputURL);

	if(!pathExtension) {
		if(error) {
			CFStringRef description = CFCopyLocalizedString(CFSTR("The type of the file “%@” could not be determined."), "");
			CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Unknown file type"), "");
			CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may be missing or may not match the file's type."), "");
			
			*error = CreateErrorForURL(InputSourceErrorDomain, InputSourceFileNotFoundError, description, inputURL, failureReason, recoverySuggestion);
			
			CFRelease(description), description = nullptr;
			CFRelease(failureReason), failureReason = nullptr;
			CFRelease(recoverySuggestion), recoverySuggestion = nullptr;
		}

		return nullptr;
	}

	// TODO: Some extensions (.oga for example) support multiple audio codecs (Vorbis, FLAC, Speex)
	// and if openDecoder is false the wrong decoder type may be returned, since the file isn't analyzed
	// until Open() is called
	
	if(FLACDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new FLACDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && WavPackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new WavPackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MPEGDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MPEGDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && OggVorbisDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggVorbisDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && OggSpeexDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggSpeexDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
#if !TARGET_OS_IPHONE
	if(nullptr == decoder && MusepackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MusepackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MonkeysAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MonkeysAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MODDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MODDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && TrueAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new TrueAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && LibsndfileDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new LibsndfileDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
#endif
	if(nullptr == decoder && CoreAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new CoreAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}

	CFRelease(pathExtension), pathExtension = nullptr;

	return decoder;
}
void Psp2Audio::SE_Play(std::string const& file, int volume, int pitch) {
	// Opening file
	FILE* stream = FileFinder::fopenUTF8(file, "rb");
	if (!stream) {
		Output::Warning("Couldn't open sound file %s", file.c_str());
		return;
	}

	// Pick the next free SE slot.
	// Does not need synchronisation
	int idx = -1;
	for (int i = 0; i < AUDIO_CHANNELS; ++i) {
		if (sfx_sounds[i].isPlaying && sfx_sounds[i].isFinished) {
			idx = i;
			break;
		}
	}

	if (idx == -1) {
		fclose(stream);
		Output::Warning("SE: No free channels available (%s)", file.c_str());
		return;
	}

	DecodedSound& sfx = sfx_sounds[idx];

	sfx.decoder = AudioDecoder::Create(stream, file);
	if (sfx.decoder == nullptr){
		fclose(stream);
		Output::Warning("Unsupported sound format (%s)", file.c_str());
		return;
	}

	// Initializing internal audio decoder
	int audiotype;

	AudioDecoder* decoder = sfx.decoder.get();

	if (!decoder->Open(stream)) {
		Output::Warning("Error occured in audio decoder (%s)", audio_decoder->GetError().c_str());
		return;
	}

	decoder->SetLooping(false);
	AudioDecoder::Format int_format;
	int samplerate;
	decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
	decoder->GetFormat(samplerate, int_format, audiotype);
	if (samplerate != 48000) Output::Warning("Cannot resample sound file. Sound will be distorted.");

	// Check for file audiocodec
	sfx.isStereo = audiotype == 2;

	// Setting default streaming values
	sfx.cur_audiobuf = sfx.audiobuf;

	decoder->SetPitch(pitch);
	decoder->SetVolume(volume);

	// Wait and signal is required to prevent reordering
	sceKernelWaitSema(SFX_Mutex_ID, 1, NULL);
	sfx.isPlaying = false;
	sfx.isFinished = false;
	sceKernelSignalSema(SFX_Mutex_ID, 1);

	// Start one SE thread
	sceKernelSignalSema(SFX_Mutex, 1);
}