mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-25 17:00:36 -09:00
Merge remote-tracking branch
'origin/GP-2858_dragonmacher_PR-4755_agatti_refactor-audio-playable' (Closes #4755)
This commit is contained in:
@@ -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]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user