Esempio n. 1
0
    virtual alure::SharedPtr<alure::Decoder> createDecoder(alure::UniquePtr<std::istream> &file)
    {
        static const std::array<DUH*(*)(DUMBFILE*),3> init_funcs{{
            dumb_read_it, dumb_read_xm, dumb_read_s3m
        }};

        auto dfs = alure::MakeUnique<DUMBFILE_SYSTEM>();
        dfs->open = nullptr;
        dfs->skip = cb_skip;
        dfs->getc = cb_read_char;
        dfs->getnc = cb_read;
        dfs->close = nullptr;
        dfs->seek = cb_seek;
        dfs->get_size = cb_get_size;

        DUMBFILE *dfile = dumbfile_open_ex(file.get(), dfs.get());
        if(!dfile) return nullptr;

        ALuint freq = alure::Context::GetCurrent()->getDevice()->getFrequency();
        DUH_SIGRENDERER *renderer;
        DUH *duh;

        for(auto init : init_funcs)
        {
            if((duh=init(dfile)) != nullptr)
            {
                if((renderer=duh_start_sigrenderer(duh, 0, 2, 0)) != nullptr)
                    return alure::MakeShared<DumbDecoder>(
                        std::move(file), std::move(dfs), dfile, duh, renderer, freq
                    );

                unload_duh(duh);
                duh = nullptr;
            }

            dumbfile_seek(dfile, 0, SEEK_SET);
        }

        if((duh=dumb_read_mod(dfile, 1)) != nullptr)
        {
            if((renderer=duh_start_sigrenderer(duh, 0, 2, 0)) != nullptr)
                return alure::MakeShared<DumbDecoder>(
                    std::move(file), std::move(dfs), dfile, duh, renderer, freq
                );

            unload_duh(duh);
            duh = nullptr;
        }

        dumbfile_close(dfile);
        return nullptr;
    }
Esempio n. 2
0
/* load_duh(): loads a .duh file, returning a pointer to a DUH struct.
 * When you have finished with it, you must pass the pointer to unload_duh()
 * so that the memory can be freed.
 */
DUH *load_duh(const char *filename) {
    DUH *duh;
    DUMBFILE *f = dumbfile_open(filename);

    if (!f)
        return NULL;

    duh = read_duh(f);

    dumbfile_close(f);

    return duh;
}
Esempio n. 3
0
/* dumb_load_it_quick(): loads an IT file into a DUH struct, returning a
 * pointer to the DUH struct. When you have finished with it, you must pass
 * the pointer to unload_duh() so that the memory can be freed.
 */
DUH *dumb_load_it_quick(const char *filename) {
    DUH *duh;
    DUMBFILE *f = dumbfile_open(filename);

    if (!f)
        return NULL;

    duh = dumb_read_it_quick(f);

    dumbfile_close(f);

    return duh;
}
Esempio n. 4
0
/* dumb_load_psm_quick(): loads a PSM file into a DUH struct, returning a
 * pointer to the DUH struct. When you have finished with it, you must
 * pass the pointer to unload_duh() so that the memory can be freed.
 */
DUH *dumb_load_psm_quick(const char *filename, int subsong)
{
	DUH *duh;
	DUMBFILE *f = dumbfile_open(filename);

	if (!f)
		return NULL;

	duh = dumb_read_psm_quick(f, subsong);

	dumbfile_close(f);

	return duh;
}
Esempio n. 5
0
/* dumb_load_mod_quick(): loads a MOD file into a DUH struct, returning a
 * pointer to the DUH struct. When you have finished with it, you must
 * pass the pointer to unload_duh() so that the memory can be freed.
 */
