Example #1
0
void MP4RtpHintTrack::ReadHint(
	MP4SampleId hintSampleId,
	u_int16_t* pNumPackets)
{
	if (m_pRefTrack == NULL) {
		InitRefTrack();
		InitRtpStart();
	}

	// dispose of any old hint
	delete m_pReadHint;
	m_pReadHint = NULL;
	delete m_pReadHintSample;
	m_pReadHintSample = NULL;
	m_readHintSampleSize = 0;

	// read the desired hint sample into memory
	ReadSample(
		hintSampleId, 
		&m_pReadHintSample, 
		&m_readHintSampleSize,
		&m_readHintTimestamp);

	m_pFile->EnableMemoryBuffer(m_pReadHintSample, m_readHintSampleSize);

	m_pReadHint = new MP4RtpHint(this);
	m_pReadHint->Read(m_pFile);

	m_pFile->DisableMemoryBuffer();

	if (pNumPackets) {
		*pNumPackets = GetHintNumberOfPackets();
	}
}
Example #2
0
 AP4_Result Start()
 {
   if (m_started)
     return AP4_SUCCESS;
   m_started = true;
   return ReadSample();
 }
Example #3
0
void MP4Track::ReadSampleFragment(
	MP4SampleId sampleId,
	u_int32_t sampleOffset,
	u_int16_t sampleLength,
	u_int8_t* pDest)
{
	if (sampleId == MP4_INVALID_SAMPLE_ID) {
		throw new MP4Error("invalid sample id", 
			"MP4Track::ReadSampleFragment");
	}

	if (sampleId != m_cachedReadSampleId) {
		MP4Free(m_pCachedReadSample);
		m_pCachedReadSample = NULL;
		m_cachedReadSampleSize = 0;
		m_cachedReadSampleId = MP4_INVALID_SAMPLE_ID;

		ReadSample(
			sampleId,
			&m_pCachedReadSample,
			&m_cachedReadSampleSize);

		m_cachedReadSampleId = sampleId;
	}

	if (sampleOffset + sampleLength > m_cachedReadSampleSize) {
		throw new MP4Error("offset and/or length are too large", 
			"MP4Track::ReadSampleFragment");
	}

	memcpy(pDest, &m_pCachedReadSample[sampleOffset], sampleLength);
}
float Pulse::GetPTT(){
  ClearArrays();
  ReadSample();
  GetRisingEdge(DC_Value, RisingEdges);
  GetRisingEdge(DC_Value2, RisingEdges2);
  
  return ComputePTT();
}
float Pulse::GetPulse(){
  Serial.println("GetPulse() in .cpp");
  ClearArrays();
  ReadSample();
  GetRisingEdge(DC_Value, RisingEdges);
  
  return ComputeHR(RisingEdges);;
}
Example #6
0
 float *fill(float *first, float *end)
 {
     int val;
     for(;first != end && remain_ && ReadSample(val); ++first, --remain_)
     {
         *first = (float)val;
     }
     return first;
 }
Example #7
0
 bool TimeSeek(double pts, bool preceeding)
 {
   AP4_Ordinal sampleIndex;
   if (AP4_SUCCEEDED(SeekSample(m_Track->GetId(), static_cast<AP4_UI64>(pts*(double)m_Track->GetMediaTimeScale()), sampleIndex, preceeding)))
   {
     if (m_Decrypter)
       m_Decrypter->SetSampleIndex(sampleIndex);
     m_started = true;
     return AP4_SUCCEEDED(ReadSample());
   }
   return false;
 };
