diff options
-rw-r--r-- | src/adlmidi.cpp | 25 | ||||
-rw-r--r-- | src/adlmidi_load.cpp | 8 | ||||
-rw-r--r-- | src/adlmidi_midiplay.cpp | 30 | ||||
-rw-r--r-- | src/adlmidi_mus2mid.c | 2 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 25 | ||||
-rw-r--r-- | src/chips/dosbox/dbopl.cpp | 54 | ||||
-rw-r--r-- | src/fraction.hpp | 9 |
7 files changed, 87 insertions, 66 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index f9891a8..e90680a 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -313,7 +313,9 @@ ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.AdlPercussionMode = percmod; - play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode; + play->opl.AdlPercussionMode = play->m_setup.AdlPercussionMode < 0 ? + play->opl.dynamic_bank_setup.adLibPercussions : + (play->m_setup.AdlPercussionMode != 0); play->opl.updateFlags(); } @@ -322,7 +324,9 @@ ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.HighVibratoMode = hvibro; - play->opl.HighVibratoMode = play->m_setup.HighVibratoMode; + play->opl.HighVibratoMode = play->m_setup.HighVibratoMode < 0 ? + play->opl.dynamic_bank_setup.deepVibrato : + (play->m_setup.HighVibratoMode != 0); play->opl.updateDeepFlags(); } @@ -331,7 +335,9 @@ ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.HighTremoloMode = htremo; - play->opl.HighTremoloMode = play->m_setup.HighTremoloMode; + play->opl.HighTremoloMode = play->m_setup.HighTremoloMode < 0 ? + play->opl.dynamic_bank_setup.deepTremolo : + (play->m_setup.HighTremoloMode != 0); play->opl.updateDeepFlags(); } @@ -340,14 +346,16 @@ ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod) if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.ScaleModulators = smod; - play->opl.ScaleModulators = play->m_setup.ScaleModulators; + play->opl.ScaleModulators = play->m_setup.ScaleModulators < 0 ? + play->opl.dynamic_bank_setup.scaleModulators : + (play->m_setup.ScaleModulators != 0); } ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness) { if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - play->m_setup.fullRangeBrightnessCC74 = fr_brightness; + play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0); } ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn) @@ -362,7 +370,7 @@ ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int { if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); - play->m_setup.LogarithmicVolumes = logvol; + play->m_setup.LogarithmicVolumes = (logvol != 0); if(play->m_setup.LogarithmicVolumes) play->opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); } @@ -372,7 +380,10 @@ ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int v if(!device) return; MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer); play->m_setup.VolumeModel = volumeModel; - play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel)); + if(play->m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model + play->opl.m_volumeScale = (OPL3::VolumesScale)play->opl.dynamic_bank_setup.volumeModel; + else + play->opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(volumeModel)); } ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath) diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index c75bed4..9e19ab6 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -93,7 +93,7 @@ static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in) ins.flags|= (in.inst_flags & WOPL_Ins_IsBlank) ? adlinsdata::Flag_NoSound : 0; bool fourOps = (in.inst_flags & WOPL_Ins_4op) || (in.inst_flags & WOPL_Ins_Pseudo4op); - for(size_t op = 0, slt = 0; op < (fourOps ? 4 : 2); op++, slt++) + for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++) { ins.adl[slt].carrier_E862 = ((static_cast<uint32_t>(in.operators[op].waveform_E0) << 24) & 0xFF000000) //WaveForm @@ -111,13 +111,13 @@ static void cvt_generic_to_FMIns(adlinsdata2 &ins, const WOPLI &in) ins.adl[slt].modulator_40 = in.operators[op].ksl_l_40;//KSLL } - ins.adl[0].finetune = in.note_offset1; + ins.adl[0].finetune = static_cast<int8_t>(in.note_offset1); ins.adl[0].feedconn = in.fb_conn1_C0; if(!fourOps) ins.adl[1] = ins.adl[0]; else { - ins.adl[1].finetune = in.note_offset2; + ins.adl[1].finetune = static_cast<int8_t>(in.note_offset2); ins.adl[1].feedconn = in.fb_conn2_C0; } @@ -151,7 +151,7 @@ static void cvt_FMIns_to_generic(WOPLI &ins, const adlinsdata2 &in) ins.inst_flags|= (in.flags & adlinsdata::Flag_Pseudo4op) ? WOPL_Ins_Pseudo4op : 0; ins.inst_flags|= (in.flags & adlinsdata::Flag_NoSound) ? WOPL_Ins_IsBlank : 0; - for(size_t op = 0, slt = 0; op < (fourOps ? 4 : 2); op++, slt++) + for(size_t op = 0, slt = 0; op < static_cast<size_t>(fourOps ? 4 : 2); op++, slt++) { ins.operators[op].waveform_E0 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 24); ins.operators[op].susrel_80 = static_cast<uint8_t>(in.adl[slt].carrier_E862 >> 16); diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 07bcc6a..3c94d76 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -680,7 +680,8 @@ bool MIDIplay::buildTrackData() MIDIplay::MIDIplay(unsigned long sampleRate): - cmf_percussion_mode(false) + cmf_percussion_mode(false), + m_arpeggioCounter(0) #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER , fullSongTimeLength(0.0), postSongWaitDelay(1.0), @@ -731,16 +732,16 @@ void MIDIplay::applySetup() opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ? opl.dynamic_bank_setup.deepTremolo : - (bool)m_setup.HighTremoloMode; + (m_setup.HighTremoloMode != 0); opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ? opl.dynamic_bank_setup.deepVibrato : - (bool)m_setup.HighVibratoMode; + (m_setup.HighVibratoMode != 0); opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ? opl.dynamic_bank_setup.adLibPercussions : - (bool)m_setup.AdlPercussionMode; + (m_setup.AdlPercussionMode != 0); opl.ScaleModulators = m_setup.ScaleModulators < 0 ? opl.dynamic_bank_setup.scaleModulators : - (bool)m_setup.ScaleModulators; + (m_setup.ScaleModulators != 0); if(m_setup.LogarithmicVolumes) opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3); opl.m_musicMode = OPL3::MODE_MIDI; @@ -755,6 +756,9 @@ void MIDIplay::applySetup() opl.Reset(m_setup.emulator, m_setup.PCM_RATE); ch.clear(); ch.resize(opl.NumChannels); + + // Reset the arpeggio counter + m_arpeggioCounter = 0; } #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER @@ -1441,7 +1445,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, MIDIchannel::NoteInfo &info = *i; const int16_t tone = info.tone; const uint8_t vol = info.vol; - const int midiins = info.midiins; + const int midiins = static_cast<int>(info.midiins); const adlinsdata2 &ains = *info.ains; AdlChannel::Location my_loc; my_loc.MidCh = MidCh; @@ -2151,7 +2155,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu } #endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */ -int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const +int64_t MIDIplay::CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const { int64_t s = -ch[c].koff_time_until_neglible; @@ -2198,7 +2202,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not // increase the score slightly. unsigned n_evacuation_stations = 0; - for(unsigned c2 = 0; c2 < opl.NumChannels; ++c2) + for(size_t c2 = 0; c2 < static_cast<size_t>(opl.NumChannels); ++c2) { if(c2 == c) continue; @@ -2299,11 +2303,11 @@ void MIDIplay::KillOrEvacuate(size_t from_channel, hooks.onNote(hooks.onNote_userData, (int)from_channel, i->tone, - i->midiins, 0, 0.0); + static_cast<int>(i->midiins), 0, 0.0); hooks.onNote(hooks.onNote_userData, (int)c, i->tone, - i->midiins, + static_cast<int>(i->midiins), i->vol, 0.0); } @@ -2490,8 +2494,8 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed arpeggio_cache = 0.0; # endif #endif - static unsigned arpeggio_counter = 0; - ++arpeggio_counter; + + ++m_arpeggioCounter; for(uint32_t c = 0; c < opl.NumChannels; ++c) { @@ -2512,7 +2516,7 @@ retry_arpeggio: if(n_users >= 4) rate_reduction = 1; - for(unsigned count = (arpeggio_counter / rate_reduction) % n_users, + for(size_t count = (m_arpeggioCounter / rate_reduction) % n_users, n = 0; n < count; ++n) i = i->next; diff --git a/src/adlmidi_mus2mid.c b/src/adlmidi_mus2mid.c index 8268198..3f3e1b8 100644 --- a/src/adlmidi_mus2mid.c +++ b/src/adlmidi_mus2mid.c @@ -416,7 +416,7 @@ int AdlMidi_mus2midi(uint8_t *in, uint32_t insize, memcpy(ctx.dst_ptr, temp_buffer, out_local - temp_buffer); ctx.dst_ptr += out_local - temp_buffer; - ctx.dstrem -= out_local - temp_buffer; + ctx.dstrem -= (uint32_t)(out_local - temp_buffer); } if (event & 128) { diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 63b4854..0584587 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -131,13 +131,6 @@ typedef int32_t ssize_t; #define INT32_MAX 0x7fffffff #endif -#ifdef _MSC_VER -#pragma warning(disable:4319) -#pragma warning(disable:4267) -#pragma warning(disable:4244) -#pragma warning(disable:4146) -#endif - #include "fraction.hpp" #ifndef ADLMIDI_HW_OPL #include "chips/opl_chip_base.h" @@ -167,12 +160,14 @@ inline Real adl_cvtReal(int32_t x) { return x * ((Real)1 / INT16_MAX); } + inline int32_t adl_cvtS16(int32_t x) { - x = (x < INT16_MIN) ? INT16_MIN : x; - x = (x > INT16_MAX) ? INT16_MAX : x; + x = (x < INT16_MIN) ? (INT16_MIN) : x; + x = (x > INT16_MAX) ? (INT16_MAX) : x; return x; } + inline int32_t adl_cvtS8(int32_t x) { return adl_cvtS16(x) / 256; @@ -485,7 +480,7 @@ public: bool eof() { if(fp) - return std::feof(fp); + return (std::feof(fp) != 0); else return mp_tell >= mp_size; } @@ -592,9 +587,9 @@ public: } void phys_erase_at(const Phys *ph) { - unsigned pos = ph - chip_channels; - assert(pos < chip_channels_count); - for(unsigned i = pos + 1; i < chip_channels_count; ++i) + intptr_t pos = ph - chip_channels; + assert(pos < static_cast<intptr_t>(chip_channels_count)); + for(intptr_t i = pos + 1; i < static_cast<intptr_t>(chip_channels_count); ++i) chip_channels[i - 1] = chip_channels[i]; --chip_channels_count; } @@ -976,6 +971,8 @@ private: char ____padding[7]; std::vector<AdlChannel> ch; + //! Counter of arpeggio processing + size_t m_arpeggioCounter; #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER std::vector<std::vector<uint8_t> > TrackData; @@ -1199,7 +1196,7 @@ private: // Determine how good a candidate this adlchannel // would be for playing a note from this instrument. - int64_t CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const; + int64_t CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t /*MidCh*/) const; // A new note will be played on this channel using this instrument. // Kill existing notes on this channel (or don't, if we do arpeggio) diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 098eb13..7d78c5f 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -819,7 +819,7 @@ INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { //BassDrum Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; old[0] = old[1]; - old[1] = Op(0)->GetSample( mod ); + old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod )); //When bassdrum is in AM mode first operator is ignoed if ( chan->regC0 & 1 ) { @@ -827,35 +827,35 @@ INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) { } else { mod = old[0]; } - Bit32s sample = Op(1)->GetSample( mod ); + Bit32s sample = static_cast<Bit32u>(Op(1)->GetSample( mod )); //Precalculate stuff used by other outputs Bit32u noiseBit = chip->ForwardNoise() & 0x1; - Bit32u c2 = Op(2)->ForwardWave(); - Bit32u c5 = Op(5)->ForwardWave(); + Bit32u c2 = static_cast<Bit32u>(Op(2)->ForwardWave()); + Bit32u c5 = static_cast<Bit32u>(Op(5)->ForwardWave()); Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; //Hi-Hat - Bit32u hhVol = Op(2)->ForwardVolume(); + Bit32u hhVol = static_cast<Bit32u>(Op(2)->ForwardVolume()); if ( !ENV_SILENT( hhVol ) ) { Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); - sample += Op(2)->GetWave( hhIndex, hhVol ); + sample += static_cast<Bit32u>(Op(2)->GetWave( hhIndex, hhVol )); } //Snare Drum - Bit32u sdVol = Op(3)->ForwardVolume(); + Bit32u sdVol = static_cast<Bit32u>(Op(3)->ForwardVolume()); if ( !ENV_SILENT( sdVol ) ) { Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); - sample += Op(3)->GetWave( sdIndex, sdVol ); + sample += static_cast<Bit32u>(Op(3)->GetWave( sdIndex, sdVol )); } //Tom-tom - sample += Op(4)->GetSample( 0 ); + sample += static_cast<Bit32u>(Op(4)->GetSample( 0 )); //Top-Cymbal - Bit32u tcVol = Op(5)->ForwardVolume(); + Bit32u tcVol = static_cast<Bit32u>(Op(5)->ForwardVolume()); if ( !ENV_SILENT( tcVol ) ) { Bit32u tcIndex = (1 + phaseBit) << 8; - sample += Op(5)->GetWave( tcIndex, tcVol ); + sample += static_cast<Bit32u>(Op(5)->GetWave( tcIndex, tcVol )); } sample <<= 1; if ( opl3Mode ) { @@ -934,31 +934,31 @@ Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise Bit32s mod = (Bit32u)((old[0] + old[1])) >> feedback; old[0] = old[1]; - old[1] = Op(0)->GetSample( mod ); + old[1] = static_cast<Bit32u>(Op(0)->GetSample( mod )); Bit32s sample; Bit32s out0 = old[0]; if ( mode == sm2AM || mode == sm3AM ) { - sample = out0 + Op(1)->GetSample( 0 ); + sample = static_cast<Bit32u>(out0 + Op(1)->GetSample( 0 )); } else if ( mode == sm2FM || mode == sm3FM ) { - sample = Op(1)->GetSample( out0 ); + sample = static_cast<Bit32u>(Op(1)->GetSample( out0 )); } else if ( mode == sm3FMFM ) { Bits next = Op(1)->GetSample( out0 ); next = Op(2)->GetSample( next ); - sample = Op(3)->GetSample( next ); + sample = static_cast<Bit32u>(Op(3)->GetSample( next )); } else if ( mode == sm3AMFM ) { sample = out0; Bits next = Op(1)->GetSample( 0 ); next = Op(2)->GetSample( next ); - sample += Op(3)->GetSample( next ); + sample += static_cast<Bit32u>(Op(3)->GetSample( next )); } else if ( mode == sm3FMAM ) { - sample = Op(1)->GetSample( out0 ); + sample = static_cast<Bit32u>(Op(1)->GetSample( out0 )); Bits next = Op(2)->GetSample( 0 ); - sample += Op(3)->GetSample( next ); + sample += static_cast<Bit32u>(Op(3)->GetSample( next )); } else if ( mode == sm3AMAM ) { sample = out0; Bits next = Op(1)->GetSample( 0 ); - sample += Op(2)->GetSample( next ); - sample += Op(3)->GetSample( 0 ); + sample += static_cast<Bit32u>(Op(2)->GetSample( next )); + sample += static_cast<Bit32u>(Op(3)->GetSample( 0 )); } switch( mode ) { case sm2AM: @@ -1213,7 +1213,7 @@ Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) { void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); memset(output, 0, sizeof(Bit32s) * samples); // int count = 0; for( Channel* ch = chan; ch < chan + 9; ) { @@ -1227,7 +1227,7 @@ void Chip::GenerateBlock2( Bitu total, Bit32s* output ) { void Chip::GenerateBlock2_Mix( Bitu total, Bit32s* output ) { while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); // int count = 0; for( Channel* ch = chan; ch < chan + 9; ) { // count++; @@ -1240,7 +1240,7 @@ void Chip::GenerateBlock2_Mix( Bitu total, Bit32s* output ) { void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); memset(output, 0, sizeof(Bit32s) * samples *2); // int count = 0; for( Channel* ch = chan; ch < chan + 18; ) { @@ -1254,7 +1254,7 @@ void Chip::GenerateBlock3( Bitu total, Bit32s* output ) { void Chip::GenerateBlock3_Mix( Bitu total, Bit32s* output ) { while ( total > 0 ) { - Bit32u samples = ForwardLFO( total ); + Bit32u samples = ForwardLFO( static_cast<Bit32u>(total) ); // int count = 0; for( Channel* ch = chan; ch < chan + 18; ) { // count++; @@ -1500,7 +1500,7 @@ void InitTables( void ) { if ( i >= 16 ) index += 9; Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) ); - ChanOffsetTable[i] = blah; + ChanOffsetTable[i] = static_cast<Bit16u>(blah); } //Same for operators for ( Bitu i = 0; i < 64; i++ ) { @@ -1515,7 +1515,7 @@ void InitTables( void ) { Bitu opNum = ( i % 8 ) / 3; DBOPL::Channel* chan = 0; Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) ); - OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah; + OpOffsetTable[i] = static_cast<Bit16u>(ChanOffsetTable[ chNum ] + blah); } #if 0 //Stupid checks if table's are correct @@ -1611,7 +1611,7 @@ void Handler::GenerateArrMix(Bit16s *out, Bitu *samples) void Handler::Init( Bitu rate ) { InitTables(); - chip.Setup( rate ); + chip.Setup( static_cast<Bit32u>(rate) ); } diff --git a/src/fraction.hpp b/src/fraction.hpp index 1ec10ab..1c0a38d 100644 --- a/src/fraction.hpp +++ b/src/fraction.hpp @@ -4,6 +4,7 @@ #include <cmath> #include <limits> + /* Fraction number handling. * Copyright (C) 1992,2001 Bisqwit (http://iki.fi/bisqwit/) */ @@ -82,6 +83,10 @@ public: self &operator= (long double orig); }; +#ifdef _MSC_VER +#pragma warning(disable:4146) +#endif + template<typename inttype> void fraction<inttype>::Optim() { @@ -110,6 +115,10 @@ void fraction<inttype>::Optim() //fprintf(stderr, "result: %d/%d\n\n", nom(), denom()); } +#ifdef _MSC_VER +#pragma warning(default:4146) +#endif + template<typename inttype> inline const fraction<inttype> abs(const fraction<inttype> &f) { |