AUpvlist _af_pv_pointer (void *val) { AUpvlist ret = AUpvnew(1); AUpvsetparam(ret, 0, 0); AUpvsetvaltype(ret, 0, AU_PVTYPE_PTR); AUpvsetval(ret, 0, &val); return ret; }
AUpvlist _af_pv_double (double val) { AUpvlist ret = AUpvnew(1); AUpvsetparam(ret, 0, 0); AUpvsetvaltype(ret, 0, AU_PVTYPE_DOUBLE); AUpvsetval(ret, 0, &val); return ret; }
AUpvlist _af_pv_long (long val) { AUpvlist ret = AUpvnew(1); AUpvsetparam(ret, 0, 0); AUpvsetvaltype(ret, 0, AU_PVTYPE_LONG); AUpvsetval(ret, 0, &val); return ret; }
/* This routine gets instrument parameters. npv is number of valid AUpvlist pairs */ void _af_instparam_get (AFfilehandle file, int instid, AUpvlist pvlist, int npv, bool forceLong) { int i, instno, j; if (!_af_filehandle_ok(file)) return; if ((instno = _af_handle_instrument_index_from_id(file, instid)) == -1) return; if (AUpvgetmaxitems(pvlist) < npv) npv = AUpvgetmaxitems(pvlist); for (i=0; i < npv; i++) { int param; int type; AUpvgetparam(pvlist, i, ¶m); if ((j = _af_instparam_index_from_id(file->fileFormat, param)) == -1) /* no parameter with that id; ignore */ continue; type = _af_units[file->fileFormat].instrumentParameters[j].type; /* forceLong is true when this routine called by afGetInstParamLong(). */ if (forceLong && type != AU_PVTYPE_LONG) { _af_error(AF_BAD_INSTPTYPE, "type of instrument parameter %d is not AU_PVTYPE_LONG", param); continue; } AUpvsetvaltype(pvlist, i, type); switch (type) { case AU_PVTYPE_LONG: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].l); break; case AU_PVTYPE_DOUBLE: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].d); break; case AU_PVTYPE_PTR: AUpvsetval(pvlist, i, &file->instruments[instno].values[j].v); break; default: _af_error(AF_BAD_INSTPTYPE, "invalid instrument parameter type %d", type); return; } } }
void afSetInstParamLong (AFfilehandle file, int instid, int param, long value) { AUpvlist pvlist = AUpvnew(1); AUpvsetparam(pvlist, 0, param); AUpvsetvaltype(pvlist, 0, AU_PVTYPE_LONG); AUpvsetval(pvlist, 0, &value); _af_instparam_set(file, instid, pvlist, 1); AUpvfree(pvlist); }
void CAFFile::initIMACompressionParams() { Track *track = getTrack(); track->f.bytesPerPacket = 34 * track->f.channelCount; track->f.framesPerPacket = 64; AUpvlist pv = AUpvnew(1); AUpvsetparam(pv, 0, _AF_IMA_ADPCM_TYPE); AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG); long l = _AF_IMA_ADPCM_TYPE_QT; AUpvsetval(pv, 0, &l); track->f.compressionParams = pv; }
long afGetInstParamLong (AFfilehandle file, int inst, int param) { long val; AUpvlist pvlist = AUpvnew(1); AUpvsetparam(pvlist, 0, param); AUpvsetvaltype(pvlist, 0, AU_PVTYPE_LONG); _af_instparam_get(file, inst, pvlist, 1, true); AUpvgetval(pvlist, 0, &val); AUpvfree(pvlist); return(val); }
status WAVEFile::parseFormat(const Tag &id, uint32_t size) { Track *track = getTrack(); uint16_t formatTag; readU16(&formatTag); uint16_t channelCount; readU16(&channelCount); uint32_t sampleRate; readU32(&sampleRate); uint32_t averageBytesPerSecond; readU32(&averageBytesPerSecond); uint16_t blockAlign; readU16(&blockAlign); track->f.channelCount = channelCount; track->f.sampleRate = sampleRate; track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN; /* Default to uncompressed audio data. */ track->f.compressionType = AF_COMPRESSION_NONE; switch (formatTag) { case WAVE_FORMAT_PCM: { uint16_t bitsPerSample; readU16(&bitsPerSample); track->f.sampleWidth = bitsPerSample; if (bitsPerSample == 0 || bitsPerSample > 32) { _af_error(AF_BAD_WIDTH, "bad sample width of %d bits", bitsPerSample); return AF_FAIL; } if (bitsPerSample <= 8) track->f.sampleFormat = AF_SAMPFMT_UNSIGNED; else track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; } break; case WAVE_FORMAT_MULAW: case IBM_FORMAT_MULAW: track->f.sampleWidth = 16; track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; track->f.byteOrder = _AF_BYTEORDER_NATIVE; track->f.compressionType = AF_COMPRESSION_G711_ULAW; break; case WAVE_FORMAT_ALAW: case IBM_FORMAT_ALAW: track->f.sampleWidth = 16; track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; track->f.byteOrder = _AF_BYTEORDER_NATIVE; track->f.compressionType = AF_COMPRESSION_G711_ALAW; break; case WAVE_FORMAT_IEEE_FLOAT: { uint16_t bitsPerSample; readU16(&bitsPerSample); if (bitsPerSample == 64) { track->f.sampleWidth = 64; track->f.sampleFormat = AF_SAMPFMT_DOUBLE; } else { track->f.sampleWidth = 32; track->f.sampleFormat = AF_SAMPFMT_FLOAT; } } break; case WAVE_FORMAT_ADPCM: { uint16_t bitsPerSample, extraByteCount, samplesPerBlock, numCoefficients; if (track->f.channelCount != 1 && track->f.channelCount != 2) { _af_error(AF_BAD_CHANNELS, "WAVE file with MS ADPCM compression " "must have 1 or 2 channels"); } readU16(&bitsPerSample); readU16(&extraByteCount); readU16(&samplesPerBlock); readU16(&numCoefficients); /* numCoefficients should be at least 7. */ assert(numCoefficients >= 7 && numCoefficients <= 255); for (int i=0; i<numCoefficients; i++) { int16_t a0, a1; readS16(&a0); readS16(&a1); msadpcmCoefficients[i][0] = a0; msadpcmCoefficients[i][1] = a1; } track->f.sampleWidth = 16; track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; track->f.compressionType = AF_COMPRESSION_MS_ADPCM; track->f.byteOrder = _AF_BYTEORDER_NATIVE; /* Create the parameter list. */ long l; void *v; AUpvlist pv = AUpvnew(4); AUpvsetparam(pv, 0, _AF_MS_ADPCM_NUM_COEFFICIENTS); AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG); l = numCoefficients; AUpvsetval(pv, 0, &l); AUpvsetparam(pv, 1, _AF_MS_ADPCM_COEFFICIENTS); AUpvsetvaltype(pv, 1, AU_PVTYPE_PTR); v = msadpcmCoefficients; AUpvsetval(pv, 1, &v); AUpvsetparam(pv, 2, _AF_FRAMES_PER_BLOCK); AUpvsetvaltype(pv, 2, AU_PVTYPE_LONG); l = samplesPerBlock; AUpvsetval(pv, 2, &l); AUpvsetparam(pv, 3, _AF_BLOCK_SIZE); AUpvsetvaltype(pv, 3, AU_PVTYPE_LONG); l = blockAlign; AUpvsetval(pv, 3, &l); track->f.compressionParams = pv; } break; case WAVE_FORMAT_DVI_ADPCM: { uint16_t bitsPerSample, extraByteCount, samplesPerBlock; readU16(&bitsPerSample); readU16(&extraByteCount); readU16(&samplesPerBlock); if (bitsPerSample != 4) { _af_error(AF_BAD_NOT_IMPLEMENTED, "IMA ADPCM compression supports only 4 bits per sample"); } int bytesPerBlock = (samplesPerBlock + 14) / 8 * 4 * channelCount; if (bytesPerBlock > blockAlign || (samplesPerBlock % 8) != 1) { _af_error(AF_BAD_CODEC_CONFIG, "Invalid samples per block for IMA ADPCM compression"); } track->f.sampleWidth = 16; track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; track->f.compressionType = AF_COMPRESSION_IMA; track->f.byteOrder = _AF_BYTEORDER_NATIVE; /* Create the parameter list. */ long l; AUpvlist pv = AUpvnew(2); AUpvsetparam(pv, 0, _AF_FRAMES_PER_BLOCK); AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG); l = samplesPerBlock; AUpvsetval(pv, 0, &l); AUpvsetparam(pv, 1, _AF_BLOCK_SIZE); AUpvsetvaltype(pv, 1, AU_PVTYPE_LONG); l = blockAlign; AUpvsetval(pv, 1, &l); track->f.compressionParams = pv; } break; case WAVE_FORMAT_EXTENSIBLE: { uint16_t bitsPerSample; readU16(&bitsPerSample); uint16_t extraByteCount; readU16(&extraByteCount); uint16_t reserved; readU16(&reserved); uint32_t channelMask; readU32(&channelMask); UUID subformat; readUUID(&subformat); if (subformat == _af_wave_guid_pcm) { track->f.sampleWidth = bitsPerSample; if (bitsPerSample == 0 || bitsPerSample > 32) { _af_error(AF_BAD_WIDTH, "bad sample width of %d bits", bitsPerSample); return AF_FAIL; } // Use valid bits per sample if bytes per sample is the same. if (reserved <= bitsPerSample && (reserved + 7) / 8 == (bitsPerSample + 7) / 8) track->f.sampleWidth = reserved; if (bitsPerSample <= 8) track->f.sampleFormat = AF_SAMPFMT_UNSIGNED; else track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; } else if (subformat == _af_wave_guid_ieee_float) { if (bitsPerSample == 64) { track->f.sampleWidth = 64; track->f.sampleFormat = AF_SAMPFMT_DOUBLE; } else { track->f.sampleWidth = 32; track->f.sampleFormat = AF_SAMPFMT_FLOAT; } } else if (subformat == _af_wave_guid_alaw || subformat == _af_wave_guid_ulaw) { track->f.compressionType = subformat == _af_wave_guid_alaw ? AF_COMPRESSION_G711_ALAW : AF_COMPRESSION_G711_ULAW; track->f.sampleWidth = 16; track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP; track->f.byteOrder = _AF_BYTEORDER_NATIVE; } else { _af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE extensible data format %s is not currently supported", subformat.name().c_str()); return AF_FAIL; } } break; case WAVE_FORMAT_YAMAHA_ADPCM: case WAVE_FORMAT_OKI_ADPCM: case WAVE_FORMAT_CREATIVE_ADPCM: case IBM_FORMAT_ADPCM: _af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE ADPCM data format 0x%x is not currently supported", formatTag); return AF_FAIL; break; case WAVE_FORMAT_MPEG: _af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE MPEG data format is not supported"); return AF_FAIL; break; case WAVE_FORMAT_MPEGLAYER3: _af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE MPEG layer 3 data format is not supported"); return AF_FAIL; break; default: _af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE file data format 0x%x not currently supported != 0xfffe ? %d, != EXTENSIBLE? %d", formatTag, formatTag != 0xfffe, formatTag != WAVE_FORMAT_EXTENSIBLE); return AF_FAIL; break; } _af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth); return AF_SUCCEED; }
/* ARGSUSED3 */ AUpvlist _afQueryInstrumentParameter (int arg1, int arg2, int arg3, int arg4) { switch (arg1) { /* For the following query types, arg2 is the file format. */ case AF_QUERY_SUPPORTED: if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; return _af_pv_long(_af_units[arg2].instrumentParameterCount != 0); case AF_QUERY_ID_COUNT: if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; return _af_pv_long(_af_units[arg2].instrumentParameterCount); case AF_QUERY_IDS: { int count; int *buffer; if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; count = _af_units[arg2].instrumentParameterCount; if (count == 0) return AU_NULL_PVLIST; buffer = (int *) _af_calloc(count, sizeof (int)); if (buffer == NULL) return AU_NULL_PVLIST; for (int i=0; i<count; i++) buffer[i] = _af_units[arg2].instrumentParameters[i].id; return _af_pv_pointer(buffer); } /* NOTREACHED */ break; /* For the next few query types, arg2 is the file format and arg3 is the instrument parameter id. */ case AF_QUERY_TYPE: { int idx; if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; idx = _af_instparam_index_from_id(arg2, arg3); if (idx<0) return AU_NULL_PVLIST; return _af_pv_long(_af_units[arg2].instrumentParameters[idx].type); } case AF_QUERY_NAME: { int idx; if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; idx = _af_instparam_index_from_id(arg2, arg3); if (idx < 0) return AU_NULL_PVLIST; return _af_pv_pointer(const_cast<char *>(_af_units[arg2].instrumentParameters[idx].name)); } case AF_QUERY_DEFAULT: { int idx; if (arg2 < 0 || arg2 >= _AF_NUM_UNITS) return AU_NULL_PVLIST; idx = _af_instparam_index_from_id(arg2, arg3); if (idx >= 0) { AUpvlist ret = AUpvnew(1); AUpvsetparam(ret, 0, _af_units[arg2].instrumentParameters[idx].id); AUpvsetvaltype(ret, 0, _af_units[arg2].instrumentParameters[idx].type); AUpvsetval(ret, 0, const_cast<AFPVu *>(&_af_units[arg2].instrumentParameters[idx].defaultValue)); return ret; } return AU_NULL_PVLIST; } } _af_error(AF_BAD_QUERY, "bad query selector"); return AU_NULL_PVLIST; }