bool CWaveReader::NextSample()
{
	_currentSample = ReadSample();



	if (_currentSample!=EOF_SAMPLE)
	{
		_currentSampleNumber++;
		return true;
	}
	else
		return false;
}
BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength)
//-----------------------------------------------------------
{
	AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream;
	DWORD dwMemPos;
	
	if ((!lpStream) || (dwMemLength < 2048)) return FALSE;
	if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
	{
		UINT numorders, numpats, numsamples;

		dwMemPos = 32;
		numpats = lpStream[dwMemPos+3];
		numorders = lpStream[dwMemPos+4];
		numsamples = 64;
		dwMemPos += 6;
		if ((!numpats) || (numpats > MAX_PATTERNS) || (!numorders)
		 || (numpats*64*32 + 294 + 37*64 >= dwMemLength)) return FALSE;
		m_nType = MOD_TYPE_AMF0;
		m_nChannels = 8;
		m_nInstruments = 0;
		m_nSamples = 31;
		m_nDefaultTempo = 125;
		m_nDefaultSpeed = 6;
		for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
		{
			Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : 0xFF;
		}
		dwMemPos = 294; // ???
		for (UINT iSmp=0; iSmp<numsamples; iSmp++)
		{
			MODINSTRUMENT *psmp = &Ins[iSmp+1];
			memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22);
			psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]);
			psmp->nVolume = lpStream[dwMemPos+23];
			psmp->nGlobalVol = 64;
			if (psmp->nVolume > 0x40) psmp->nVolume = 0x40;
			psmp->nVolume <<= 2;
			psmp->nLength = *((LPDWORD)(lpStream+dwMemPos+25));
			psmp->nLoopStart = *((LPDWORD)(lpStream+dwMemPos+29));
			psmp->nLoopEnd = psmp->nLoopStart + *((LPDWORD)(lpStream+dwMemPos+33));
			if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength))
			{
				psmp->uFlags = CHN_LOOP;
			} else
			{
				psmp->nLoopStart = psmp->nLoopEnd = 0;
			}
			if ((psmp->nLength) && (iSmp>31)) m_nSamples = iSmp+1;
			dwMemPos += 37;
		}
		for (UINT iPat=0; iPat<numpats; iPat++)
		{
			MODCOMMAND *p = AllocatePattern(64, m_nChannels);
			if (!p) break;
			Patterns[iPat] = p;
			PatternSize[iPat] = 64;
			const UCHAR *pin = lpStream + dwMemPos;
			for (UINT i=0; i<8*64; i++)
			{
				p->note = 0;

				if (pin[0])
				{
					p->note = pin[0] + 13;
				}
				p->instr = pin[1];
				p->command = pin[2];
				p->param = pin[3];
				if (p->command > 0x0F)
				{
				#ifdef AMFLOG
					Log("0x%02X.0x%02X ?", p->command, p->param);
				#endif
					p->command = 0;
				}
				ConvertModCommand(p);
				pin += 4;
				p++;
			}
			dwMemPos += 64*32;
		}
		// Read samples
		for (UINT iData=0; iData<m_nSamples; iData++)
		{
			MODINSTRUMENT *psmp = &Ins[iData+1];
			if (psmp->nLength)
			{
				dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength);
			}
		}
		return TRUE;
	}
	////////////////////////////
	// DSM/AMF
	USHORT *ptracks[MAX_PATTERNS];
	DWORD sampleseekpos[MAX_SAMPLES];

	if ((pfh->szAMF[0] != 'A') || (pfh->szAMF[1] != 'M') || (pfh->szAMF[2] != 'F')
	 || (pfh->version < 10) || (pfh->version > 14) || (!pfh->numtracks)
	 || (!pfh->numorders) || (pfh->numorders > MAX_PATTERNS)
	 || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES)
	 || (pfh->numchannels < 4) || (pfh->numchannels > 32))
		return FALSE;
	memcpy(m_szNames[0], pfh->title, 32);
	dwMemPos = sizeof(AMFFILEHEADER);
	m_nType = MOD_TYPE_AMF;
	m_nChannels = pfh->numchannels;
	m_nSamples = pfh->numsamples;
	m_nInstruments = 0;
	// Setup Channel Pan Positions
	if (pfh->version >= 11)
	{
		signed char *panpos = (signed char *)(lpStream + dwMemPos);
		UINT nchannels = (pfh->version >= 13) ? 32 : 16;
		for (UINT i=0; i<nchannels; i++)
		{
			int pan = (panpos[i] + 64) * 2;
			if (pan < 0) pan = 0;
			if (pan > 256) { pan = 128; ChnSettings[i].dwFlags |= CHN_SURROUND; }
			ChnSettings[i].nPan = pan;
		}
		dwMemPos += nchannels;
	} else
	{
		for (UINT i=0; i<16; i++)
		{
			ChnSettings[i].nPan = (lpStream[dwMemPos+i] & 1) ? 0x30 : 0xD0;
		}
		dwMemPos += 16;
	}
	// Get Tempo/Speed
	m_nDefaultTempo = 125;
	m_nDefaultSpeed = 6;
	if (pfh->version >= 13)
	{
		if (lpStream[dwMemPos] >= 32) m_nDefaultTempo = lpStream[dwMemPos];
		if (lpStream[dwMemPos+1] <= 32) m_nDefaultSpeed = lpStream[dwMemPos+1];
		dwMemPos += 2;
	}
	// Setup sequence list
	for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
	{
		Order[iOrd] = 0xFF;
		if (iOrd < pfh->numorders)
		{
			Order[iOrd] = iOrd;
			PatternSize[iOrd] = 64;
			if (pfh->version >= 14)
			{
				PatternSize[iOrd] = *(USHORT *)(lpStream+dwMemPos);
				dwMemPos += 2;
			}
			ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
			dwMemPos += m_nChannels * sizeof(USHORT);
		}
	}
	if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return TRUE;
	// Read Samples
	UINT maxsampleseekpos = 0;
	for (UINT iIns=0; iIns<m_nSamples; iIns++)
	{
		MODINSTRUMENT *pins = &Ins[iIns+1];
		AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos);

		dwMemPos += sizeof(AMFSAMPLE);
		memcpy(m_szNames[iIns+1], psh->samplename, 32);
		memcpy(pins->name, psh->filename, 13);
		pins->nLength = psh->length;
		pins->nC4Speed = psh->c2spd;
		pins->nGlobalVol = 64;
		pins->nVolume = psh->volume * 4;
		if (pfh->version >= 11)
		{
			pins->nLoopStart = *(DWORD *)(lpStream+dwMemPos);
			pins->nLoopEnd = *(DWORD *)(lpStream+dwMemPos+4);
			dwMemPos += 8;
		} else
		{
			pins->nLoopStart = *(WORD *)(lpStream+dwMemPos);
			pins->nLoopEnd = pins->nLength;
			dwMemPos += 2;
		}
		sampleseekpos[iIns] = 0;
		if ((psh->type) && (psh->offset < dwMemLength-1))
		{
			sampleseekpos[iIns] = psh->offset;
			if (psh->offset > maxsampleseekpos) maxsampleseekpos = psh->offset;
			if ((pins->nLoopEnd > pins->nLoopStart + 2)
			 && (pins->nLoopEnd <= pins->nLength)) pins->uFlags |= CHN_LOOP;
		}
	}
	// Read Track Mapping Table
	USHORT *pTrackMap = (USHORT *)(lpStream+dwMemPos);
	UINT realtrackcnt = 0;
	dwMemPos += pfh->numtracks * sizeof(USHORT);
	for (UINT iTrkMap=0; iTrkMap<pfh->numtracks; iTrkMap++)
	{
		if (realtrackcnt < pTrackMap[iTrkMap]) realtrackcnt = pTrackMap[iTrkMap];
	}
	// Store tracks positions
	BYTE **pTrackData = new BYTE *[realtrackcnt];
	memset(pTrackData, 0, sizeof(pTrackData));
	for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength)
	{
		UINT nTrkSize = *(USHORT *)(lpStream+dwMemPos);
		nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
		if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength)
		{
			pTrackData[iTrack] = (BYTE *)(lpStream + dwMemPos);
		}
		dwMemPos += nTrkSize * 3 + 3;
	}
	// Create the patterns from the list of tracks
	for (UINT iPat=0; iPat<pfh->numorders; iPat++)
	{
		MODCOMMAND *p = AllocatePattern(PatternSize[iPat], m_nChannels);
		if (!p) break;
		Patterns[iPat] = p;
		for (UINT iChn=0; iChn<m_nChannels; iChn++)
		{
			UINT nTrack = ptracks[iPat][iChn];
			if ((nTrack) && (nTrack <= pfh->numtracks))
			{
				UINT realtrk = pTrackMap[nTrack-1];
				if (realtrk)
				{
					realtrk--;
					if ((realtrk < realtrackcnt) && (pTrackData[realtrk]))
					{
						AMF_Unpack(p+iChn, pTrackData[realtrk], PatternSize[iPat], m_nChannels);
					}
				}
			}
		}
	}
	delete pTrackData;
	// Read Sample Data
	for (UINT iSeek=1; iSeek<=maxsampleseekpos; iSeek++)
	{
		if (dwMemPos >= dwMemLength) break;
		for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (iSeek == sampleseekpos[iSmp])
		{
			MODINSTRUMENT *pins = &Ins[iSmp+1];
			dwMemPos += ReadSample(pins, RS_PCM8U, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
			break;
		}
	}
	return TRUE;
}
Example #10
0
BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
//-----------------------------------------------------------
{
	PSMCHUNK *pfh = (PSMCHUNK *)lpStream;
	DWORD dwMemPos, dwSongPos;
//	DWORD smpnames[MAX_SAMPLES];
	DWORD patptrs[MAX_PATTERNS];
	BYTE samplemap[MAX_SAMPLES];
	UINT nPatterns;

	// Swap chunk
	swap_PSMCHUNK(pfh);

	// Chunk0: "PSM ",filesize,"FILE"
	if (dwMemLength < 256) return FALSE;
	if (pfh->id == PSM_ID_OLD)
	{
	#ifdef PSM_LOG
		Log("Old PSM format not supported\n");
	#endif
		return FALSE;
	}
	if ((pfh->id != PSM_ID_NEW) || (pfh->len+12 > dwMemLength) || (pfh->listid != IFFID_FILE)) return FALSE;
	m_nType = MOD_TYPE_PSM;
	m_nChannels = 16;
	m_nSamples = 0;
	nPatterns = 0;
	dwMemPos = 12;
	dwSongPos = 0;
	for (UINT iChPan=0; iChPan<16; iChPan++)
	{
		UINT pan = (((iChPan & 3) == 1) || ((iChPan&3)==2)) ? 0xC0 : 0x40;
		ChnSettings[iChPan].nPan = pan;
	}
	while (dwMemPos+8 < dwMemLength)
	{
		PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
		swap_PSMCHUNK(pchunk);
		if ((pchunk->len >= dwMemLength - 8) || (dwMemPos + pchunk->len + 8 > dwMemLength)) break;
		dwMemPos += 8;
		PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
		ULONG len = pchunk->len;
		if (len) switch(pchunk->id)
		{
		// "TITL": Song title
		case IFFID_TITL:
			if (!pdata[0]) { pdata++; len--; }
			memcpy(m_szNames[0], pdata, (len>31) ? 31 : len);
			m_szNames[0][31] = 0;
			break;
		// "PBOD": Pattern
		case IFFID_PBOD:
			if ((len >= 12) && (nPatterns < MAX_PATTERNS))
			{
				patptrs[nPatterns++] = dwMemPos-8;
			}
			break;
		// "SONG": Song description
		case IFFID_SONG:
			if ((len >= sizeof(PSMSONGHDR)+8) && (!dwSongPos))
			{
				dwSongPos = dwMemPos - 8;
			}
			break;
		// "DSMP": Sample Data
		case IFFID_DSMP:
			if ((len >= sizeof(PSMSAMPLE)) && (m_nSamples+1 < MAX_SAMPLES))
			{
				m_nSamples++;
				MODINSTRUMENT *pins = &Ins[m_nSamples];
				PSMSAMPLE *psmp = (PSMSAMPLE *)pdata;
				swap_PSMSAMPLE(psmp);
//				smpnames[m_nSamples] = psmp->smpid;
				memcpy(m_szNames[m_nSamples], psmp->samplename, 31);
				m_szNames[m_nSamples][31] = 0;
				samplemap[m_nSamples-1] = (BYTE)m_nSamples;
				// Init sample
				pins->nGlobalVol = 0x40;
				pins->nC4Speed = psmp->samplerate;
				pins->nLength = psmp->length;
				pins->nLoopStart = psmp->loopstart;
				pins->nLoopEnd = psmp->loopend;
				pins->nPan = 128;
				pins->nVolume = (psmp->defvol+1) * 2;
				pins->uFlags = (psmp->flags & 0x80) ? CHN_LOOP : 0;
				if (pins->nLoopStart > 0) pins->nLoopStart--;
				// Point to sample data
				pdata += 0x60;
				len -= 0x60;
				// Load sample data
				if ((pins->nLength > 3) && (len > 3))
				{
					ReadSample(pins, RS_PCM8D, (LPCSTR)pdata, len);
				} else
				{
					pins->nLength = 0;
				}
			}
			break;
	#if 0
		default:
			{
				CHAR s[8], s2[64];
				*(DWORD *)s = pchunk->id;
				s[4] = 0;
				wsprintf(s2, "%s: %4d bytes @ %4d\n", s, pchunk->len, dwMemPos);
				OutputDebugString(s2);
			}
	#endif
		}
		dwMemPos += pchunk->len;
	}
	// Step #1: convert song structure
	PSMSONGHDR *pSong = (PSMSONGHDR *)(lpStream+dwSongPos+8);
	if ((!dwSongPos) || (pSong->channels < 2) || (pSong->channels > 32)) return TRUE;
	m_nChannels = pSong->channels;
	// Valid song header -> convert attached chunks
	{
		DWORD dwSongEnd = dwSongPos + 8 + *(DWORD *)(lpStream+dwSongPos+4);
		dwMemPos = dwSongPos + 8 + 11; // sizeof(PSMCHUNK)+sizeof(PSMSONGHDR)
		while (dwMemPos + 8 < dwSongEnd)
		{
			PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
			swap_PSMCHUNK(pchunk);
			dwMemPos += 8;
			if ((pchunk->len > dwSongEnd) || (dwMemPos + pchunk->len > dwSongEnd)) break;
			PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
			ULONG len = pchunk->len;
			switch(pchunk->id)
			{
			case IFFID_OPLH:
				if (len >= 0x20)
				{
					UINT pos = len - 3;
					while (pos > 5)
					{
						BOOL bFound = FALSE;
						pos -= 5;
						DWORD dwName = *(DWORD *)(pdata+pos);
						for (UINT i=0; i<nPatterns; i++)
						{
							DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
							if (dwName == dwPatName)
							{
								bFound = TRUE;
								break;
							}
						}
						if ((!bFound) && (pdata[pos+1] > 0) && (pdata[pos+1] <= 0x10)
						 && (pdata[pos+3] > 0x40) && (pdata[pos+3] < 0xC0))
						{
							m_nDefaultSpeed = pdata[pos+1];
							m_nDefaultTempo = pdata[pos+3];
							break;
						}
					}
					UINT iOrd = 0;
					while ((pos+5<len) && (iOrd < MAX_ORDERS))
					{
						DWORD dwName = *(DWORD *)(pdata+pos);
						for (UINT i=0; i<nPatterns; i++)
						{
							DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
							if (dwName == dwPatName)
							{
								Order[iOrd++] = i;
								break;
							}
						}
						pos += 5;
					}
				}
				break;
			}
			dwMemPos += pchunk->len;
		}
	}

	// Step #2: convert patterns
	for (UINT nPat=0; nPat<nPatterns; nPat++)
	{
		PSMPATTERN *pPsmPat = (PSMPATTERN *)(lpStream+patptrs[nPat]+8);
		swap_PSMPATTERN(pPsmPat);
		ULONG len = *(DWORD *)(lpStream+patptrs[nPat]+4) - 12;
		UINT nRows = pPsmPat->rows;
		if (len > pPsmPat->size) len = pPsmPat->size;
		if ((nRows < 64) || (nRows > 256)) nRows = 64;
		PatternSize[nPat] = nRows;
		if ((Patterns[nPat] = AllocatePattern(nRows, m_nChannels)) == NULL) break;
		MODCOMMAND *m = Patterns[nPat];
		BYTE *p = pPsmPat->data;
		UINT pos = 0;
		UINT row = 0;
		UINT oldch = 0;
//		BOOL bNewRow = FALSE;
	#ifdef PSM_LOG
		Log("Pattern %d at offset 0x%04X\n", nPat, (DWORD)(p - (BYTE *)lpStream));
	#endif
		while ((row < nRows) && (pos+1 < len))
		{
			UINT flags = p[pos++];
			UINT ch = p[pos++];

		#ifdef PSM_LOG
			//Log("flags+ch: %02X.%02X\n", flags, ch);
		#endif
			if (((flags & 0xf0) == 0x10) && (ch <= oldch) /*&& (!bNewRow)*/)
			{
				if ((pos+1<len) && (!(p[pos] & 0x0f)) && (p[pos+1] < m_nChannels))
				{
				#ifdef PSM_LOG
					//if (!nPat) Log("Continuing on new row\n");
				#endif
					row++;
					m += m_nChannels;
					oldch = ch;
					continue;
				}
			}
			if ((pos >= len) || (row >= nRows)) break;
			if (!(flags & 0xf0))
			{
			#ifdef PSM_LOG
				//if (!nPat) Log("EOR(%d): %02X.%02X\n", row, p[pos], p[pos+1]);
			#endif
				row++;
				m += m_nChannels;
//				bNewRow = TRUE;
				oldch = ch;
				continue;
			}
//			bNewRow = FALSE;
			if (ch >= m_nChannels)
			{
			#ifdef PSM_LOG
				if (!nPat) Log("Invalid channel row=%d (0x%02X.0x%02X)\n", row, flags, ch);
			#endif
				ch = 0;
			}
			// Note + Instr
			if ((flags & 0x40) && (pos+1 < len))
			{
				UINT note = p[pos++];
				UINT nins = p[pos++];
			#ifdef PSM_LOG
				//if (!nPat) Log("note+ins: %02X.%02X\n", note, nins);
				if ((!nPat) && (nins >= m_nSamples)) Log("WARNING: invalid instrument number (%d)\n", nins);
			#endif
				if ((note) && (note < 0x80)) note = (note>>4)*12+(note&0x0f)+12+1;
				m[ch].instr = samplemap[nins];
				m[ch].note = note;
			}
			// Volume
			if ((flags & 0x20) && (pos < len))
			{
				m[ch].volcmd = VOLCMD_VOLUME;
				m[ch].vol = p[pos++] / 2;
			}
			// Effect
			if ((flags & 0x10) && (pos+1 < len))
			{
				UINT command = p[pos++];
				UINT param = p[pos++];
				// Convert effects
				switch(command)
				{
				// 01: fine volslide up
				case 0x01:	command = CMD_VOLUMESLIDE; param |= 0x0f; break;
				// 04: fine volslide down
				case 0x04:	command = CMD_VOLUMESLIDE; param>>=4; param |= 0xf0; break;
				// 0C: portamento up
				case 0x0C:	command = CMD_PORTAMENTOUP; param = (param+1)/2; break;
				// 0E: portamento down
				case 0x0E:	command = CMD_PORTAMENTODOWN; param = (param+1)/2; break;
				// 33: Position Jump
				case 0x33:	command = CMD_POSITIONJUMP; break;
				// 34: Pattern break
				case 0x34:	command = CMD_PATTERNBREAK; break;
				// 3D: speed
				case 0x3D:	command = CMD_SPEED; break;
				// 3E: tempo
				case 0x3E:	command = CMD_TEMPO; break;
				// Unknown
				default:
				#ifdef PSM_LOG
					Log("Unknown PSM effect pat=%d row=%d ch=%d: %02X.%02X\n", nPat, row, ch, command, param);
				#endif
					command = param = 0;
				}
				m[ch].command = (BYTE)command;
				m[ch].param = (BYTE)param;
			}
			oldch = ch;
		}
BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength)
//-----------------------------------------------------------
{
	DSMFILEHEADER *pfh = (DSMFILEHEADER *)lpStream;
	DSMSONG *psong;
	DWORD dwMemPos;
	UINT nPat, nSmp;

	if ((!lpStream) || (dwMemLength < 1024) || (pfh->id_RIFF != DSMID_RIFF)
	 || (pfh->riff_len + 8 > dwMemLength) || (pfh->riff_len < 1024)
	 || (pfh->id_DSMF != DSMID_DSMF) || (pfh->id_SONG != DSMID_SONG)
	 || (pfh->song_len > dwMemLength)) return FALSE;
	psong = (DSMSONG *)(lpStream + sizeof(DSMFILEHEADER));
	dwMemPos = sizeof(DSMFILEHEADER) + pfh->song_len;
	m_nType = MOD_TYPE_DSM;
	m_nChannels = psong->numtrk;
	if (m_nChannels < 4) m_nChannels = 4;
	if (m_nChannels > 16) m_nChannels = 16;
	m_nSamples = psong->numsmp;
	if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES - 1;
	m_nDefaultSpeed = psong->speed;
	m_nDefaultTempo = psong->bpm;
	m_nDefaultGlobalVolume = psong->globalvol << 2;
	if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
	m_nSongPreAmp = psong->mastervol & 0x7F;
	for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
	{
		Order[iOrd] = (BYTE)((iOrd < psong->numord) ? psong->orders[iOrd] : 0xFF);
	}
	for (UINT iPan=0; iPan<16; iPan++)
	{
		ChnSettings[iPan].nPan = 0x80;
		if (psong->panpos[iPan] <= 0x80)
		{
			ChnSettings[iPan].nPan = psong->panpos[iPan] << 1;
		}
	}
	memcpy(m_szNames[0], psong->songname, 28);
	nPat = 0;
	nSmp = 1;
	while (dwMemPos < dwMemLength - 8)
	{
		DSMPATT *ppatt = (DSMPATT *)(lpStream + dwMemPos);
		DSMINST *pins = (DSMINST *)(lpStream+dwMemPos);
		// Reading Patterns
		if (ppatt->id_PATT == DSMID_PATT)
		{
			dwMemPos += 8;
			if (dwMemPos + ppatt->patt_len >= dwMemLength) break;
			DWORD dwPos = dwMemPos;
			dwMemPos += ppatt->patt_len;
			MODCOMMAND *m = AllocatePattern(64, m_nChannels);
			if (!m) break;
			PatternSize[nPat] = 64;
			Patterns[nPat] = m;
			UINT row = 0;
			while ((row < 64) && (dwPos + 2 <= dwMemPos))
			{
				UINT flag = lpStream[dwPos++];
				if (flag)
				{
					UINT ch = (flag & 0x0F) % m_nChannels;
					if (flag & 0x80)
					{
						UINT note = lpStream[dwPos++];
						if (note)
						{
							if (note <= 12*9) note += 12;
							m[ch].note = (BYTE)note;
						}
					}
					if (flag & 0x40)
					{
						m[ch].instr = lpStream[dwPos++];
					}
					if (flag & 0x20)
					{
						m[ch].volcmd = VOLCMD_VOLUME;
						m[ch].vol = lpStream[dwPos++];
					}
					if (flag & 0x10)
					{
						UINT command = lpStream[dwPos++];
						UINT param = lpStream[dwPos++];
						switch(command)
						{
						// 4-bit Panning
						case 0x08:
							switch(param & 0xF0)
							{
							case 0x00: param <<= 4; break;
							case 0x10: command = 0x0A; param = (param & 0x0F) << 4; break;
							case 0x20: command = 0x0E; param = (param & 0x0F) | 0xA0; break;
							case 0x30: command = 0x0E; param = (param & 0x0F) | 0x10; break;
							case 0x40: command = 0x0E; param = (param & 0x0F) | 0x20; break;
							default: command = 0;
							}
							break;
						// Portamentos
						case 0x11:
						case 0x12:
							command &= 0x0F;
							break;
						// 3D Sound (?)
						case 0x13:
							command = 'X' - 55;
							param = 0x91;
							break;
						default:
							// Volume + Offset (?)
							command = ((command & 0xF0) == 0x20) ? 0x09 : 0;
						}
						m[ch].command = (BYTE)command;
						m[ch].param = (BYTE)param;
						if (command) ConvertModCommand(&m[ch]);
					}
				} else
				{
					m += m_nChannels;
					row++;
				}
			}
			nPat++;
		} else
		// Reading Samples
		if ((nSmp <= m_nSamples) && (pins->id_INST == DSMID_INST))
		{
			if (dwMemPos + pins->inst_len >= dwMemLength - 8) break;
			DWORD dwPos = dwMemPos + sizeof(DSMINST);
			dwMemPos += 8 + pins->inst_len;
			memcpy(m_szNames[nSmp], pins->samplename, 28);
			MODINSTRUMENT *psmp = &Ins[nSmp];
			memcpy(psmp->name, pins->filename, 13);
			psmp->nGlobalVol = 64;
			psmp->nC4Speed = pins->c2spd;
			psmp->uFlags = (WORD)((pins->flags & 1) ? CHN_LOOP : 0);
			psmp->nLength = pins->length;
			psmp->nLoopStart = pins->loopstart;
			psmp->nLoopEnd = pins->loopend;
			psmp->nVolume = (WORD)(pins->volume << 2);
			if (psmp->nVolume > 256) psmp->nVolume = 256;
			UINT smptype = (pins->flags & 2) ? RS_PCM8S : RS_PCM8U;
			ReadSample(psmp, smptype, (LPCSTR)(lpStream+dwPos), dwMemLength - dwPos);
			nSmp++;
		} else
		{
			break;
		}
	}
	return TRUE;
}
Example #12
0
 bool TimeSeek(double pts, bool preceeding)
 {
   if (AP4_SUCCEEDED(SeekSample(m_Track->GetId(), static_cast<AP4_UI64>(pts*(double)m_Track->GetMediaTimeScale()), preceeding)))
     return AP4_SUCCEEDED(ReadSample());
   return false;
 };
Example #13
0
/*-----------------------------------------------------------------------------
 Mac implementations of the Intel API wrappers
 -----------------------------------------------------------------------------*/
bool PowerStats::Intel_ReadSample() {
  return ReadSample() != 0;
}
Example #14
0
/*----------------------------------------------------------------------
|   WriteSamples
+---------------------------------------------------------------------*/
static AP4_Result
WriteSamples(AP4_Mpeg2TsWriter&               writer,
             AP4_Track*                       audio_track,
             SampleReader*                    audio_reader, 
             AP4_Mpeg2TsWriter::SampleStream* audio_stream,
             AP4_Track*                       video_track,
             SampleReader*                    video_reader, 
             AP4_Mpeg2TsWriter::SampleStream* video_stream,
             unsigned int                     segment_duration_threshold)
{
    AP4_Sample        audio_sample;
    AP4_DataBuffer    audio_sample_data;
    unsigned int      audio_sample_count = 0;
    double            audio_ts = 0.0;
    bool              audio_eos = false;
    AP4_Sample        video_sample;
    AP4_DataBuffer    video_sample_data;
    unsigned int      video_sample_count = 0;
    double            video_ts = 0.0;
    bool              video_eos = false;
    double            last_ts = 0.0;
    unsigned int      segment_number = 0;
    double            segment_duration = 0.0;
    AP4_ByteStream*   output = NULL;
    AP4_ByteStream*   playlist = NULL;
    char              string_buffer[32];
    AP4_Result        result = AP4_SUCCESS;
    AP4_Array<double> segment_durations;
    
    // prime the samples
    if (audio_reader) {
        result = ReadSample(*audio_reader, *audio_track, audio_sample, audio_sample_data, audio_ts, audio_eos);
        if (AP4_FAILED(result)) goto end;
    }
    if (video_reader) {
        result = ReadSample(*video_reader, *video_track, video_sample, video_sample_data, video_ts, video_eos);
        if (AP4_FAILED(result)) goto end;
    }
    
    for (;;) {
        bool sync_sample = false;
        AP4_Track* chosen_track= NULL;
        if (audio_track && !audio_eos) {
            chosen_track = audio_track;
            if (video_track == NULL) sync_sample = true;
        }
        if (video_track && !video_eos) {
            if (audio_track) {
                if (video_ts <= audio_ts) {
                    chosen_track = video_track;
                }
            } else {
                chosen_track = video_track;
            }
            if (chosen_track == video_track && video_sample.IsSync()) {
                sync_sample = true;
            }
        }
        if (chosen_track == NULL) break;
        
        // check if we need to start a new segment
        if (Options.segment_duration && sync_sample) {
            if (video_track) {
                segment_duration = video_ts - last_ts;
            } else {
                segment_duration = audio_ts - last_ts;
            }
            if (segment_duration >= (double)Options.segment_duration - (double)segment_duration_threshold/1000.0) {
                if (video_track) {
                    last_ts = video_ts;
                } else {
                    last_ts = audio_ts;
                }
                if (output) {
                    segment_durations.Append(segment_duration);
                    if (Options.verbose) {
                        printf("Segment %d, duration=%.2f, %d audio samples, %d video samples\n",
                               segment_number, 
                               segment_duration,
                               audio_sample_count, 
                               video_sample_count);
                    }
                    output->Release();
                    output = NULL;
                    ++segment_number;
                    audio_sample_count = 0;
                    video_sample_count = 0;
                }
            }
        }
        if (output == NULL) {
            output = OpenOutput(Options.output, segment_number);
            if (output == NULL) return AP4_ERROR_CANNOT_OPEN_FILE;
            writer.WritePAT(*output);
            writer.WritePMT(*output);
        }
        
        // write the samples out and advance to the next sample
        if (chosen_track == audio_track) {
            result = audio_stream->WriteSample(audio_sample, 
                                               audio_sample_data,
                                               audio_track->GetSampleDescription(audio_sample.GetDescriptionIndex()), 
                                               video_track==NULL, 
                                               *output);
            if (AP4_FAILED(result)) return result;
            
            result = ReadSample(*audio_reader, *audio_track, audio_sample, audio_sample_data, audio_ts, audio_eos);
            if (AP4_FAILED(result)) return result;
            ++audio_sample_count;
        } else if (chosen_track == video_track) {
            result = video_stream->WriteSample(video_sample,
                                               video_sample_data, 
                                               video_track->GetSampleDescription(video_sample.GetDescriptionIndex()),
                                               true, 
                                               *output);
            if (AP4_FAILED(result)) return result;

            result = ReadSample(*video_reader, *video_track, video_sample, video_sample_data, video_ts, video_eos);
            if (AP4_FAILED(result)) return result;
            ++video_sample_count;
        } else {
            break;
        }        
    }
    
    // finish the last segment
    if (output) {
        if (video_track) {
            segment_duration = video_ts - last_ts;
        } else {
            segment_duration = audio_ts - last_ts;
        }
        segment_durations.Append(segment_duration);
        if (Options.verbose) {
            printf("Segment %d, duration=%.2f, %d audio samples, %d video samples\n",
                   segment_number, 
                   segment_duration,
                   audio_sample_count, 
                   video_sample_count);
        }
        output->Release();
        output = NULL;
        ++segment_number;
        audio_sample_count = 0;
        video_sample_count = 0;
    }

    // create the playlist file if needed 
    if (Options.playlist) {
        playlist = OpenOutput(Options.playlist, 0);
        if (playlist == NULL) return AP4_ERROR_CANNOT_OPEN_FILE;

        unsigned int target_duration = 0;
        for (unsigned int i=0; i<segment_durations.ItemCount(); i++) {
            if ((unsigned int)(segment_durations[i]+0.5) > target_duration) {
                target_duration = segment_durations[i];
            }
        }

        playlist->WriteString("#EXTM3U\r\n");
        if (Options.playlist_hls_version > 1) {
            sprintf(string_buffer, "#EXT-X-VERSION:%d\r\n", Options.playlist_hls_version);
            playlist->WriteString(string_buffer);
        }
        playlist->WriteString("#EXT-X-MEDIA-SEQUENCE:0\r\n");
        playlist->WriteString("#EXT-X-TARGETDURATION:");
        sprintf(string_buffer, "%d\r\n\r\n", target_duration);
        playlist->WriteString(string_buffer);

        for (unsigned int i=0; i<segment_durations.ItemCount(); i++) {
            if (Options.playlist_hls_version >= 3) {
                sprintf(string_buffer, "#EXTINF:%f,\r\n", segment_durations[i]);
            } else {
                sprintf(string_buffer, "#EXTINF:%u,\r\n", (unsigned int)(segment_durations[i]+0.5));
            }
            playlist->WriteString(string_buffer);
            sprintf(string_buffer, Options.output, i);
            playlist->WriteString(string_buffer);
            playlist->WriteString("\r\n");
        }
                        
        playlist->WriteString("\r\n#EXT-X-ENDLIST\r\n");
        playlist->Release();
    }    

    if (Options.verbose) {
        if (video_track) {
            segment_duration = video_ts - last_ts;
        } else {
            segment_duration = audio_ts - last_ts;
        }
        printf("Conversion complete, duration=%.2f secs\n",
               segment_duration);
    }
    
end:
    if (output) output->Release();
    
    return result;
}
Example #15
0
void NodeSig(phylo P, sample S, int outmethod, int abundWeighted) {
  // Currently need to use taxon name of interior as a marker,
  // because Mesquite will not show all labels, but if it will soon,
  // best to use notes, and not muck around with taxon name

  //TODO modifying to use abundances, need longs instead of ints for counters

  int plot, node, taxon, i, ordHI, ordLO, run;
  int tipsReal_n[P.nnodes];
  float test_r[RUNS];
  char mark[2];
  char tmp[15];
  int **tips_rn;
  // was: int tips_rn[RUNS][MaxNode+1];
  phylo Out[S.nsamples];
  int *attach;

  attach = ivector(0, S.ntaxa-1);

  tips_rn = imatrix(0, RUNS-1, 0, P.nnodes-1);

  for (i = 0; i < S.nsamples; i++) {
    Out[i] = P; // all the pointers in Out are the same as those in Intree
                // careful not to change any preexisting arrays in Out, or they will
                // also be changed in Intree!

    if (TreeView == 0)
      Out[i].arenotes = 1;
    if (TreeView == 1)
      Out[i].arenotes = 0;

    // dimension a new array for Out names:
    if (TreeView == 0)
      Out[i].notes = cmatrix(0, P.nnodes-1, 0, MAXNOTELENGTH+10);
    if (TreeView == 1)
      Out[i].taxon = cmatrix(0, P.nnodes-1, 0, MAXTAXONLENGTH+10);

  }

  // for each plot

  if (outmethod == 1)
    printf("plot\tnode\tnode_name           \tntaxa\tmedian\trank\tsig\n");
  for (plot = 0; plot < S.nsamples; plot++) {
    if (S.srec[plot] > 2) {

      for (node = 0; node < P.nnodes; node++) {
        tipsReal_n[node] = 0;
        for (run = 0; run < RUNS; run++)
          tips_rn[run][node] = 0;
      }

      // need to reset it
      AttachSampleToPhylo(S, P, attach);

      // follow up from tips, adding 1 to each node passed through
      for (taxon = 0; taxon < S.srec[plot]; taxon++) {
        i = P.t2n[ attach[ S.id[plot][taxon] ] ];
        while (i != -1) {
          if (abundWeighted)
            tipsReal_n[i] += S.abund[plot][taxon];
          else
            tipsReal_n[i]++;
          i = P.up[i];
        }
      }
      // ooo this is slow, putting rnd inside the plot loop!
      for (run = 0; run < RUNS; run++) {
        // now randomize the plot
        // RandomizeB(plot);
        PhylogenyAttachShuffle(P, S, attach);

        for (taxon = 0; taxon < S.srec[plot]; taxon++) {
          i = P.t2n[ attach[ S.id[plot][taxon] ] ];
          while (i != -1) {
            if (abundWeighted)
              tips_rn[run][i] += S.abund[plot][taxon];
            else
              tips_rn[run][i]++;
            i = P.up[i];
          }
        }
      }

      // now unpeel the nodes
      for (node = 0; node < P.nnodes; node++) {
        if (TreeView == 0)
          strcpy(Out[plot].notes[node], "");
        if (TreeView == 1)
          strcpy(Out[plot].taxon[node], "");

        // interior nodes only
        if (P.noat[node] != 0) {
          ordHI = 0;
          ordLO = 0;
          for (run = 0; run < RUNS; run++) {
            if (tips_rn[run][node] < tipsReal_n[node])
              ordHI++;
            if (tips_rn[run][node] > tipsReal_n[node])
              ordLO++;
          }

          strcpy(mark, " ");

          if (ordLO >= (int) ((float) RUNS * 0.975)) {
            strcpy(mark, "-");
            if (TreeView == 0)
              strcat(Out[plot].notes[node], "SIGLESS");
            if (TreeView == 1) {
              sprintf(tmp, "LESS_%d_", node);
              strcpy(Out[plot].taxon[node], tmp);
            }
            if (outmethod == 1)
              printf("%d\t%d\t%-10s\t%d\t%d\t%d\t%d\t%s\n", plot
                     +1, node, P.taxon[node], tipsReal_n[node],
                     (int) test_r[(int) ((float) RUNS * 0.5)], ordHI,
                     ordLO, mark);
          } else if (ordHI >= (int) ((float) RUNS * 0.975)) {
            strcpy(mark, "+");
            if (TreeView == 0)
              strcat(Out[plot].notes[node], "SIGMORE");

            if (TreeView == 1) {
              sprintf(tmp, "MORE_%d_", node);
              strcpy(Out[plot].taxon[node], tmp);
            }
            if (outmethod == 1)
              printf("%d\t%d\t%-20s\t%d\t%d\t%d\t%d\t%s\n", plot
                     +1, node, P.taxon[node], tipsReal_n[node],
                     (int) test_r[(int) ((float) RUNS * 0.5)], ordHI,
                     ordLO, mark);
          }
          // printf("%s\t%s\n", Out.taxon[node], Intree.taxon[node]);
          else if (outmethod == 1)
            printf("%d\t%d\t%-20s\t%d\t%d\t%d\t%d\t%s\n", plot+1,
                   node, P.taxon[node], tipsReal_n[node],
                   (int) test_r[(int) ((float) RUNS * 0.5)], ordHI,
                   ordLO, mark);
        }
        if ((TreeView == 1) && (strcmp(P.taxon[node], ".") != 0)) {
          strcat(Out[plot].taxon[node], P.taxon[node]);
        }
      }

    }
    // Name tree
    strcpy(Out[plot].phyname, "NodeSig_");
    strcat(Out[plot].phyname, S.pname[plot]);
  }
  if (outmethod ==0)
    WriteNexus(Out, S.nsamples, ReadSample(SampleFile), 1,
               ReadTraits(TraitFile), 1);

}
Example #16
0
BOOL CSoundFile::ReadPTM(const BYTE *lpStream, DWORD dwMemLength)
//---------------------------------------------------------------
{
	DWORD dwMemPos;
	UINT nOrders;

	if ((!lpStream) || (dwMemLength < sizeof(PTMFILEHEADER))) return FALSE;
	PTMFILEHEADER pfh = *(LPPTMFILEHEADER)lpStream;

	pfh.norders = bswapLE16(pfh.norders);
	pfh.nsamples = bswapLE16(pfh.nsamples);
	pfh.npatterns = bswapLE16(pfh.npatterns);
	pfh.nchannels = bswapLE16(pfh.nchannels);
	pfh.fileflags = bswapLE16(pfh.fileflags);
	pfh.reserved2 = bswapLE16(pfh.reserved2);
	pfh.ptmf_id = bswapLE32(pfh.ptmf_id);
	for (UINT j=0; j<128; j++)
        {
	        pfh.patseg[j] = bswapLE16(pfh.patseg[j]);
	}

	if ((pfh.ptmf_id != 0x464d5450) || (!pfh.nchannels)
	 || (pfh.nchannels > 32)
	 || (pfh.norders > 256) || (!pfh.norders)
	 || (!pfh.nsamples) || (pfh.nsamples > 255)
	 || (!pfh.npatterns) || (pfh.npatterns > 128)
	 || (SIZEOF_PTMFILEHEADER+pfh.nsamples*SIZEOF_PTMSAMPLE >= (int)dwMemLength)) return FALSE;
	memcpy(m_szNames[0], pfh.songname, 28);
	m_szNames[0][28] = 0;
	m_nType = MOD_TYPE_PTM;
	m_nChannels = pfh.nchannels;
	m_nSamples = (pfh.nsamples < MAX_SAMPLES) ? pfh.nsamples : MAX_SAMPLES-1;
	dwMemPos = SIZEOF_PTMFILEHEADER;
	nOrders = (pfh.norders < MAX_ORDERS) ? pfh.norders : MAX_ORDERS-1;
	memcpy(Order, pfh.orders, nOrders);
	for (UINT ipan=0; ipan<m_nChannels; ipan++)
	{
		ChnSettings[ipan].nVolume = 64;
		ChnSettings[ipan].nPan = ((pfh.chnpan[ipan] & 0x0F) << 4) + 4;
	}
	for (UINT ismp=0; ismp<m_nSamples; ismp++, dwMemPos += SIZEOF_PTMSAMPLE)
	{
		MODINSTRUMENT *pins = &Ins[ismp+1];
		PTMSAMPLE *psmp = (PTMSAMPLE *)(lpStream+dwMemPos);

		lstrcpyn(m_szNames[ismp+1], psmp->samplename, 28);
		memcpy(pins->name, psmp->filename, 12);
		pins->name[12] = 0;
		pins->nGlobalVol = 64;
		pins->nPan = 128;
		pins->nVolume = psmp->volume << 2;
		pins->nC4Speed = bswapLE16(psmp->nC4Spd) << 1;
		pins->uFlags = 0;
		if ((psmp->sampletype & 3) == 1)
		{
			UINT smpflg = RS_PCM8D;
			pins->nLength = BS2WORD(psmp->length);
			pins->nLoopStart = BS2WORD(psmp->loopbeg);
			pins->nLoopEnd = BS2WORD(psmp->loopend);
			DWORD samplepos = BS2WORD(psmp->fileofs);
			if (psmp->sampletype & 4) pins->uFlags |= CHN_LOOP;
			if (psmp->sampletype & 8) pins->uFlags |= CHN_PINGPONGLOOP;
			if (psmp->sampletype & 16)
			{
				pins->uFlags |= CHN_16BIT;
				pins->nLength >>= 1;
				pins->nLoopStart >>= 1;
				pins->nLoopEnd >>= 1;
				smpflg = RS_PTM8DTO16;
			}
			if ((pins->nLength) && (samplepos) && (samplepos < dwMemLength))
			{
				ReadSample(pins, smpflg, (LPSTR)(lpStream+samplepos), dwMemLength-samplepos);
			}
		}
Example #17
0
bool module_renderer::ReadDSM(const uint8_t * const lpStream, const uint32_t dwMemLength)
//-----------------------------------------------------------------------
{
    DSMFILEHEADER *pfh = (DSMFILEHEADER *)lpStream;
    DSMSONG *psong;
    uint32_t dwMemPos;
    UINT nPat, nSmp;

    if ((!lpStream) || (dwMemLength < 1024) || (pfh->id_RIFF != DSMID_RIFF)
     || (pfh->riff_len + 8 > dwMemLength) || (pfh->riff_len < 1024)
     || (pfh->id_DSMF != DSMID_DSMF) || (pfh->id_SONG != DSMID_SONG)
     || (pfh->song_len > dwMemLength)) return false;
    psong = (DSMSONG *)(lpStream + sizeof(DSMFILEHEADER));
    dwMemPos = sizeof(DSMFILEHEADER) + pfh->song_len;
    m_nType = MOD_TYPE_DSM;
    m_nChannels = psong->numtrk;
    if (m_nChannels < 1) m_nChannels = 1;
    if (m_nChannels > 16) m_nChannels = 16;
    m_nSamples = psong->numsmp;
    if (m_nSamples > MAX_SAMPLES) m_nSamples = MAX_SAMPLES;
    m_nDefaultSpeed = psong->speed;
    m_nDefaultTempo = psong->bpm;
    m_nDefaultGlobalVolume = psong->globalvol << 2;
    if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > MAX_GLOBAL_VOLUME)) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME;
    m_nSamplePreAmp = psong->mastervol & 0x7F;
    Order.ReadAsByte(psong->orders, psong->numord, sizeof(psong->orders));

    for (UINT iPan=0; iPan<16; iPan++)
    {
        ChnSettings[iPan].nPan = 0x80;
        if (psong->panpos[iPan] <= 0x80)
        {
            ChnSettings[iPan].nPan = psong->panpos[iPan] << 1;
        }
    }
    assign_without_padding(this->song_name, psong->songname, 28);
    nPat = 0;
    nSmp = 1;
    while (dwMemPos < dwMemLength - 8)
    {
        DSMPATT *ppatt = (DSMPATT *)(lpStream + dwMemPos);
        DSMSAMPLE *pSmp = (DSMSAMPLE *)(lpStream+dwMemPos);
        // Reading Patterns
        if (ppatt->id_PATT == DSMID_PATT)
        {
            dwMemPos += 8;
            if (dwMemPos + ppatt->patt_len >= dwMemLength) break;
            uint32_t dwPos = dwMemPos;
            dwMemPos += ppatt->patt_len;
            if(Patterns.Insert(nPat, 64))
                break;

            modplug::tracker::modevent_t *m = Patterns[nPat];
            UINT row = 0;
            while ((row < 64) && (dwPos + 2 <= dwMemPos))
            {
                UINT flag = lpStream[dwPos++];
                if (flag)
                {
                    UINT ch = (flag & 0x0F) % m_nChannels;
                    if (flag & 0x80)
                    {
                        UINT note = lpStream[dwPos++];
                        if (note)
                        {
                            if (note <= 12*9) note += 12;
                            m[ch].note = (uint8_t)note;
                        }
                    }
                    if (flag & 0x40)
                    {
                        m[ch].instr = lpStream[dwPos++];
                    }
                    if (flag & 0x20)
                    {
                        m[ch].volcmd = VolCmdVol;
                        m[ch].vol = lpStream[dwPos++];
                    }
                    if (flag & 0x10)
                    {
                        UINT command = lpStream[dwPos++];
                        UINT param = lpStream[dwPos++];
                        switch(command)
                        {
                        // 4-bit Panning
                        case 0x08:
                            switch(param & 0xF0)
                            {
                            case 0x00: param <<= 4; break;
                            case 0x10: command = 0x0A; param = (param & 0x0F) << 4; break;
                            case 0x20: command = 0x0E; param = (param & 0x0F) | 0xA0; break;
                            case 0x30: command = 0x0E; param = (param & 0x0F) | 0x10; break;
                            case 0x40: command = 0x0E; param = (param & 0x0F) | 0x20; break;
                            default: command = 0;
                            }
                            break;
                        // Portamentos
                        case 0x11:
                        case 0x12:
                            command &= 0x0F;
                            break;
                        // 3D Sound (?)
                        case 0x13:
                            command = 'X' - 55;
                            param = 0x91;
                            break;
                        default:
                            // Volume + Offset (?)
                            command = ((command & 0xF0) == 0x20) ? 0x09 : 0;
                        }
                        //XXXih: gross!
                        m[ch].command = (modplug::tracker::cmd_t) command;
                        m[ch].param = (uint8_t)param;
                        if (command) ConvertModCommand(&m[ch]);
                    }
                } else
                {
                    m += m_nChannels;
                    row++;
                }
            }
            nPat++;
        } else
        // Reading Samples
        if ((nSmp <= m_nSamples) && (pSmp->id_INST == DSMID_INST))
        {
            if (dwMemPos + pSmp->inst_len >= dwMemLength - 8) break;
            uint32_t dwPos = dwMemPos + sizeof(DSMSAMPLE);
            dwMemPos += 8 + pSmp->inst_len;
            memcpy(m_szNames[nSmp], pSmp->samplename, 28);
            SpaceToNullStringFixed<28>(m_szNames[nSmp]);
            modsample_t *psmp = &Samples[nSmp];
            memcpy(psmp->legacy_filename, pSmp->filename, 13);
            SpaceToNullStringFixed<13>(psmp->legacy_filename);
            psmp->global_volume = 64;
            psmp->c5_samplerate = pSmp->c2spd;
            psmp->flags = (uint16_t)((pSmp->flags & 1) ? CHN_LOOP : 0);
            psmp->length = pSmp->length;
            psmp->loop_start = pSmp->loopstart;
            psmp->loop_end = pSmp->loopend;
            psmp->default_volume = (uint16_t)(pSmp->volume << 2);
            if (psmp->default_volume > 256) psmp->default_volume = 256;
            UINT smptype = (pSmp->flags & 2) ? RS_PCM8S : RS_PCM8U;
            ReadSample(psmp, smptype, (LPCSTR)(lpStream+dwPos), dwMemLength - dwPos);
            nSmp++;
        } else
        {
            break;
        }
    }
    return true;
}
Example #18
0
bool module_renderer::ReadITProject(const uint8_t * lpStream, const uint32_t dwMemLength)
//-----------------------------------------------------------------------
{
    UINT i,n,nsmp;
    uint32_t id,len,size;
    uint32_t dwMemPos = 0;
    uint32_t version;

    ASSERT_CAN_READ(12);

    // Check file ID

    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id != ITP_FILE_ID) return false;
    dwMemPos += sizeof(uint32_t);

    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    version = id;
    dwMemPos += sizeof(uint32_t);

    // bad_max supported version
    if(version > ITP_VERSION)
    {
        return false;
    }

    m_nType = MOD_TYPE_IT;

    // Song name

    // name string length
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    dwMemPos += sizeof(uint32_t);

    // name string
    ASSERT_CAN_READ(len);
    if (len <= MAX_SAMPLENAME)
    {
        assign_without_padding(this->song_name, reinterpret_cast<const char *>(lpStream + dwMemPos), len);
        dwMemPos += len;
    }
    else return false;

    // Song comments

    // comment string length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);
    if(id > UINT16_MAX) return false;

    // allocate and copy comment string
    ASSERT_CAN_READ(id);
    if(id > 0)
    {
        ReadMessage(lpStream + dwMemPos, id - 1, leCR);
    }
    dwMemPos += id;

    // Song global config
    ASSERT_CAN_READ(5*4);

    // m_dwSongFlags
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_dwSongFlags = (id & SONG_FILE_FLAGS);
    dwMemPos += sizeof(uint32_t);

    if(!(m_dwSongFlags & SONG_ITPROJECT)) return false;

    // m_nDefaultGlobalVolume
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultGlobalVolume = id;
    dwMemPos += sizeof(uint32_t);

    // m_nSamplePreAmp
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nSamplePreAmp = id;
    dwMemPos += sizeof(uint32_t);

    // m_nDefaultSpeed
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultSpeed = id;
    dwMemPos += sizeof(uint32_t);

    // m_nDefaultTempo
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultTempo = id;
    dwMemPos += sizeof(uint32_t);

    // Song channels data
    ASSERT_CAN_READ(2*4);

    // m_nChannels
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nChannels = (modplug::tracker::chnindex_t)id;
    dwMemPos += sizeof(uint32_t);
    if(m_nChannels > 127) return false;

    // channel name string length (=MAX_CHANNELNAME)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    dwMemPos += sizeof(uint32_t);
    if(len > MAX_CHANNELNAME) return false;

    // Channels' data
    for(i=0; i<m_nChannels; i++){
        ASSERT_CAN_READ(3*4 + len);

        // ChnSettings[i].nPan
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].nPan = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].dwFlags
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].dwFlags = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].nVolume
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].nVolume = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].szName
        memcpy(&ChnSettings[i].szName[0],lpStream+dwMemPos,len);
        SetNullTerminator(ChnSettings[i].szName);
        dwMemPos += len;
    }

    // Song mix plugins
    // size of mix plugins data
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);

    // mix plugins
    ASSERT_CAN_READ(id);
    dwMemPos += LoadMixPlugins(lpStream+dwMemPos, id);

    // Song midi config

    // midi cfg data length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);

    // midi cfg
    ASSERT_CAN_READ(id);
    if (id <= sizeof(m_MidiCfg))
    {
        memcpy(&m_MidiCfg, lpStream + dwMemPos, id);
        SanitizeMacros();
        dwMemPos += id;
    }

    // Song Instruments

    // m_nInstruments
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nInstruments = (modplug::tracker::instrumentindex_t)id;
    if(m_nInstruments > MAX_INSTRUMENTS) return false;
    dwMemPos += sizeof(uint32_t);

    // path string length (=_MAX_PATH)
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    if(len > _MAX_PATH) return false;
    dwMemPos += sizeof(uint32_t);

    // instruments' paths
    for(i=0; i<m_nInstruments; i++){
        ASSERT_CAN_READ(len);
        memcpy(&m_szInstrumentPath[i][0],lpStream+dwMemPos,len);
        SetNullTerminator(m_szInstrumentPath[i]);
        dwMemPos += len;
    }

    // Song Orders

    // size of order array (=MAX_ORDERS)
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    size = id;
    if(size > MAX_ORDERS) return false;
    dwMemPos += sizeof(uint32_t);

    // order data
    ASSERT_CAN_READ(size);
    Order.ReadAsByte(lpStream+dwMemPos, size, dwMemLength-dwMemPos);
    dwMemPos += size;



    // Song Patterns

    ASSERT_CAN_READ(3*4);
    // number of patterns (=MAX_PATTERNS)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    size = id;
    dwMemPos += sizeof(uint32_t);
    if(size > MAX_PATTERNS) return false;

    // m_nPatternNames
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    const modplug::tracker::patternindex_t numNamedPats = id;
    dwMemPos += sizeof(uint32_t);

    // pattern name string length (=MAX_PATTERNNAME)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    const uint32_t patNameLen = id;
    dwMemPos += sizeof(uint32_t);

    // m_lpszPatternNames
    ASSERT_CAN_READ(numNamedPats * patNameLen);
    char *patNames = (char *)(lpStream + dwMemPos);
    dwMemPos += numNamedPats * patNameLen;

    // modcommand data length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    n = id;
    if(n != 6) return false;
    dwMemPos += sizeof(uint32_t);

    for(modplug::tracker::patternindex_t npat=0; npat<size; npat++)
    {
        // Patterns[npat].GetNumRows()
        ASSERT_CAN_READ(4);
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        if(id > MAX_PATTERN_ROWS) return false;
        const modplug::tracker::rowindex_t nRows = id;
        dwMemPos += sizeof(uint32_t);

        // Try to allocate & read only sized patterns
        if(nRows)
        {

            // Allocate pattern
            if(Patterns.Insert(npat, nRows))
            {
                dwMemPos += m_nChannels * Patterns[npat].GetNumRows() * n;
                continue;
            }
            if(npat < numNamedPats && patNameLen > 0)
            {
                Patterns[npat].SetName(patNames, patNameLen);
                patNames += patNameLen;
            }

            // Pattern data
            long datasize = m_nChannels * Patterns[npat].GetNumRows() * n;
            //if (streamPos+datasize<=dwMemLength) {
            if(Patterns[npat].ReadITPdata(lpStream, dwMemPos, datasize, dwMemLength))
            {
                ErrorBox(IDS_ERR_FILEOPEN, NULL);
                return false;
            }
            //memcpy(Patterns[npat],lpStream+streamPos,datasize);
            //streamPos += datasize;
            //}
        }
    }

    // Load embeded samples

    ITSAMPLESTRUCT pis;

    // Read original number of samples
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id > MAX_SAMPLES) return false;
    m_nSamples = (modplug::tracker::sampleindex_t)id;
    dwMemPos += sizeof(uint32_t);

    // Read number of embeded samples
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id > MAX_SAMPLES) return false;
    n = id;
    dwMemPos += sizeof(uint32_t);

    // Read samples
    for(i=0; i<n; i++){

        ASSERT_CAN_READ(4 + sizeof(ITSAMPLESTRUCT) + 4);

        // Sample id number
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        nsmp = id;
        dwMemPos += sizeof(uint32_t);

        if(nsmp < 1 || nsmp >= MAX_SAMPLES)
            return false;

        // Sample struct
        memcpy(&pis,lpStream+dwMemPos,sizeof(ITSAMPLESTRUCT));
        dwMemPos += sizeof(ITSAMPLESTRUCT);

        // Sample length
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        len = id;
        dwMemPos += sizeof(uint32_t);
        if(dwMemPos >= dwMemLength || len > dwMemLength - dwMemPos) return false;

        // Copy sample struct data (ut-oh... this code looks very familiar!)
        if(pis.id == LittleEndian(IT_IMPS))
        {
            modsample_t *pSmp = &Samples[nsmp];
            memcpy(pSmp->legacy_filename, pis.filename, 12);
            pSmp->flags = 0;
            pSmp->length = 0;
            pSmp->loop_start = pis.loopbegin;
            pSmp->loop_end = pis.loopend;
            pSmp->sustain_start = pis.susloopbegin;
            pSmp->sustain_end = pis.susloopend;
            pSmp->c5_samplerate = pis.C5Speed;
            if(!pSmp->c5_samplerate) pSmp->c5_samplerate = 8363;
            if(pis.C5Speed < 256) pSmp->c5_samplerate = 256;
            pSmp->default_volume = pis.vol << 2;
            if(pSmp->default_volume > 256) pSmp->default_volume = 256;
            pSmp->global_volume = pis.gvl;
            if(pSmp->global_volume > 64) pSmp->global_volume = 64;
            if(pis.flags & 0x10) pSmp->flags |= CHN_LOOP;
            if(pis.flags & 0x20) pSmp->flags |= CHN_SUSTAINLOOP;
            if(pis.flags & 0x40) pSmp->flags |= CHN_PINGPONGLOOP;
            if(pis.flags & 0x80) pSmp->flags |= CHN_PINGPONGSUSTAIN;
            pSmp->default_pan = (pis.dfp & 0x7F) << 2;
            if(pSmp->default_pan > 256) pSmp->default_pan = 256;
            if(pis.dfp & 0x80) pSmp->flags |= CHN_PANNING;
            pSmp->vibrato_type = autovibit2xm[pis.vit & 7];
            pSmp->vibrato_rate = pis.vis;
            pSmp->vibrato_depth = pis.vid & 0x7F;
            pSmp->vibrato_sweep = pis.vir;
            if(pis.length){
                pSmp->length = pis.length;
                if (pSmp->length > MAX_SAMPLE_LENGTH) pSmp->length = MAX_SAMPLE_LENGTH;
                UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
                if (pis.flags & 2){
                    flags += 5;
                    if (pis.flags & 4) flags |= RSF_STEREO;
                    pSmp->flags |= CHN_16BIT;
                }
                else{
                    if (pis.flags & 4) flags |= RSF_STEREO;
                }
                // Read sample data
                ReadSample(&Samples[nsmp], flags, (LPSTR)(lpStream+dwMemPos), len);
                dwMemPos += len;
                memcpy(m_szNames[nsmp], pis.name, 26);
            }
        }
    }

    // Load instruments

    CMappedFile f;
    LPBYTE lpFile;

    for(modplug::tracker::instrumentindex_t i = 0; i < m_nInstruments; i++)
    {

        if(m_szInstrumentPath[i][0] == '\0' || !f.Open(m_szInstrumentPath[i])) continue;

        len = f.GetLength();
        lpFile = f.Lock(len);
        if(!lpFile) { f.Close(); continue; }

        ReadInstrumentFromFile(i+1, lpFile, len);
        f.Unlock();
        f.Close();
    }

    // Extra info data

    __int32 fcode = 0;
    const uint8_t * ptr = lpStream + bad_min(dwMemPos, dwMemLength);

    if (dwMemPos <= dwMemLength - 4) {
        fcode = (*((__int32 *)ptr));
    }

    // Embed instruments' header [v1.01]
    if(version >= 0x00000101 && m_dwSongFlags & SONG_ITPEMBEDIH && fcode == 'EBIH')
    {
        // jump embeded instrument header tag
        ptr += sizeof(__int32);

        // set first instrument's header as current
        i = 1;

        // parse file
        while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments )
        {

            fcode = (*((__int32 *)ptr));                    // read field code

            switch( fcode )
            {
            case 'MPTS': goto mpts; //:)            // reached end of instrument headers
            case 'SEP@': case 'MPTX':
                ptr += sizeof(__int32);                    // jump code
                i++;                                                    // switch to next instrument
                break;

            default:
                ptr += sizeof(__int32);                    // jump field code
                ReadExtendedInstrumentProperty(Instruments[i], fcode, ptr, lpStream + dwMemLength);
                break;
            }
        }
    }

    //HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate,
    //      hence the code duplication.
    if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 )
    {
        fcode = (*((__int32 *)ptr));
    }

    // Song extensions
mpts:
    if( fcode == 'MPTS' )
        LoadExtendedSongProperties(MOD_TYPE_IT, ptr, lpStream, dwMemLength);

    m_nMaxPeriod = 0xF000;
    m_nMinPeriod = 8;

    if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
    {
        SetModFlag(MSF_COMPATIBLE_PLAY, false);
        SetModFlag(MSF_MIDICC_BUGEMULATION, true);
        SetModFlag(MSF_OLDVOLSWING, true);
    }

    return true;
}