Merge remote-tracking branch

'origin/GP-2858_dragonmacher_PR-4755_agatti_refactor-audio-playable'
(Closes #4755)
This commit is contained in:
Ryan Kurtz
2022-11-22 00:54:06 -05:00
5 changed files with 83 additions and 129 deletions

View File

@@ -4,9 +4,7 @@
icon.content.handler.archive.dt = closedBookBlue.png
icon.content.handler.program = program_obj.png
icon.data.type.aiff = audio-volume-medium.png
icon.data.type.au = audio-volume-medium.png
icon.data.type.wave = audio-volume-medium.png
icon.data.type.audio.player = audio-volume-medium.png
[Dark Defaults]

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,14 +15,6 @@
*/
package ghidra.program.model.data;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.sound.sampled.*;
import javax.swing.Icon;
import generic.theme.GIcon;
import ghidra.docking.settings.Settings;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
@@ -104,36 +96,6 @@ public class AIFFDataType extends BuiltIn implements Dynamic {
return "<AIFF-Representation>";
}
private static class AIFFData implements Playable {
private static final Icon AUDIO_ICON = new GIcon("icon.data.type.aiff");
private byte[] bytes;
public AIFFData(byte[] bytes) {
this.bytes = bytes;
}
@Override
public void clicked(MouseEvent event) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream ais =
AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes));
clip.open(ais);
clip.start();
}
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
Msg.debug(this, "Unable to play audio", e);
}
}
@Override
public Icon getImageIcon() {
return AUDIO_ICON;
}
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
byte[] data = new byte[length];
@@ -141,12 +103,12 @@ public class AIFFDataType extends BuiltIn implements Dynamic {
Msg.error(this, "AIFF-Sound error: Not enough bytes in memory");
return null;
}
return new AIFFData(data);
return new AudioPlayer(data);
}
@Override
public Class<?> getValueClass(Settings settings) {
return AIFFData.class;
return AudioPlayer.class;
}
@Override

View File

@@ -15,14 +15,6 @@
*/
package ghidra.program.model.data;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.sound.sampled.*;
import javax.swing.Icon;
import generic.theme.GIcon;
import ghidra.docking.settings.Settings;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
@@ -56,7 +48,7 @@ public class AUDataType extends BuiltIn implements Dynamic {
Msg.debug(this, "Invalid AU magic number");
return -1;
}
//Ints always stored as big endian in this format but can be in any kind of program so must get the ints as big endian even when in a little endian program
//Ints always stored as big endian in this format but can be in any kind of program so must get the ints as big endian even when in a little endian program
int dataOffset = GhidraBigEndianDataConverter.INSTANCE.getInt(buf, 4);
int dataSize = GhidraBigEndianDataConverter.INSTANCE.getInt(buf, 8);
@@ -108,36 +100,6 @@ public class AUDataType extends BuiltIn implements Dynamic {
return "<AU-Representation>";
}
private static class AUData implements Playable {
private static final Icon AUDIO_ICON = new GIcon("icon.data.type.au");
private byte[] bytes;
public AUData(byte[] bytes) {
this.bytes = bytes;
}
@Override
public void clicked(MouseEvent event) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream ais =
AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes));
clip.open(ais);
clip.start();
}
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
Msg.debug(this, "Unable to play audio", e);
}
}
@Override
public Icon getImageIcon() {
return AUDIO_ICON;
}
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
byte[] data = new byte[length];
@@ -145,12 +107,12 @@ public class AUDataType extends BuiltIn implements Dynamic {
Msg.error(this, "AU-DataTpe Error: Not enough bytes in memory");
return null;
}
return new AUData(data);
return new AudioPlayer(data);
}
@Override
public Class<?> getValueClass(Settings settings) {
return AUData.class;
return AudioPlayer.class;
}
@Override

View File

@@ -0,0 +1,71 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.model.data;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.sound.sampled.*;
import javax.sound.sampled.LineEvent.Type;
import javax.swing.Icon;
import generic.theme.GIcon;
import ghidra.util.Msg;
public class AudioPlayer implements Playable, LineListener {
private static final Icon AUDIO_ICON = new GIcon("icon.data.type.audio.player");
private byte[] bytes;
public AudioPlayer(byte[] bytes) {
this.bytes = bytes;
}
@Override
public Icon getImageIcon() {
return AUDIO_ICON;
}
@Override
public void clicked(MouseEvent event) {
try (AudioInputStream stream =
AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes))) {
Clip clip = AudioSystem.getClip();
clip.addLineListener(this);
clip.open(stream);
clip.start();
}
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
Msg.debug(this, "Unable to play audio", e);
}
}
@Override
public void update(LineEvent event) {
LineEvent.Type eventType = event.getType();
if (eventType != Type.STOP && eventType != Type.CLOSE) {
return;
}
if (event.getSource() instanceof Clip clip) {
clip.removeLineListener(this);
clip.close();
}
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,14 +15,6 @@
*/
package ghidra.program.model.data;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.sound.sampled.*;
import javax.swing.Icon;
import generic.theme.GIcon;
import ghidra.docking.settings.Settings;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
@@ -101,36 +93,6 @@ public class WAVEDataType extends BuiltIn implements Dynamic {
return "<WAVE-Resource>";
}
private static class WAVEData implements Playable {
private static final Icon AUDIO_ICON = new GIcon("icon.data.type.wave");
private byte[] bytes;
public WAVEData(byte[] bytes) {
this.bytes = bytes;
}
@Override
public void clicked(MouseEvent event) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream ais =
AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes));
clip.open(ais);
clip.start();
}
catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
Msg.debug(this, "Unable to play audio", e);
}
}
@Override
public Icon getImageIcon() {
return AUDIO_ICON;
}
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
byte[] data = new byte[length];
@@ -138,13 +100,12 @@ public class WAVEDataType extends BuiltIn implements Dynamic {
Msg.error(this, "WAVE-Sound error: " + "Not enough bytes!");
return null;
}
WAVEData waveData = new WAVEData(data);
return waveData;
return new AudioPlayer(data);
}
@Override
public Class<?> getValueClass(Settings settings) {
return WAVEData.class;
return AudioPlayer.class;
}
@Override