static void wave_stop_playback(ALCdevice *device) { wave_data *data = (wave_data*)device->ExtraData; ALuint dataLen; long size; if(!data->thread) return; data->killNow = 1; StopThread(data->thread); data->thread = NULL; data->killNow = 0; alFree(data->buffer); data->buffer = NULL; size = ftell(data->f); if(size > 0) { dataLen = size - data->DataStart; if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0) fwrite32le(dataLen, data->f); // 'data' header len if(fseek(data->f, 4, SEEK_SET) == 0) fwrite32le(size-8, data->f); // 'WAVE' header len } }
static ALCboolean wave_reset_playback(ALCdevice *device) { wave_data *data = (wave_data*)device->ExtraData; ALuint channels=0, bits=0; size_t val; fseek(data->f, 0, SEEK_SET); clearerr(data->f); switch(device->FmtType) { case DevFmtByte: device->FmtType = DevFmtUByte; break; case DevFmtUShort: device->FmtType = DevFmtShort; break; case DevFmtUByte: case DevFmtShort: case DevFmtFloat: break; } bits = BytesFromDevFmt(device->FmtType) * 8; channels = ChannelsFromDevFmt(device->FmtChans); fprintf(data->f, "RIFF"); fwrite32le(0xFFFFFFFF, data->f); // 'RIFF' header len; filled in at close fprintf(data->f, "WAVE"); fprintf(data->f, "fmt "); fwrite32le(40, data->f); // 'fmt ' header len; 40 bytes for EXTENSIBLE // 16-bit val, format type id (extensible: 0xFFFE) fwrite16le(0xFFFE, data->f); // 16-bit val, channel count fwrite16le(channels, data->f); // 32-bit val, frequency fwrite32le(device->Frequency, data->f); // 32-bit val, bytes per second fwrite32le(device->Frequency * channels * bits / 8, data->f); // 16-bit val, frame size fwrite16le(channels * bits / 8, data->f); // 16-bit val, bits per sample fwrite16le(bits, data->f); // 16-bit val, extra byte count fwrite16le(22, data->f); // 16-bit val, valid bits per sample fwrite16le(bits, data->f); // 32-bit val, channel mask fwrite32le(channel_masks[channels], data->f); // 16 byte GUID, sub-type format val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f); fprintf(data->f, "data"); fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close if(ferror(data->f)) { AL_PRINT("Error writing header: %s\n", strerror(errno)); return ALC_FALSE; } data->DataStart = ftell(data->f); data->size = device->UpdateSize * channels * bits / 8; data->buffer = alMalloc(data->size); if(!data->buffer) { AL_PRINT("buffer malloc failed\n"); return ALC_FALSE; } SetDefaultWFXChannelOrder(device); data->thread = StartThread(WaveProc, device); if(data->thread == NULL) { alFree(data->buffer); data->buffer = NULL; return ALC_FALSE; } return ALC_TRUE; }
static void rawseg_writeexec(struct GlobalVars *gv,FILE *f) /* creates a new file for each segment, writes file name, start address */ /* and length into the output file */ { const char *fn = "rawseg_writeexec(): "; bool firstsec; unsigned long addr; FILE *segf; struct Phdr *p; struct LinkedSection *ls,*prevls; struct SegReloc *srlist; char buf[256]; for (p=gv->phdrlist; p; p=p->next) { if (p->type==PT_LOAD && (p->flags&PHDR_USED) && p->start!=ADDR_NONE && p->start_vma!=ADDR_NONE) { firstsec = TRUE; srlist = NULL; snprintf(buf,256,"%s.%s",gv->dest_name,p->name); segf = fopen(buf,"wb"); if (segf == NULL) { error(29,buf); /* cannot create file */ continue; } /* write file name, start address and length of segment to output */ fprintf(f,"\"%s\" 0x%llx 0x%llx\n",buf,p->start,p->mem_end-p->start); /* write segment's sections */ for (ls=(struct LinkedSection *)gv->lnksec.first; ls->n.next!=NULL; ls=(struct LinkedSection *)ls->n.next) { if (ls->copybase>=(unsigned long)p->start && (ls->copybase+ls->size)<=(unsigned long)p->mem_end && (ls->flags & SF_ALLOC)) { if (gv->keep_relocs) { /* remember relocations, adjusted from section to segment base */ struct Reloc *r; struct RelocInsert *ri; struct LinkedSection *relsec; struct Phdr *relph; for (r=(struct Reloc *)ls->relocs.first; r->n.next!=NULL; r=(struct Reloc *)r->n.next) { if (ri = r->insert) { if (r->rtype!=R_ABS || ri->bpos!=0 || ri->bsiz!=32) { /* only absolute 32-bit relocs are supported */ error(32,fff_rawseg.tname,reloc_name[r->rtype], (int)ri->bpos,(int)ri->bsiz,ri->mask, ls->name,r->offset); continue; } } else continue; if (r->relocsect.lnk == NULL) { if (r->flags & RELF_DYNLINK) continue; /* NULL, because it was resolved by a sh.obj. */ else ierror("%sReloc type %d (%s) at %s+0x%lx " "(addend 0x%llx) is missing a relocsect.lnk", fn,(int)r->rtype,reloc_name[r->rtype],ls->name, r->offset,r->addend); } relsec = r->relocsect.lnk; /* find out to which segment relsec belongs */ for (relph=gv->phdrlist; relph; relph=relph->next) { if (relph->type==PT_LOAD && (relph->flags&PHDR_USED) && relph->start!=ADDR_NONE && relph->start_vma!=ADDR_NONE) { if (relsec->copybase>=(unsigned long)relph->start && (relsec->copybase+relsec->size)<= (unsigned long)relph->mem_end && (relsec->flags & SF_ALLOC)) break; } } /* use segment's base address for relocation instead */ if (relph) { lword segoffs,a,v; struct SegReloc *newsr,*srp; segoffs = (lword)relsec->copybase - relph->start; v = writesection(gv,ls->data+r->offset,r,r->addend+segoffs); if (v != 0) { /* Calculated value doesn't fit into relocation type x ... */ if (ri = r->insert) error(35,gv->dest_name,ls->name,r->offset,v, reloc_name[r->rtype],(int)ri->bpos, (int)ri->bsiz,ri->mask); else ierror("%sReloc (%s+%lx), type=%s, without RelocInsert", fn,ls->name,r->offset,reloc_name[r->rtype]); } /* remember relocation offset and segment for later */ newsr = alloc(sizeof(struct SegReloc)); newsr->next = NULL; newsr->seg = relph; newsr->offset = (ls->copybase - (unsigned long)p->start) + r->offset; if (srp = srlist) { while (srp->next) srp = srp->next; srp->next = newsr; } else srlist = newsr; } else ierror("%sNo segment for reloc offset section '%s'", fn,relsec->name); } } else calc_relocs(gv,ls); if (!firstsec) { /* write an alignment gap, when needed */ if (ls->copybase > addr) fwritegap(segf,ls->copybase-addr); else if (ls->copybase < addr) error(98,fff[gv->dest_format]->tname,ls->name,prevls->name); } else firstsec = FALSE; fwritex(segf,ls->data,ls->size); addr = ls->copybase + ls->size; prevls = ls; } } fclose(segf); if (srlist) { /* write relocation files for this segment */ struct Phdr *relph; struct SegReloc *sr; uint32_t rcnt; FILE *rf; for (relph=gv->phdrlist; relph; relph=relph->next) { for (sr=srlist,rf=NULL,rcnt=0; sr; sr=sr->next) { if (sr->seg == relph) { if (!rf) { snprintf(buf,256,"%s.%s.rel%s", gv->dest_name,p->name,relph->name); rf = fopen(buf,"wb"); if (rf == NULL) { error(29,buf); /* cannot create file */ continue; } fwritegap(rf,4); /* number of relocs will be stored here */ } if (gv->endianess == _BIG_ENDIAN_) fwrite32be(rf,sr->offset); else fwrite32le(rf,sr->offset); rcnt++; } } if (rf) { /* write number of relocs into the first word */ fseek(rf,0,SEEK_SET); if (gv->endianess == _BIG_ENDIAN_) fwrite32be(rf,rcnt); else fwrite32le(rf,rcnt); fclose(rf); } } } } } }