--- a/net/minecraft/world/level/block/NoteBlock.java
+++ b/net/minecraft/world/level/block/NoteBlock.java
@@ -25,43 +25,54 @@
 import net.minecraft.world.phys.BlockHitResult;
 
 public class NoteBlock extends Block {
+
     public static final EnumProperty<NoteBlockInstrument> INSTRUMENT = BlockStateProperties.NOTEBLOCK_INSTRUMENT;
     public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
     public static final IntegerProperty NOTE = BlockStateProperties.NOTE;
 
     public NoteBlock(BlockBehaviour.Properties settings) {
         super(settings);
-        this.registerDefaultState(this.stateDefinition.any().setValue(INSTRUMENT, NoteBlockInstrument.HARP).setValue(NOTE, Integer.valueOf(0)).setValue(POWERED, Boolean.valueOf(false)));
+        this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(NoteBlock.INSTRUMENT, NoteBlockInstrument.HARP)).setValue(NoteBlock.NOTE, 0)).setValue(NoteBlock.POWERED, false));
     }
 
     @Override
     public BlockState getStateForPlacement(BlockPlaceContext ctx) {
-        return this.defaultBlockState().setValue(INSTRUMENT, NoteBlockInstrument.byState(ctx.getLevel().getBlockState(ctx.getClickedPos().below())));
+        return (BlockState) this.defaultBlockState().setValue(NoteBlock.INSTRUMENT, NoteBlockInstrument.byState(ctx.getLevel().getBlockState(ctx.getClickedPos().below())));
     }
 
     @Override
     public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
-        return direction == Direction.DOWN ? state.setValue(INSTRUMENT, NoteBlockInstrument.byState(neighborState)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
+        return direction == Direction.DOWN ? (BlockState) state.setValue(NoteBlock.INSTRUMENT, NoteBlockInstrument.byState(neighborState)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
     }
 
     @Override
     public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
-        boolean bl = world.hasNeighborSignal(pos);
-        if (bl != state.getValue(POWERED)) {
-            if (bl) {
-                this.playNote((Entity)null, world, pos);
+        boolean flag1 = world.hasNeighborSignal(pos);
+
+        if (flag1 != (Boolean) state.getValue(NoteBlock.POWERED)) {
+            if (flag1) {
+                this.playNote((Entity) null, world, pos, state); // CraftBukkit
+                state = world.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event
             }
 
-            world.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(bl)), 3);
+            world.setBlock(pos, (BlockState) state.setValue(NoteBlock.POWERED, flag1), 3);
         }
 
     }
 
-    private void playNote(@Nullable Entity entity, Level world, BlockPos pos) {
-        if (world.getBlockState(pos.above()).isAir()) {
-            world.blockEvent(pos, this, 0, 0);
-            world.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, pos);
+    private void playNote(@Nullable Entity entity, Level world, BlockPos blockposition, BlockState data) { // CraftBukkit
+        if (world.getBlockState(blockposition.above()).isAir()) {
+            // CraftBukkit start
+            // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.v1_19_R1.event.CraftEventFactory.callNotePlayEvent(world, blockposition, data.getValue(NoteBlock.INSTRUMENT), data.getValue(NoteBlock.NOTE)); // Paper - move event into block event handler
+            // if (event.isCancelled()) {
+            //     return;
+            // }
+            // CraftBukkit end
+            // Paper - TODO any way to cancel the game event?
+            world.blockEvent(blockposition, this, 0, 0);
+            world.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, blockposition);
         }
+
     }
 
     @Override
@@ -69,9 +80,9 @@
         if (world.isClientSide) {
             return InteractionResult.SUCCESS;
         } else {
-            state = state.cycle(NOTE);
+            state = (BlockState) state.cycle(NoteBlock.NOTE);
             world.setBlock(pos, state, 3);
-            this.playNote(player, world, pos);
+            this.playNote(player, world, pos, state); // CraftBukkit
             player.awardStat(Stats.TUNE_NOTEBLOCK);
             return InteractionResult.CONSUME;
         }
@@ -80,22 +91,27 @@
     @Override
     public void attack(BlockState state, Level world, BlockPos pos, Player player) {
         if (!world.isClientSide) {
-            this.playNote(player, world, pos);
+            this.playNote(player, world, pos, state); // CraftBukkit
             player.awardStat(Stats.PLAY_NOTEBLOCK);
         }
     }
 
     @Override
     public boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) {
-        int i = state.getValue(NOTE);
-        float f = (float)Math.pow(2.0D, (double)(i - 12) / 12.0D);
-        world.playSound((Player)null, pos, state.getValue(INSTRUMENT).getSoundEvent(), SoundSource.RECORDS, 3.0F, f);
-        world.addParticle(ParticleTypes.NOTE, (double)pos.getX() + 0.5D, (double)pos.getY() + 1.2D, (double)pos.getZ() + 0.5D, (double)i / 24.0D, 0.0D, 0.0D);
+        // Paper start - move NotePlayEvent call to fix instrument/note changes
+        org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.v1_19_R1.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(INSTRUMENT), state.getValue(NOTE));
+        if (event.isCancelled()) return false;
+        int k = event.getNote().getId();
+        float f = (float) Math.pow(2.0D, (double) (k - 12) / 12.0D);
+
+        world.playSound(null, pos, org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(), SoundSource.RECORDS, 3.0F, f);
+        // Paper end
+        world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D);
         return true;
     }
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(INSTRUMENT, POWERED, NOTE);
+        builder.add(NoteBlock.INSTRUMENT, NoteBlock.POWERED, NoteBlock.NOTE);
     }
 }
