You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-06 12:20:30 +00:00
Entirely new (and much improved) animation editor.
This commit is contained in:
@@ -554,274 +554,92 @@ EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() {
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
// FIXME: Needs to be rewritten for AudioStream in Godot 3.0+
|
||||
#if 0
|
||||
bool EditorSamplePreviewPlugin::handles(const String& p_type) const {
|
||||
bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
|
||||
|
||||
return ClassDB::is_parent_class(p_type,"Sample");
|
||||
return ClassDB::is_parent_class(p_type, "AudioStream");
|
||||
}
|
||||
|
||||
Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) {
|
||||
|
||||
Ref<Sample> smp =p_from;
|
||||
ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>());
|
||||
Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) {
|
||||
|
||||
Ref<AudioStream> stream = p_from;
|
||||
ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>());
|
||||
|
||||
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
|
||||
thumbnail_size*=EDSCALE;
|
||||
thumbnail_size *= EDSCALE;
|
||||
PoolVector<uint8_t> img;
|
||||
int w = thumbnail_size;
|
||||
int h = thumbnail_size;
|
||||
img.resize(w*h*3);
|
||||
img.resize(w * h * 3);
|
||||
|
||||
PoolVector<uint8_t>::Write imgdata = img.write();
|
||||
uint8_t * imgw = imgdata.ptr();
|
||||
PoolVector<uint8_t> data = smp->get_data();
|
||||
PoolVector<uint8_t>::Read sampledata = data.read();
|
||||
const uint8_t *sdata=sampledata.ptr();
|
||||
uint8_t *imgw = imgdata.ptr();
|
||||
|
||||
bool stereo = smp->is_stereo();
|
||||
bool _16=smp->get_format()==Sample::FORMAT_PCM16;
|
||||
int len = smp->get_length();
|
||||
Ref<AudioStreamPlayback> playback = stream->instance_playback();
|
||||
|
||||
if (len<1)
|
||||
return Ref<Texture>();
|
||||
float len_s = stream->get_length();
|
||||
if (len_s == 0) {
|
||||
len_s = 60; //one minute audio if no length specified
|
||||
}
|
||||
int frame_length = AudioServer::get_singleton()->get_mix_rate() * len_s;
|
||||
|
||||
if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) {
|
||||
Vector<AudioFrame> frames;
|
||||
frames.resize(frame_length);
|
||||
|
||||
struct IMA_ADPCM_State {
|
||||
playback->start();
|
||||
playback->mix(frames.ptrw(), 1, frames.size());
|
||||
playback->stop();
|
||||
|
||||
int16_t step_index;
|
||||
int32_t predictor;
|
||||
/* values at loop point */
|
||||
int16_t loop_step_index;
|
||||
int32_t loop_predictor;
|
||||
int32_t last_nibble;
|
||||
int32_t loop_pos;
|
||||
int32_t window_ofs;
|
||||
const uint8_t *ptr;
|
||||
} ima_adpcm;
|
||||
for (int i = 0; i < w; i++) {
|
||||
|
||||
ima_adpcm.step_index=0;
|
||||
ima_adpcm.predictor=0;
|
||||
ima_adpcm.loop_step_index=0;
|
||||
ima_adpcm.loop_predictor=0;
|
||||
ima_adpcm.last_nibble=-1;
|
||||
ima_adpcm.loop_pos=0x7FFFFFFF;
|
||||
ima_adpcm.window_ofs=0;
|
||||
ima_adpcm.ptr=NULL;
|
||||
|
||||
|
||||
for(int i=0;i<w;i++) {
|
||||
|
||||
float max[2]={-1e10,-1e10};
|
||||
float min[2]={1e10,1e10};
|
||||
int from = i*len/w;
|
||||
int to = (i+1)*len/w;
|
||||
if (to>=len)
|
||||
to=len-1;
|
||||
|
||||
for(int j=from;j<to;j++) {
|
||||
|
||||
while(j>ima_adpcm.last_nibble) {
|
||||
|
||||
static const int16_t _ima_adpcm_step_table[89] = {
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
|
||||
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
|
||||
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
|
||||
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
|
||||
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
|
||||
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
|
||||
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
|
||||
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
||||
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
|
||||
};
|
||||
|
||||
static const int8_t _ima_adpcm_index_table[16] = {
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8
|
||||
};
|
||||
|
||||
int16_t nibble,diff,step;
|
||||
|
||||
ima_adpcm.last_nibble++;
|
||||
const uint8_t *src_ptr=sdata;
|
||||
|
||||
int ofs = ima_adpcm.last_nibble>>1;
|
||||
|
||||
if (stereo)
|
||||
ofs*=2;
|
||||
|
||||
|
||||
nibble = (ima_adpcm.last_nibble&1)?
|
||||
(src_ptr[ofs]>>4):(src_ptr[ofs]&0xF);
|
||||
step=_ima_adpcm_step_table[ima_adpcm.step_index];
|
||||
|
||||
ima_adpcm.step_index += _ima_adpcm_index_table[nibble];
|
||||
if (ima_adpcm.step_index<0)
|
||||
ima_adpcm.step_index=0;
|
||||
if (ima_adpcm.step_index>88)
|
||||
ima_adpcm.step_index=88;
|
||||
|
||||
diff = step >> 3 ;
|
||||
if (nibble & 1)
|
||||
diff += step >> 2 ;
|
||||
if (nibble & 2)
|
||||
diff += step >> 1 ;
|
||||
if (nibble & 4)
|
||||
diff += step ;
|
||||
if (nibble & 8)
|
||||
diff = -diff ;
|
||||
|
||||
ima_adpcm.predictor+=diff;
|
||||
if (ima_adpcm.predictor<-0x8000)
|
||||
ima_adpcm.predictor=-0x8000;
|
||||
else if (ima_adpcm.predictor>0x7FFF)
|
||||
ima_adpcm.predictor=0x7FFF;
|
||||
|
||||
|
||||
/* store loop if there */
|
||||
if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) {
|
||||
|
||||
ima_adpcm.loop_step_index = ima_adpcm.step_index;
|
||||
ima_adpcm.loop_predictor = ima_adpcm.predictor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float v=ima_adpcm.predictor/32767.0;
|
||||
if (v>max[0])
|
||||
max[0]=v;
|
||||
if (v<min[0])
|
||||
min[0]=v;
|
||||
}
|
||||
max[0]*=0.8;
|
||||
min[0]*=0.8;
|
||||
|
||||
for(int j=0;j<h;j++) {
|
||||
float v = (j/(float)h) * 2.0 - 1.0;
|
||||
uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3];
|
||||
if (v>min[0] && v<max[0]) {
|
||||
imgofs[0]=255;
|
||||
imgofs[1]=150;
|
||||
imgofs[2]=80;
|
||||
} else {
|
||||
imgofs[0]=0;
|
||||
imgofs[1]=0;
|
||||
imgofs[2]=0;
|
||||
}
|
||||
}
|
||||
float max = -1000;
|
||||
float min = 1000;
|
||||
int from = uint64_t(i) * frame_length / w;
|
||||
int to = uint64_t(i + 1) * frame_length / w;
|
||||
to = MIN(to, frame_length);
|
||||
from = MIN(from, frame_length - 1);
|
||||
if (to == from) {
|
||||
to = from + 1;
|
||||
}
|
||||
} else {
|
||||
for(int i=0;i<w;i++) {
|
||||
// i trust gcc will optimize this loop
|
||||
float max[2]={-1e10,-1e10};
|
||||
float min[2]={1e10,1e10};
|
||||
int c=stereo?2:1;
|
||||
int from = uint64_t(i)*len/w;
|
||||
int to = (uint64_t(i)+1)*len/w;
|
||||
if (to>=len)
|
||||
to=len-1;
|
||||
|
||||
if (_16) {
|
||||
const int16_t*src =(const int16_t*)sdata;
|
||||
for (int j = from; j < to; j++) {
|
||||
|
||||
for(int j=0;j<c;j++) {
|
||||
max = MAX(max, frames[j].l);
|
||||
max = MAX(max, frames[j].r);
|
||||
|
||||
for(int k=from;k<=to;k++) {
|
||||
min = MIN(min, frames[j].l);
|
||||
min = MIN(min, frames[j].r);
|
||||
}
|
||||
|
||||
float v = src[uint64_t(k)*c+j]/32768.0;
|
||||
if (v>max[j])
|
||||
max[j]=v;
|
||||
if (v<min[j])
|
||||
min[j]=v;
|
||||
}
|
||||
int pfrom = CLAMP((min * 0.5 + 0.5) * h / 2, 0, h / 2) + h / 4;
|
||||
int pto = CLAMP((max * 0.5 + 0.5) * h / 2, 0, h / 2) + h / 4;
|
||||
|
||||
}
|
||||
for (int j = 0; j < h; j++) {
|
||||
uint8_t *p = &imgw[(j * w + i) * 3];
|
||||
if (j < pfrom || j > pto) {
|
||||
p[0] = 100;
|
||||
p[1] = 100;
|
||||
p[2] = 100;
|
||||
} else {
|
||||
|
||||
const int8_t*src =(const int8_t*)sdata;
|
||||
|
||||
for(int j=0;j<c;j++) {
|
||||
|
||||
for(int k=from;k<=to;k++) {
|
||||
|
||||
float v = src[uint64_t(k)*c+j]/128.0;
|
||||
if (v>max[j])
|
||||
max[j]=v;
|
||||
if (v<min[j])
|
||||
min[j]=v;
|
||||
}
|
||||
|
||||
}
|
||||
p[0] = 180;
|
||||
p[1] = 180;
|
||||
p[2] = 180;
|
||||
}
|
||||
|
||||
max[0]*=0.8;
|
||||
max[1]*=0.8;
|
||||
min[0]*=0.8;
|
||||
min[1]*=0.8;
|
||||
|
||||
if (!stereo) {
|
||||
for(int j=0;j<h;j++) {
|
||||
float v = (j/(float)h) * 2.0 - 1.0;
|
||||
uint8_t* imgofs = &imgw[(j*w+i)*3];
|
||||
if (v>min[0] && v<max[0]) {
|
||||
imgofs[0]=255;
|
||||
imgofs[1]=150;
|
||||
imgofs[2]=80;
|
||||
} else {
|
||||
imgofs[0]=0;
|
||||
imgofs[1]=0;
|
||||
imgofs[2]=0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
for(int j=0;j<h;j++) {
|
||||
|
||||
int half;
|
||||
float v;
|
||||
if (j<(h/2)) {
|
||||
half=0;
|
||||
v = (j/(float)(h/2)) * 2.0 - 1.0;
|
||||
} else {
|
||||
half=1;
|
||||
if( (float)(h/2) != 0 ) {
|
||||
v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
|
||||
} else {
|
||||
v = ((j-(h/2))/(float)(1/2)) * 2.0 - 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* imgofs = &imgw[(j*w+i)*3];
|
||||
if (v>min[half] && v<max[half]) {
|
||||
imgofs[0]=255;
|
||||
imgofs[1]=150;
|
||||
imgofs[2]=80;
|
||||
} else {
|
||||
imgofs[0]=0;
|
||||
imgofs[1]=0;
|
||||
imgofs[2]=0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
imgdata = PoolVector<uint8_t>::Write();
|
||||
post_process_preview(img);
|
||||
//post_process_preview(img);
|
||||
|
||||
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture));
|
||||
ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB8,img),0);
|
||||
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
|
||||
Ref<Image> image;
|
||||
image.instance();
|
||||
image->create(w, h, false, Image::FORMAT_RGB8, img);
|
||||
ptex->create_from_image(image, 0);
|
||||
return ptex;
|
||||
|
||||
}
|
||||
|
||||
EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() {
|
||||
EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user