Ejemplo n.º 1
0
void TextureMap::GenerateFilteredMaps()
{
  int r,s,x,y;
  int lowres,highres;
  float sample[samples];
  float *sample1=(float*)calloc(samples,sizeof(float)),
        *sample2=(float*)calloc(samples,sizeof(float)),
        *sample3=(float*)calloc(samples,sizeof(float)),
        *sample4=(float*)calloc(samples,sizeof(float));

  for(r=maxresolution-1;r>=0;r--)
  {
    highres=2*(1<<r);
    lowres=(1<<r);
    for(x=0;x<lowres;x++)
    {
      for(y=0;y<lowres;y++)
      {
	ReadUnfilteredSample(r+1,x*2+0,y*2+0,sample1);
	ReadUnfilteredSample(r+1,x*2+1,y*2+0,sample2);
	ReadUnfilteredSample(r+1,x*2+0,y*2+1,sample3);
	ReadUnfilteredSample(r+1,x*2+1,y*2+1,sample4);
	for(s=0;s<samples;s++)
	{
	  sample[s]=0.25*(sample1[s]+sample2[s]+sample3[s]+sample4[s]);
	}
	WriteSample(r,x,y,sample);
      }
    }
  }
  free(sample1);
  free(sample2);
  free(sample3);
  free(sample4);
}
Ejemplo n.º 2
0
static double ChooseSample (void *vpar, long i, long j)
{
   Sample_Param *param = (Sample_Param *)vpar;
   double x, y;
   
   if (swrite_Basic)
      WriteSample (vpar, 0, j);
   x = i * param->a + j * param->b + param->c;
   y = param->F(x);
   return y;
}
Ejemplo n.º 3
0
/*----------------------------------------------------------------------
|   WriteSamples
+---------------------------------------------------------------------*/
static void
WriteSamples(AP4_Track*             track, 
             AP4_SampleDescription* sdesc, 
             AP4_ByteStream*        output)
{
    // make the frame prefix
    unsigned int   nalu_length_size = 0;
    AP4_DataBuffer prefix;
    if (AP4_FAILED(MakeFramePrefix(sdesc, prefix, nalu_length_size))) {
        return;
    }

    AP4_Sample     sample;
    AP4_DataBuffer data;
    AP4_Ordinal    index = 0;
    while (AP4_SUCCEEDED(track->ReadSample(index, sample, data))) {
        WriteSample(data, prefix, nalu_length_size, output);
	    index++;
    }
}
Ejemplo n.º 4
0
/*----------------------------------------------------------------------
|   DecryptAndWriteSamples
+---------------------------------------------------------------------*/
static void
DecryptAndWriteSamples(AP4_Track*             track, 
                       AP4_SampleDescription* sdesc, 
                       AP4_Byte*              key, 
                       AP4_ByteStream*        output)
{
    AP4_ProtectedSampleDescription* pdesc = AP4_DYNAMIC_CAST(AP4_ProtectedSampleDescription, sdesc);
    if (pdesc == NULL) {
        fprintf(stderr, "ERROR: unable to obtain cipher info\n");
        return;
    }
    
    // get the original sample description and make the prefix
    AP4_SampleDescription* orig_sdesc = pdesc->GetOriginalSampleDescription();
    unsigned int   nalu_length_size = 0;
    AP4_DataBuffer prefix;
    if (AP4_FAILED(MakeFramePrefix(orig_sdesc, prefix, nalu_length_size))) {
        return;
    }
    
    // create the decrypter
    AP4_SampleDecrypter* decrypter = AP4_SampleDecrypter::Create(pdesc, key, 16);
    if (decrypter == NULL) {
        fprintf(stderr, "ERROR: unable to create decrypter\n");
        return;
    }

    AP4_Sample     sample;
    AP4_DataBuffer encrypted_data;
    AP4_DataBuffer decrypted_data;
    AP4_Ordinal    index = 0;
    while (AP4_SUCCEEDED(track->ReadSample(index, sample, encrypted_data))) {
        if (AP4_FAILED(decrypter->DecryptSampleData(encrypted_data, decrypted_data))) {
            fprintf(stderr, "ERROR: failed to decrypt sample\n");
            return;
        }
        WriteSample(decrypted_data, prefix, nalu_length_size, output);
	    index++;
    }
}
Ejemplo n.º 5
0
void WriteSamples2(s16* rl , u32 sample_count)
{
	for (u32 i=0;i<(sample_count*2);i+=2)
		WriteSample(rl[i|0],rl[i|1]);
}
Ejemplo n.º 6
0
void WriteSamples1(s16* r , s16* l , u32 sample_count)
{
	for (u32 i=0;i<sample_count;i++)
		WriteSample(r[i],l[i]);
}
Ejemplo n.º 7
0
GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset, Bool drift_inter)
{
	u32 i, tracksDone;
	TrackWriter *tmp, *curWriter;
	GF_Err e;
	u32 descIndex, sampSize, chunkNumber;
	u64 DTS;
	u16 curGroupID;
	u8 forceNewChunk, writeGroup, isEdited;
	//this is used to emulate the write ...
	u64 offset, sampOffset, size, mdatSize;
	u32 count;
	GF_ISOFile *movie = mw->movie;

	mdatSize = 0;

#ifdef TEST_LARGE_FILES
	if (!Emulation) {
		char *blank;
		u32 count, i;
		i = count = 0;
		blank = gf_malloc(sizeof(char)*1024*1024);
		memset(blank, 0, sizeof(char)*1024*1024);
		count = 4096;
		memset(blank, 0, sizeof(char)*1024*1024);
		while (i<count) {
			u32 res = gf_bs_write_data(bs, blank, 1024*1024);
			if (res != 1024*1024) fprintf(stdout, "error writing to disk: only %d bytes written\n", res);
			i++;
			fprintf(stdout, "writing blank block: %.02f done - %d/%d \r", (100.0*i)/count , i, count);
		}
		gf_free(blank);
	}
	mdatSize = 4096*1024;
	mdatSize *= 1024;
#endif

	/*write meta content first - WE DON'T support fragmentation of resources in ISOM atm*/
	if (movie->meta) {
		e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);
		if (e) return e;
		mdatSize += size;
		StartOffset += (u32) size;
	}
	if (movie->moov && movie->moov->meta) {
		e = DoWriteMeta(movie, movie->moov->meta, bs, Emulation, StartOffset, &size);
		if (e) return e;
		mdatSize += size;
		StartOffset += (u32) size;
	}
	i=0;
	while ((tmp = (TrackWriter*)gf_list_enum(writers, &i))) {
		if (tmp->mdia->mediaTrack->meta) {
			e = DoWriteMeta(movie, tmp->mdia->mediaTrack->meta, bs, Emulation, StartOffset, &size);
			if (e) return e;
			mdatSize += size;
			StartOffset += (u32) size;
		}
	}



	if (movie->storageMode == GF_ISOM_STORE_TIGHT) 
		return DoFullInterleave(mw, writers, bs, Emulation, StartOffset);

	e = GF_OK;

	curGroupID = 1;
	//we emulate a write from this offset...
	offset = StartOffset;
	writeGroup = 1;
	tracksDone = 0;

