示例#1
0
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
    }
}
示例#2
0
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;
}
示例#3
0
文件: t_rawseg.c 项目: 8l/vlink
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);
          }
        }
      }
    }
  }
}