DUH *DUMBEXPORT dumb_load_mod_quick(const char *filename, int restrict)
{
	DUH *duh;
	DUMBFILE *f = dumbfile_open(filename);

	if (!f)
		return NULL;

	duh = dumb_read_mod_quick(f, restrict);

	dumbfile_close(f);

	return duh;
}
Esempio n. 6
0
static void *dat_read_xm_quick(PACKFILE *f, long size)
{
	DUMBFILE *df;
	DUH *duh;

	(void)size;

	df = dumbfile_open_packfile(f);

	if (!df)
		return NULL;

	duh = dumb_read_xm_quick(df);

	dumbfile_close(df);

	return duh;
}
bool MODDecoder::Close(CFErrorRef */*error*/)
{
	if(!IsOpen()) {
		log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioDecoder.MOD");
		LOG4CXX_WARN(logger, "Close() called on an AudioDecoder that hasn't been opened");
		return true;
	}

	if(dsr)
		duh_end_sigrenderer(dsr), dsr = NULL;
	if(duh)
		unload_duh(duh), duh = NULL;
	if(df)
		dumbfile_close(df), df = NULL;

	mIsOpen = false;
	return true;
}
Esempio n. 8
0
void* Init(const char* strFile, unsigned int filecache, int* channels,
           int* samplerate, int* bitspersample, int64_t* totaltime,
           int* bitrate, AEDataFormat* format, const AEChannel** channelinfo)
{
  void* file = XBMC->OpenFile(strFile,0);
  if (!file)
    return NULL;

  dumbfile_mem_status memdata;
  memdata.size = XBMC->GetFileLength(file);
  memdata.ptr = new uint8_t[memdata.size];
  XBMC->ReadFile(file, const_cast<uint8_t*>(memdata.ptr), memdata.size);
  XBMC->CloseFile(file);

  DUMBFILE* f = dumbfile_open_ex(&memdata, &mem_dfs);
  if (!f)
    return NULL;

  DumbContext* result = new DumbContext;

  if (memdata.size >= 4 &&
      memdata.ptr[0] == 'I' && memdata.ptr[1] == 'M' &&
      memdata.ptr[2] == 'P' && memdata.ptr[3] == 'M')
  {
    result->module = dumb_read_it(f);
  }
  else if (memdata.size >= 17 &&
           memcmp(memdata.ptr, "Extended Module: ", 17) == 0)
  {
    result->module = dumb_read_xm(f);
  }
  else if (memdata.size >= 0x30 &&
           memdata.ptr[0x2C] == 'S' && memdata.ptr[0x2D] == 'C' &&
           memdata.ptr[0x2E] == 'R' && memdata.ptr[0x2F] == 'M')
  {
    result->module = dumb_read_s3m(f);
  }
  else
  {
    dumbfile_close(f);
    delete result;
    return NULL;
  }

  dumbfile_close(f);

  result->sr = duh_start_sigrenderer(result->module, 0, 2, 0);

  if (!result->sr)
  {
    delete result;
    return NULL;
  }

  *channels = 2;
  *samplerate = 48000;
  *bitspersample = 16;
  *totaltime = duh_get_length(result->module)/65536*1000;
  *format = AE_FMT_S16NE;
   static enum AEChannel map[3] = { AE_CH_FL, AE_CH_FR , AE_CH_NULL};

  *channelinfo = map;
  *bitrate = duh_sigrenderer_get_n_channels(result->sr);

  return result;
}
bool MODDecoder::Open(CFErrorRef *error)
{
	if(IsOpen()) {
		log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioDecoder.MOD");
		LOG4CXX_WARN(logger, "Open() called on an AudioDecoder that is already open");		
		return true;
	}

	// Ensure the input source is open
	if(!mInputSource->IsOpen() && !mInputSource->Open(error))
		return false;

	dfs.open = NULL;
	dfs.skip = skip_callback;
	dfs.getc = getc_callback;
	dfs.getnc = getnc_callback;
	dfs.close = close_callback;

	df = dumbfile_open_ex(this, &dfs);
	if(NULL == df) {
		return false;
	}

	CFStringRef fileSystemPath = CFURLCopyFileSystemPath(GetURL(), kCFURLPOSIXPathStyle);
	CFStringRef extension = NULL;

	CFRange range;
	if(CFStringFindWithOptionsAndLocale(fileSystemPath, CFSTR("."), CFRangeMake(0, CFStringGetLength(fileSystemPath)), kCFCompareBackwards, CFLocaleGetSystem(), &range)) {
		extension = CFStringCreateWithSubstring(kCFAllocatorDefault, fileSystemPath, CFRangeMake(range.location + 1, CFStringGetLength(fileSystemPath) - range.location - 1));
	}

	CFRelease(fileSystemPath), fileSystemPath = NULL;

	if(NULL == extension) {
		return false;
	}
	
	// Attempt to create the appropriate decoder based on the file's extension
	if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("it"), kCFCompareCaseInsensitive))
		duh = dumb_read_it(df);
	else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("xm"), kCFCompareCaseInsensitive))
		duh = dumb_read_xm(df);
	else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("s3m"), kCFCompareCaseInsensitive))
		duh = dumb_read_s3m(df);
	else if(kCFCompareEqualTo == CFStringCompare(extension, CFSTR("mod"), kCFCompareCaseInsensitive))
		duh = dumb_read_mod(df);
	
	CFRelease(extension), extension = NULL;

	if(NULL == duh) {
		if(error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			CFStringRef displayName = CreateDisplayNameForURL(mInputSource->GetURL());
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MOD file."), ""), 
															   displayName);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Not a MOD file"), ""));
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
			
			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioDecoderErrorDomain, 
								   AudioDecoderInputOutputError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;
		}
		
		if(df)
			dumbfile_close(df), df = NULL;

		return false;
	}

	mTotalFrames = duh_get_length(duh);

	dsr = duh_start_sigrenderer(duh, 0, 2, 0);
	if(NULL == dsr) {
		if(error) {
			CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 
																			   32,
																			   &kCFTypeDictionaryKeyCallBacks,
																			   &kCFTypeDictionaryValueCallBacks);
			
			CFStringRef displayName = CreateDisplayNameForURL(mInputSource->GetURL());
			CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, 
															   NULL, 
															   CFCopyLocalizedString(CFSTR("The file “%@” is not a valid MOD file."), ""), 
															   displayName);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedDescriptionKey, 
								 errorString);
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedFailureReasonKey, 
								 CFCopyLocalizedString(CFSTR("Not a MOD file"), ""));
			
			CFDictionarySetValue(errorDictionary, 
								 kCFErrorLocalizedRecoverySuggestionKey, 
								 CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""));
			
			CFRelease(errorString), errorString = NULL;
			CFRelease(displayName), displayName = NULL;
			
			*error = CFErrorCreate(kCFAllocatorDefault, 
								   AudioDecoderErrorDomain, 
								   AudioDecoderInputOutputError, 
								   errorDictionary);
			
			CFRelease(errorDictionary), errorDictionary = NULL;
		}

		if(df)
			dumbfile_close(df), df = NULL;
		if(duh)
			unload_duh(duh), duh = NULL;

		return false;
	}
	
	// Generate interleaved 2 channel 44.1 16-bit output
	mFormat.mFormatID			= kAudioFormatLinearPCM;
	mFormat.mFormatFlags		= kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
	
	mFormat.mSampleRate			= DUMB_SAMPLE_RATE;
	mFormat.mChannelsPerFrame	= DUMB_CHANNELS;
	mFormat.mBitsPerChannel		= DUMB_BIT_DEPTH;
	
	mFormat.mBytesPerPacket		= (mFormat.mBitsPerChannel / 8) * mFormat.mChannelsPerFrame;
	mFormat.mFramesPerPacket	= 1;
	mFormat.mBytesPerFrame		= mFormat.mBytesPerPacket * mFormat.mFramesPerPacket;
	
	mFormat.mReserved			= 0;
	
	// Set up the source format
	mSourceFormat.mFormatID				= 'MOD ';
	
	mSourceFormat.mSampleRate			= DUMB_SAMPLE_RATE;
	mSourceFormat.mChannelsPerFrame		= DUMB_CHANNELS;
	
	// Setup the channel layout
	mChannelLayout = CreateChannelLayoutWithTag(kAudioChannelLayoutTag_Stereo);

	mIsOpen = true;
	return true;
}