#ifdef TEST_LARGE_FILES
	offset += mdatSize;
#endif

	count = gf_list_count(writers);
	//browse each groups
	while (1) {
		/*the max DTS the chunk of the current writer*/
		u64 chunkLastDTS = 0;
		/*the timescale related to the max DTS*/
		u32 chunkLastScale = 0;

		writeGroup = 1;

		//proceed a group
		while (writeGroup) {
			curWriter = NULL;
			for (i=0 ; i < count; i++) {
				tmp = (TrackWriter*)gf_list_get(writers, i);
				
				//is it done writing ?
				if (tmp->isDone) continue;

				//is it in our group ??
				if (tmp->mdia->information->sampleTable->groupID != curGroupID) continue;

				//write till this chunk is full on this track...
				while (1) {
					//To Check: are empty sample tables allowed ???
					if (tmp->sampleNumber > tmp->mdia->information->sampleTable->SampleSize->sampleCount) {
						tmp->isDone = 1;
						tracksDone ++;
						break;
					}

					//OK, get the current sample in this track
					stbl_GetSampleDTS(tmp->mdia->information->sampleTable->TimeToSample, tmp->sampleNumber, &DTS);

					//can this sample fit in our chunk ?
					if ( ( (DTS - tmp->DTSprev) + tmp->chunkDur) *  movie->moov->mvhd->timeScale > movie->interleavingTime * tmp->timeScale
						/*drfit check: reject sample if outside our check window*/
						|| (drift_inter && chunkLastDTS && ( ((u64)tmp->DTSprev*chunkLastScale) > ((u64)chunkLastDTS*tmp->timeScale)) ) 
						) {
						//in case the sample is longer than InterleaveTime
						if (!tmp->chunkDur) {
							forceNewChunk = 1;
						} else {
							//this one is full. go to next one (exit the loop)
							tmp->chunkDur = 0;
							break;
						}
					} else {
						forceNewChunk = tmp->chunkDur ? 0 : 1;
					}
					//OK, we can write this track
					curWriter = tmp;
					
					//small check for first 2 samples (DTS = 0 :)
					if (tmp->sampleNumber == 2 && !tmp->chunkDur) forceNewChunk = 0;

					tmp->chunkDur += (u32) (DTS - tmp->DTSprev);
					tmp->DTSprev = DTS;

					e = stbl_GetSampleInfos(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, &sampOffset, &chunkNumber, &descIndex, &isEdited);
					if (e) return e;
					e = stbl_GetSampleSize(curWriter->mdia->information->sampleTable->SampleSize, curWriter->sampleNumber, &sampSize);
					if (e) return e;
					
					//do we actually write, or do we emulate ?
					if (Emulation) {
						//update our offsets...
						if (Media_IsSelfContained(curWriter->mdia, descIndex) ) {
							e = stbl_SetChunkAndOffset(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, descIndex, curWriter->stsc, &curWriter->stco, offset, forceNewChunk);
							if (e) return e;
							offset += sampSize;
							mdatSize += sampSize;
						} else {
							if (curWriter->prev_offset != sampOffset) forceNewChunk = 1;
							curWriter->prev_offset = sampOffset + sampSize;

							//we have a DataRef, so use the offset idicated in sampleToChunk 
							//and ChunkOffset tables...
							e = stbl_SetChunkAndOffset(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, descIndex, curWriter->stsc, &curWriter->stco, sampOffset, forceNewChunk);
							if (e) return e;
						}
					} else {
						//this is no game, we're writing ....
						if (Media_IsSelfContained(curWriter->mdia, descIndex) ) {
							e = WriteSample(mw, sampSize, sampOffset, isEdited, bs);
							if (e) return e;
						}
					}
					//ok, the sample is done
					if (curWriter->sampleNumber == curWriter->mdia->information->sampleTable->SampleSize->sampleCount) {
						curWriter->isDone = 1;
						//one more track done...
						tracksDone ++;
						break;
					} else {
						curWriter->sampleNumber ++;
					}
				}
				/*record chunk end-time & track timescale for drift-controled interleaving*/
				if (drift_inter && curWriter) {
					chunkLastScale = curWriter->timeScale;
					chunkLastDTS = curWriter->DTSprev;
					/*add one interleave window drift - since the "maxDTS" is the previously written one, we will
					have the following cases:
					- sample doesn't fit: post-pone and force new chunk 
					- sample time larger than previous chunk time + interleave: post-pone and force new chunk
					- otherwise store and track becomes current reference

					this ensures a proper drift regulation (max DTS diff is less than the interleaving window)
					*/
					chunkLastDTS += curWriter->timeScale * movie->interleavingTime / movie->moov->mvhd->timeScale;
				}
			}
			//no sample found, we're done with this group
			if (!curWriter) {
				writeGroup = 0;
				continue;
			}
		}
		//if all our track are done, break
		if (tracksDone == gf_list_count(writers)) break;
		//go to next group
		curGroupID ++;
	}
	if (movie->mdat) movie->mdat->dataSize = mdatSize;
	return GF_OK;
}
Ejemplo n.º 8
0
GF_Err DoFullInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset)
{

	u32 i, tracksDone;
	TrackWriter *tmp, *curWriter, *prevWriter;
	GF_Err e;
	u64 DTS, DTStmp, TStmp;
	s64 res;
	u32 descIndex, sampSize, chunkNumber;
	u16 curGroupID, curTrackPriority;
	u8 forceNewChunk, writeGroup, isEdited;
	//this is used to emulate the write ...
	u64 offset, totSize, sampOffset;
	GF_ISOFile *movie = mw->movie;
	e = GF_OK;


	totSize = 0;
	curGroupID = 1;

	prevWriter = NULL;
	//we emulate a write from this offset...
	offset = StartOffset;
	writeGroup = 1;
	tracksDone = 0;

	
	//browse each groups
	while (1) {
		writeGroup = 1;

		//proceed a group
		while (writeGroup) {
			//first get the appropriated sample for the min time in this group
			curWriter = NULL;
			DTStmp = (u64) -1;
			TStmp = 0;
			curTrackPriority = (u16) -1;

			i=0;
			while ((tmp = (TrackWriter*)gf_list_enum(writers, &i))) {

				//is it done writing ?
				//is it in our group ??
				if (tmp->isDone || tmp->mdia->information->sampleTable->groupID != curGroupID) continue;

				//OK, get the current sample in this track
				stbl_GetSampleDTS(tmp->mdia->information->sampleTable->TimeToSample, tmp->sampleNumber, &DTS);				
				res = TStmp ? DTStmp * tmp->timeScale - DTS * TStmp : 0;
				if (res < 0) continue;
				if ((!res) && curTrackPriority <= tmp->mdia->information->sampleTable->trackPriority) continue;
				curWriter = tmp;
				curTrackPriority = tmp->mdia->information->sampleTable->trackPriority;
				DTStmp = DTS;
				TStmp = tmp->timeScale;
			}
			//no sample found, we're done with this group
			if (!curWriter) {
				//we're done with the group
				curTrackPriority = 0;
				writeGroup = 0;
				continue;
			}
			//To Check: are empty sample tables allowed ???
			if (curWriter->sampleNumber > curWriter->mdia->information->sampleTable->SampleSize->sampleCount) {
				curWriter->isDone = 1;
				tracksDone ++;
				continue;
			}

			e = stbl_GetSampleInfos(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, &sampOffset, &chunkNumber, &descIndex, &isEdited);
			if (e) return e;
			e = stbl_GetSampleSize(curWriter->mdia->information->sampleTable->SampleSize, curWriter->sampleNumber, &sampSize);
			if (e) return e;
			
			//do we actually write, or do we emulate ?
			if (Emulation) {
				//are we in the same track ??? If not, force a new chunk when adding this sample
				if (curWriter != prevWriter) {
					forceNewChunk = 1;
				} else {
					forceNewChunk = 0;
				}
				//update our offsets...
				if (Media_IsSelfContained(curWriter->mdia, descIndex) ) {
					e = stbl_SetChunkAndOffset(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, descIndex, curWriter->stsc, &curWriter->stco, offset, forceNewChunk);
					if (e) return e;
					offset += sampSize;
					totSize += sampSize;
				} else {
					if (curWriter->prev_offset != sampOffset) forceNewChunk = 1;
					curWriter->prev_offset = sampOffset + sampSize;

					//we have a DataRef, so use the offset idicated in sampleToChunk 
					//and ChunkOffset tables...
					e = stbl_SetChunkAndOffset(curWriter->mdia->information->sampleTable, curWriter->sampleNumber, descIndex, curWriter->stsc, &curWriter->stco, sampOffset, 0);
					if (e) return e;
				}
			} else {
				//this is no game, we're writing ....
				if (Media_IsSelfContained(curWriter->mdia, descIndex) ) {
					e = WriteSample(mw, sampSize, sampOffset, isEdited, bs);
					if (e) return e;
				}
			}
			//ok, the sample is done
			if (curWriter->sampleNumber == curWriter->mdia->information->sampleTable->SampleSize->sampleCount) {
				curWriter->isDone = 1;
				//one more track done...
				tracksDone ++;
			} else {
				curWriter->sampleNumber ++;
			}
			prevWriter = curWriter;
		}
		//if all our track are done, break
		if (tracksDone == gf_list_count(writers)) break;
		//go to next group
		curGroupID ++;
	}
	movie->mdat->dataSize = totSize;
	return GF_OK;
}
Ejemplo n.º 9
0
//this function writes track by track in the order of tracks inside the moov...
GF_Err DoWrite(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset)
{
	u32 i;
	GF_Err e;
	TrackWriter *writer;
	u64 offset, sampOffset, predOffset;
	u32 chunkNumber, descIndex, sampSize;
	u8 isEdited, force;
	u64 size, mdatSize = 0;
	GF_ISOFile *movie = mw->movie;

	/*write meta content first - WE DON'T support fragmentation of resources in ISOM atm*/
	if (movie->openMode != GF_ISOM_OPEN_WRITE) {
		if (movie->meta) {
			e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);
			if (e) return e;
			mdatSize += size;
			StartOffset += size;
		}
		if (movie->moov && movie->moov->meta) {
			e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);
			if (e) return e;
			mdatSize += size;
			StartOffset += size;
		}
		i=0;
		while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {
			if (writer->mdia->mediaTrack->meta) {
				e = DoWriteMeta(movie, movie->meta, bs, Emulation, StartOffset, &size);
				if (e) return e;
				mdatSize += size;
				StartOffset += size;
			}
		}
	}

	offset = StartOffset;
	predOffset = 0;
	i=0;
	while ((writer = (TrackWriter*)gf_list_enum(writers, &i))) {
		while (!writer->isDone) {
			//To Check: are empty sample tables allowed ???
			if (writer->sampleNumber > writer->mdia->information->sampleTable->SampleSize->sampleCount) {
				writer->isDone = 1;
				continue;
			}
			e = stbl_GetSampleInfos(writer->mdia->information->sampleTable, writer->sampleNumber, &sampOffset, &chunkNumber, &descIndex, &isEdited);
			if (e) return e;
			e = stbl_GetSampleSize(writer->mdia->information->sampleTable->SampleSize, writer->sampleNumber, &sampSize);
			if (e) return e;

			//update our chunks. 
			force = 0;
			if (movie->openMode == GF_ISOM_OPEN_WRITE) {
				offset = sampOffset;
				if (predOffset != offset) 
					force = 1;
			}
			//update our global offset...
			if (Media_IsSelfContained(writer->mdia, descIndex) ) {
				e = stbl_SetChunkAndOffset(writer->mdia->information->sampleTable, writer->sampleNumber, descIndex, writer->stsc, &writer->stco, offset, force);
				if (e) return e;
				if (movie->openMode == GF_ISOM_OPEN_WRITE) {
					predOffset = sampOffset + sampSize;
				} else {
					offset += sampSize;
					mdatSize += sampSize;
				}
			} else {
				if (predOffset != offset) force = 1;
				predOffset = sampOffset + sampSize;
				//we have a DataRef, so use the offset idicated in sampleToChunk and ChunkOffset tables...
				e = stbl_SetChunkAndOffset(writer->mdia->information->sampleTable, writer->sampleNumber, descIndex, writer->stsc, &writer->stco, sampOffset, force);
				if (e) return e;
			}
			//we write the sample if not emulation
			if (!Emulation) {
				if (Media_IsSelfContained(writer->mdia, descIndex) ) {
					e = WriteSample(mw, sampSize, sampOffset, isEdited, bs);
					if (e) return e;
				}
			}
			//ok, the track is done
			if (writer->sampleNumber == writer->mdia->information->sampleTable->SampleSize->sampleCount) {
				writer->isDone = 1;
			} else {
				writer->sampleNumber ++;
			}
		}
	}
	//set the mdatSize...
	movie->mdat->dataSize = mdatSize;
	return GF_OK;
}
Ejemplo n.º 10
0
bool module_renderer::SaveITProject(LPCSTR lpszFileName)
//-------------------------------------------------
{
    // Check song type

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

    UINT i,j = 0;
    for(i = 0 ; i < m_nInstruments ; i++) { if(m_szInstrumentPath[i][0] != '\0' || !Instruments[i+1]) j++; }
    if(m_nInstruments && j != m_nInstruments) return false;

    // Open file

    FILE *f;

    if((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return false;


    // File ID

    uint32_t id = ITP_FILE_ID;
    fwrite(&id, 1, sizeof(id), f);

    id = ITP_VERSION;
    fwrite(&id, 1, sizeof(id), f);

    // Song name

    // name string length
    id = 27;
    fwrite(&id, 1, sizeof(id), f);

    // song name
    char namebuf[27];
    copy_with_padding(namebuf, 27, this->song_name);
    fwrite(namebuf, 1, 27, f);

    // Song comments

    // comment string length
    id = m_lpszSongComments ? strlen(m_lpszSongComments)+1 : 0;
    fwrite(&id, 1, sizeof(id), f);

    // comment string
    if(m_lpszSongComments) fwrite(&m_lpszSongComments[0], 1, strlen(m_lpszSongComments)+1, f);

    // Song global config

    id = (m_dwSongFlags & SONG_FILE_FLAGS);
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultGlobalVolume;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nSamplePreAmp;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultSpeed;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultTempo;
    fwrite(&id, 1, sizeof(id), f);

    // Song channels data

    // number of channels
    id = m_nChannels;
    fwrite(&id, 1, sizeof(id), f);

    // channel name string length
    id = MAX_CHANNELNAME;
    fwrite(&id, 1, sizeof(id), f);

    // channel config data
    for(i=0; i<m_nChannels; i++){
        id = ChnSettings[i].nPan;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].dwFlags;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].nVolume;
        fwrite(&id, 1, sizeof(id), f);
        fwrite(&ChnSettings[i].szName[0], 1, MAX_CHANNELNAME, f);
    }

    // Song mix plugins

    // mix plugins data length
    id = SaveMixPlugins(NULL, TRUE);
    fwrite(&id, 1, sizeof(id), f);

    // mix plugins data
    SaveMixPlugins(f, FALSE);

    // Song midi config

    // midi cfg data length
    id = sizeof(MODMIDICFG);
    fwrite(&id, 1, sizeof(id), f);

    // midi cfg
    fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f);

    // Song Instruments

    // number of instruments
    id = m_nInstruments;
    fwrite(&id, 1, sizeof(id), f);

    // path name string length
    id = _MAX_PATH;
    fwrite(&id, 1, sizeof(id), f);

    // instruments' path
    for(i=0; i<m_nInstruments; i++) fwrite(&m_szInstrumentPath[i][0], 1, _MAX_PATH, f);

    // Song Orders

    // order array size
    id = Order.size();
    fwrite(&id, 1, sizeof(id), f);

    // order array
    Order.WriteAsByte(f, id);

    // Song Patterns

    // number of patterns
    id = MAX_PATTERNS;
    fwrite(&id, 1, sizeof(id), f);

    // number of pattern name strings
    modplug::tracker::patternindex_t numNamedPats = Patterns.GetNumNamedPatterns();
    numNamedPats = bad_min(numNamedPats, MAX_PATTERNS);
    id = numNamedPats;
    fwrite(&id, 1, sizeof(id), f);

    // length of a pattern name string
    id = MAX_PATTERNNAME;
    fwrite(&id, 1, sizeof(id), f);
    // pattern name string
    for(modplug::tracker::patternindex_t nPat = 0; nPat < numNamedPats; nPat++)
    {
        char name[MAX_PATTERNNAME];
        MemsetZero(name);
        Patterns[nPat].GetName(name, MAX_PATTERNNAME);
        fwrite(name, 1, MAX_PATTERNNAME, f);
    }

    // modcommand data length
    id = sizeof(modplug::tracker::modevent_t);
    fwrite(&id, 1, sizeof(id), f);

    // patterns data content
    for(UINT npat=0; npat<MAX_PATTERNS; npat++){
        // pattern size (number of rows)
        id = Patterns[npat] ? Patterns[npat].GetNumRows() : 0;
        fwrite(&id, 1, sizeof(id), f);
        // pattern data
        if(Patterns[npat] && Patterns[npat].GetNumRows()) Patterns[npat].WriteITPdata(f);
        //fwrite(Patterns[npat], 1, m_nChannels * Patterns[npat].GetNumRows() * sizeof(modplug::tracker::modcommand_t), f);
    }

    // Song lonely (instrument-less) samples

    // Write original number of samples
    id = m_nSamples;
    fwrite(&id, 1, sizeof(id), f);

    vector<bool> sampleUsed(m_nSamples, false);

    // Mark samples used in instruments
    for(i=0; i<m_nInstruments; i++)
    {
        if(Instruments[i + 1] != nullptr)
        {
            modinstrument_t *p = Instruments[i + 1];
            for(j = 0; j < 128; j++)
            {
                if(p->Keyboard[j] > 0 && p->Keyboard[j] <= m_nSamples)
                    sampleUsed[p->Keyboard[j] - 1] = true;
            }
        }
    }

    // Count samples not used in any instrument
    i = 0;
    for(j = 1; j <= m_nSamples; j++)
        if(!sampleUsed[j - 1] && Samples[j].sample_data) i++;

    id = i;
    fwrite(&id, 1, sizeof(id), f);

    // Write samples not used in any instrument (help, this looks like duplicate code!)
    ITSAMPLESTRUCT itss;
    for(UINT nsmp=1; nsmp<=m_nSamples; nsmp++)
    {
        if(!sampleUsed[nsmp - 1] && Samples[nsmp].sample_data)
        {

            modsample_t *psmp = &Samples[nsmp];
            memset(&itss, 0, sizeof(itss));
            memcpy(itss.filename, psmp->legacy_filename, 12);
            memcpy(itss.name, m_szNames[nsmp], 26);

            itss.id = LittleEndian(IT_IMPS);
            itss.gvl = (uint8_t)psmp->global_volume;
            itss.flags = 0x00;

            if(psmp->flags & CHN_LOOP) itss.flags |= 0x10;
            if(psmp->flags & CHN_SUSTAINLOOP) itss.flags |= 0x20;
            if(psmp->flags & CHN_PINGPONGLOOP) itss.flags |= 0x40;
            if(psmp->flags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80;
            itss.C5Speed = psmp->c5_samplerate;
            if (!itss.C5Speed) itss.C5Speed = 8363;
            itss.length = psmp->length;
            itss.loopbegin = psmp->loop_start;
            itss.loopend = psmp->loop_end;
            itss.susloopbegin = psmp->sustain_start;
            itss.susloopend = psmp->sustain_end;
            itss.vol = (uint8_t)(psmp->default_volume >> 2);
            itss.dfp = (uint8_t)(psmp->default_pan >> 2);
            itss.vit = autovibxm2it[psmp->vibrato_type & 7];
            itss.vis = bad_min(psmp->vibrato_rate, 64);
            itss.vid = bad_min(psmp->vibrato_depth, 32);
            itss.vir = bad_min(psmp->vibrato_sweep, 255); //(psmp->vibrato_sweep < 64) ? psmp->vibrato_sweep * 4 : 255;
            if (psmp->flags & CHN_PANNING) itss.dfp |= 0x80;
            if ((psmp->sample_data) && (psmp->length)) itss.cvt = 0x01;
            UINT flags = RS_PCM8S;

            if(psmp->flags & CHN_STEREO)
            {
                flags = RS_STPCM8S;
                itss.flags |= 0x04;
            }
            if(psmp->flags & CHN_16BIT)
            {
                itss.flags |= 0x02;
                flags = (psmp->flags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
            }

            id = nsmp;
            fwrite(&id, 1, sizeof(id), f);

            itss.samplepointer = NULL;
            fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);

            id = WriteSample(NULL, psmp, flags);
            fwrite(&id, 1, sizeof(id), f);
            WriteSample(f, psmp, flags);
        }
    }
Ejemplo n.º 11
0
void MP4File::MakeIsmaCompliant(bool addIsmaComplianceSdp)
{
    ProtectWriteOperation("MP4MakeIsmaCompliant");

    if (m_useIsma) {
        // already done
        return;
    }
    m_useIsma = true;

    // find first audio and/or video tracks

    MP4TrackId audioTrackId = MP4_INVALID_TRACK_ID;
    try {
        audioTrackId = FindTrackId(0, MP4_AUDIO_TRACK_TYPE);
    }
    catch (MP4Error* e) {
        delete e;
    }

    MP4TrackId videoTrackId = MP4_INVALID_TRACK_ID;
    try {
        videoTrackId = FindTrackId(0, MP4_VIDEO_TRACK_TYPE);
    }
    catch (MP4Error* e) {
        delete e;
    }

    u_int64_t fileMsDuration =
        ConvertFromMovieDuration(GetDuration(), MP4_MSECS_TIME_SCALE);

    // delete any existing OD track
    if (m_odTrackId != MP4_INVALID_TRACK_ID) {
        DeleteTrack(m_odTrackId);
    }

    AddODTrack();
    SetODProfileLevel(0xFF);

    if (audioTrackId != MP4_INVALID_TRACK_ID) {
        AddTrackToOd(audioTrackId);
    }

    if (videoTrackId != MP4_INVALID_TRACK_ID) {
        AddTrackToOd(videoTrackId);
    }

    // delete any existing scene track
    MP4TrackId sceneTrackId = MP4_INVALID_TRACK_ID;
    try {
        sceneTrackId = FindTrackId(0, MP4_SCENE_TRACK_TYPE);
    }
    catch (MP4Error *e) {
        delete e;
    }
    if (sceneTrackId != MP4_INVALID_TRACK_ID) {
        DeleteTrack(sceneTrackId);
    }

    // add scene track
    sceneTrackId = AddSceneTrack();
    SetSceneProfileLevel(0xFF);
    SetGraphicsProfileLevel(0xFF);
    SetTrackIntegerProperty(sceneTrackId,
                            "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId",
                            MP4SystemsV2ObjectType);

    SetTrackESConfiguration(sceneTrackId,
                            BifsV2Config, sizeof(BifsV2Config));

    u_int8_t* pBytes = NULL;
    u_int64_t numBytes = 0;

    // write OD Update Command
    CreateIsmaODUpdateCommandFromFileForFile(
        m_odTrackId,
        audioTrackId,
        videoTrackId,
        &pBytes,
        &numBytes);

    WriteSample(m_odTrackId, pBytes, numBytes, fileMsDuration);

    MP4Free(pBytes);
    pBytes = NULL;

    // write BIFS Scene Replace Command
    CreateIsmaSceneCommand(
        MP4_IS_VALID_TRACK_ID(audioTrackId),
        MP4_IS_VALID_TRACK_ID(videoTrackId),
        &pBytes,
        &numBytes);

    WriteSample(sceneTrackId, pBytes, numBytes, fileMsDuration);

    MP4Free(pBytes);
    pBytes = NULL;

    // add session level sdp
    CreateIsmaIodFromFile(
        m_odTrackId,
        sceneTrackId,
        audioTrackId,
        videoTrackId,
        &pBytes,
        &numBytes);

    char* iodBase64 = MP4ToBase64(pBytes, numBytes);

    char* sdpBuf = (char*)MP4Calloc(strlen(iodBase64) + 256);

    if (addIsmaComplianceSdp) {
        strcpy(sdpBuf, "a=isma-compliance:1,1.0,1\015\012");
    }

    sprintf(&sdpBuf[strlen(sdpBuf)],
            "a=mpeg4-iod: \042data:application/mpeg4-iod;base64,%s\042\015\012",
            iodBase64);

    SetSessionSdp(sdpBuf);

    VERBOSE_ISMA(GetVerbosity(),
                 printf("IOD SDP = %s\n", sdpBuf));

    MP4Free(iodBase64);
    iodBase64 = NULL;
    MP4Free(pBytes);
    pBytes = NULL;
    MP4Free(sdpBuf);
    sdpBuf = NULL;
}