Beispiel #1
0
node newtmp(node ttype, scope v, bool decl){
     node tmpsymb;
     assert(ttype != returns_T && ttype != exits_T);
     tmpsymb = newsymbol(tmp__S,totype(ttype),NULL,
	  intern_F|tmp_F|defined_F|literal_F);
     if (decl) push(v->tmpdecls,list(2,declare__S,tmpsymb));
     return tmpsymb;
     }
Beispiel #2
0
node newstmp(node ttype, scope v, bool decl){
     node tmpsymb;
     static int count = 0;
     char buf[20];
     tmpsymb = newsymbol(tmp__S,totype(ttype),NULL, intern_F|defined_F|tmp_F);
     sprintf(buf,"stmp%d_",count++);
     tmpsymb->body.symbol.Cname = strperm(buf);
     if (decl) push(v->tmpdecls,list(2,declare__S,tmpsymb));
     return tmpsymb;
     }
Beispiel #3
0
static int typeseqno(node t){
     assert(istype(t));
     return totype(t)->body.type.seqno;
     }
Beispiel #4
0
node type(node e){		/* assume e is checked previously */
     /* this returns a unique TYPE */
     if (e == NULL) return void_T;
     again:
     switch(e->tag) {
	  case position_tag: e = e->body.position.contents; goto again;
	  case symbol_tag: return e->body.symbol.type;
     	  case string_const_tag: /* not implemented yet */ return bad_or_undefined_T;
     	  case char_const_tag: return char_T;
     	  case int_const_tag: return int_T;
     	  case double_const_tag: return double_T;
     	  case string_tag: assert(FALSE); 
     	  case unique_string_tag: assert(FALSE); /* was return bad_or_undefined_T; */
	  case cons_tag: {
	       node h, ht;
     	       h = unpos(CAR(e));
	       if (h->tag == unique_string_tag) {
		    if (h == equalequal__S || h == unequal_S) return bool_T;
		    if (h == cast__S) {
			 assert(istype(CADR(e)));
			 return cadr(e);
			 }
		    if (h == function_S) return type__T;
		    if (h == funcall__S || h == prefix__S || h == infix__S) {
			 return functionrettype(type(CADR(e)));
			 }
		    if (h == take__S) {
			 return membertype(type(CADR(e)),CADDR(e));
			 }
		    if (h == array_take_S) {
			 return arrayElementType(type(CADR(e)));
			 }
		    if (h == return_S) return returns_T;
		    if (h == exits_S) return exits_T;
		    if (h == Ccode_S) return cadr(e);
		    assert(FALSE);
		    }
	       ht = type(h);
	       if (ht == type__T) return totype(h);
	       if (ht == keyword_T) {
		    node w = ispos(h) ? h->body.position.contents : h;
		    if (w == block__K) return void_T;
     	       	    if (w == blockn__K) {
			 if (length(e) < 2) return void_T;
			 return type(last(e));
			 }
		    if ( w == object__K || w == tagged_object_K || w == array_K || w == tarray_K || w == or_K) {
			 return type__T;
			 }
		    if (w == label__S) return void_T;
		    if (w == goto__S) return void_T;
		    assert(FALSE); /* there must be some other keywords! */
		    }
	       ht = ht->body.type.definition;
	       if (iscons(ht)) {
		    if (equal(CAR(ht),function_S)) {
			 assert(FALSE);
		    	 return caddr(ht);
			 }
		    else assert(FALSE); return NULL;
		    }
	       assert(FALSE); return NULL;
	       }
	  case type_tag: return type__T;
	  }
     assert(FALSE);
     return NULL;
     }
//   as determined by the values you specify for fromchannels and tochannels.
//   however, it is recommended the mixing destination buffer always be stereo, for quality reasons.
// PANNING AND VOLUME ADJUSTMENT:
//   the cached volume levels given are applied to the source audio when mixing.
//   this automatically includes panning, which applies for every case except (mono to mono) conversion.
// CLIPPING:
//   values exceeding the bounds of the destination bitrate will be clamped to within the valid range.
// INTERPOLATION:
//   this performs linear interpolation of samples.
//   some games would sound very noticeably wrong otherwise.
template<typename fromtype, typename totype, int fromchannels, int tochannels>
static void Mix(const unsigned char*__restrict buf, unsigned char*__restrict outbuf, DWORD size, DWORD outSize, bool sizeReachesBufferEnd, Hooks::DirectSound::CachedVolumeAndPan& volumes)
{
	enum { fromshift = (2+sizeof(fromtype)-sizeof(totype))<<3 }; // 16 when both buffers have the same bit/sample... this is for combining differing bitrates
	enum { maxto = (1<<(8*sizeof(totype)-1))-1 }; // clamping magnitude (127 or 32767)
	enum { tosignoffset = (totype(-1)<0)?0:-(1<<(8*sizeof(totype)-1)) }; // add this to make numbers in the "to" buffer signed
	enum { fromsignoffset = (fromtype(-1)<0)?0:-(1<<(8*sizeof(fromtype)-1)) }; // add this to make numbers in the "from" buffer signed
	enum { toincrement = sizeof(totype) * tochannels };
	enum { fromincrement = sizeof(fromtype) * fromchannels };
	
	DWORD frac = 0; // amount of next sample to use, out of 1024 (for linear interpolation)
	DWORD fracnumer = (size*(toincrement<<10));
	DWORD fracincrement = fracnumer / outSize;
	// unfortunately needs to be very exact (can't drift even by 1 or clicking becomes audible), so we also need:
	DWORD fracErrorIncrement = fracnumer % outSize;
	DWORD fracError = 0;

	DWORD offsetRemainder = 0;
	DWORD inOffset = 0;
	for(DWORD i = 0; i < outSize; outbuf += toincrement, i += toincrement)
	{