Ver código fonte

-support for stereo ima-adpcm sample compression & playback
-support for converting samples to ima-adpcm upon export

Juan Linietsky 9 anos atrás
pai
commit
61c4c5795f

+ 72 - 53
servers/audio/audio_mixer_sw.cpp

@@ -45,14 +45,14 @@ void AudioMixerSW::do_resample(const Depth* p_src, int32_t *p_dst, ResamplerStat
 	while (p_state->amount--) {
 
 		int32_t pos=p_state->pos >> MIX_FRAC_BITS;
-		if (is_stereo)
+		if (is_stereo && !is_ima_adpcm)
 			pos<<=1;
 
 		if (is_ima_adpcm) {
 
-			int sample_pos = pos + p_state->ima_adpcm->window_ofs;
+			int sample_pos = pos + p_state->ima_adpcm[0].window_ofs;
 
-			while(sample_pos>p_state->ima_adpcm->last_nibble) {
+			while(sample_pos>p_state->ima_adpcm[0].last_nibble) {
 
 
 				static const int16_t _ima_adpcm_step_table[89] = {
@@ -72,52 +72,64 @@ void AudioMixerSW::do_resample(const Depth* p_src, int32_t *p_dst, ResamplerStat
 					-1, -1, -1, -1, 2, 4, 6, 8
 				};
 
-				int16_t nibble,signed_nibble,diff,step;
+				for(int i=0;i<(is_stereo?2:1);i++) {
 
-				p_state->ima_adpcm->last_nibble++;
-				const uint8_t *src_ptr=p_state->ima_adpcm->ptr;
 
-				nibble = (p_state->ima_adpcm->last_nibble&1)?
-						(src_ptr[p_state->ima_adpcm->last_nibble>>1]>>4):(src_ptr[p_state->ima_adpcm->last_nibble>>1]&0xF);
-				step=_ima_adpcm_step_table[p_state->ima_adpcm->step_index];
+					int16_t nibble,signed_nibble,diff,step;
 
-				p_state->ima_adpcm->step_index += _ima_adpcm_index_table[nibble];
-				if (p_state->ima_adpcm->step_index<0)
-					p_state->ima_adpcm->step_index=0;
-				if (p_state->ima_adpcm->step_index>88)
-					p_state->ima_adpcm->step_index=88;
+					p_state->ima_adpcm[i].last_nibble++;
+					const uint8_t *src_ptr=p_state->ima_adpcm[i].ptr;
 
-				/*
-				signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
-				diff = (2 * signed_nibble + 1) * step / 4; */
 
-				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 ;
+					uint8_t nbb = src_ptr[ (p_state->ima_adpcm[i].last_nibble>>1) *  (is_stereo?2:1) + i ];
+					nibble = (p_state->ima_adpcm[i].last_nibble&1)?(nbb>>4):(nbb&0xF);
+					step=_ima_adpcm_step_table[p_state->ima_adpcm[i].step_index];
 
-				p_state->ima_adpcm->predictor+=diff;
-				if (p_state->ima_adpcm->predictor<-0x8000)
-					p_state->ima_adpcm->predictor=-0x8000;
-				else if (p_state->ima_adpcm->predictor>0x7FFF)
-					p_state->ima_adpcm->predictor=0x7FFF;
 
+					p_state->ima_adpcm[i].step_index += _ima_adpcm_index_table[nibble];
+					if (p_state->ima_adpcm[i].step_index<0)
+						p_state->ima_adpcm[i].step_index=0;
+					if (p_state->ima_adpcm[i].step_index>88)
+						p_state->ima_adpcm[i].step_index=88;
 
-				/* store loop if there */
-				if (p_state->ima_adpcm->last_nibble==p_state->ima_adpcm->loop_pos) {
+					/*
+					signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
+					diff = (2 * signed_nibble + 1) * step / 4; */
+
+					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 ;
+
+					p_state->ima_adpcm[i].predictor+=diff;
+					if (p_state->ima_adpcm[i].predictor<-0x8000)
+						p_state->ima_adpcm[i].predictor=-0x8000;
+					else if (p_state->ima_adpcm[i].predictor>0x7FFF)
+						p_state->ima_adpcm[i].predictor=0x7FFF;
+
+
+					/* store loop if there */
+					if (p_state->ima_adpcm[i].last_nibble==p_state->ima_adpcm[i].loop_pos) {
+
+						p_state->ima_adpcm[i].loop_step_index = p_state->ima_adpcm[i].step_index;
+						p_state->ima_adpcm[i].loop_predictor = p_state->ima_adpcm[i].predictor;
+					}
+
+					//printf("%i - %i - pred %i\n",int(p_state->ima_adpcm[i].last_nibble),int(nibble),int(p_state->ima_adpcm[i].predictor));
 
-					p_state->ima_adpcm->loop_step_index = p_state->ima_adpcm->step_index;
-					p_state->ima_adpcm->loop_predictor = p_state->ima_adpcm->predictor;
 				}
 
 			}
 
-			final=p_state->ima_adpcm->predictor;
+			final=p_state->ima_adpcm[0].predictor;
+			if (is_stereo) {
+				final_r=p_state->ima_adpcm[1].predictor;
+			}
 
 		} else {
 			final=p_src[pos];
@@ -399,9 +411,10 @@ void AudioMixerSW::mix_channel(Channel& c) {
 
 	if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
 
-		rstate.ima_adpcm=&c.mix.ima_adpcm;
+		rstate.ima_adpcm=c.mix.ima_adpcm;
 		if (loop_format!=AS::SAMPLE_LOOP_NONE) {
-			c.mix.ima_adpcm.loop_pos=loop_begin_fp>>MIX_FRAC_BITS;
+			c.mix.ima_adpcm[0].loop_pos=loop_begin_fp>>MIX_FRAC_BITS;
+			c.mix.ima_adpcm[1].loop_pos=loop_begin_fp>>MIX_FRAC_BITS;
 			loop_format=AS::SAMPLE_LOOP_FORWARD;
 		}
 	}
@@ -447,9 +460,11 @@ void AudioMixerSW::mix_channel(Channel& c) {
 					/* go to loop-begin */
 
 					if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
-						c.mix.ima_adpcm.step_index=c.mix.ima_adpcm.loop_step_index;
-						c.mix.ima_adpcm.predictor=c.mix.ima_adpcm.loop_predictor;
-						c.mix.ima_adpcm.last_nibble=loop_begin_fp>>MIX_FRAC_BITS;
+						for(int i=0;i<2;i++) {
+							c.mix.ima_adpcm[i].step_index=c.mix.ima_adpcm[i].loop_step_index;
+							c.mix.ima_adpcm[i].predictor=c.mix.ima_adpcm[i].loop_predictor;
+							c.mix.ima_adpcm[i].last_nibble=loop_begin_fp>>MIX_FRAC_BITS;
+						}
 						c.mix.offset=loop_begin_fp;
 					} else {
 						c.mix.offset=loop_begin_fp+(c.mix.offset-loop_end_fp);
@@ -549,10 +564,12 @@ void AudioMixerSW::mix_channel(Channel& c) {
 			CALL_RESAMPLE_MODE(int16_t,is_stereo,false,use_filter,use_fx,interpolation_type,mix_channels);
 
 		} else if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
-			c.mix.ima_adpcm.window_ofs=c.mix.offset>>MIX_FRAC_BITS;
-			c.mix.ima_adpcm.ptr=(const uint8_t*)data;
-			int8_t *src_ptr =  &((int8_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ];
-			CALL_RESAMPLE_MODE(int8_t,false,true,use_filter,use_fx,interpolation_type,mix_channels);
+			for(int i=0;i<2;i++) {
+				c.mix.ima_adpcm[i].window_ofs=c.mix.offset>>MIX_FRAC_BITS;
+				c.mix.ima_adpcm[i].ptr=(const uint8_t*)data;
+			}
+			int8_t *src_ptr =  NULL;
+			CALL_RESAMPLE_MODE(int8_t,is_stereo,true,use_filter,use_fx,interpolation_type,mix_channels);
 
 		}
 
@@ -781,14 +798,16 @@ AudioMixer::ChannelID AudioMixerSW::channel_alloc(RID p_sample) {
 
 	if (sample_manager->sample_get_format(c.sample)==AudioServer::SAMPLE_FORMAT_IMA_ADPCM) {
 
-		c.mix.ima_adpcm.step_index=0;
-		c.mix.ima_adpcm.predictor=0;
-		c.mix.ima_adpcm.loop_step_index=0;
-		c.mix.ima_adpcm.loop_predictor=0;
-		c.mix.ima_adpcm.last_nibble=-1;
-		c.mix.ima_adpcm.loop_pos=0x7FFFFFFF;
-		c.mix.ima_adpcm.window_ofs=0;
-		c.mix.ima_adpcm.ptr=NULL;
+		for(int i=0;i<2;i++) {
+			c.mix.ima_adpcm[i].step_index=0;
+			c.mix.ima_adpcm[i].predictor=0;
+			c.mix.ima_adpcm[i].loop_step_index=0;
+			c.mix.ima_adpcm[i].loop_predictor=0;
+			c.mix.ima_adpcm[i].last_nibble=-1;
+			c.mix.ima_adpcm[i].loop_pos=0x7FFFFFFF;
+			c.mix.ima_adpcm[i].window_ofs=0;
+			c.mix.ima_adpcm[i].ptr=NULL;
+		}
 	}
 
 	ChannelID ret_id = index+c.check*MAX_CHANNELS;

+ 1 - 1
servers/audio/audio_mixer_sw.h

@@ -105,7 +105,7 @@ private:
 				int32_t loop_pos;
 				int32_t window_ofs;
 				const uint8_t *ptr;
-			} ima_adpcm;
+			} ima_adpcm[2];
 
 		} mix;
 

+ 4 - 4
servers/audio/sample_manager_sw.cpp

@@ -38,12 +38,8 @@ SampleManagerSW::~SampleManagerSW()
 
 RID SampleManagerMallocSW::sample_create(AS::SampleFormat p_format, bool p_stereo, int p_length) {
 
-	ERR_EXPLAIN("IMA-ADPCM and STEREO are not a valid combination for sample format.");
-	ERR_FAIL_COND_V( p_format == AS::SAMPLE_FORMAT_IMA_ADPCM && p_stereo,RID());
 	Sample *s = memnew( Sample );
 	int datalen = p_length;
-	if (p_stereo)
-		datalen*=2;
 	if (p_format==AS::SAMPLE_FORMAT_PCM16)
 		datalen*=2;
 	else if (p_format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
@@ -53,6 +49,10 @@ RID SampleManagerMallocSW::sample_create(AS::SampleFormat p_format, bool p_stere
 		datalen/=2;
 		datalen+=4;
 	}
+
+	if (p_stereo)
+		datalen*=2;
+
 #define SAMPLE_EXTRA 16
 
 	s->data = memalloc(datalen+SAMPLE_EXTRA); //help the interpolator by allocating a little more..

+ 53 - 0
tools/editor/editor_import_export.cpp

@@ -1706,6 +1706,17 @@ void EditorImportExport::load_config() {
 		}
 	}
 
+	if (cf->has_section("convert_samples")) {
+
+		if (cf->has_section_key("convert_samples","max_hz"))
+			sample_action_max_hz=cf->get_value("convert_samples","max_hz");
+
+		if (cf->has_section_key("convert_samples","trim"))
+			sample_action_trim=cf->get_value("convert_samples","trim");
+	}
+
+
+
 }
 
 
@@ -1816,6 +1827,14 @@ void EditorImportExport::save_config() {
 
 	cf->set_value("script","encrypt_key",script_key);
 
+	switch(sample_action) {
+		case SAMPLE_ACTION_NONE: cf->set_value("convert_samples","action","none"); break;
+		case SAMPLE_ACTION_COMPRESS_RAM: cf->set_value("convert_samples","action","compress_ram"); break;
+	}
+
+	cf->set_value("convert_samples","max_hz",sample_action_max_hz);
+	cf->set_value("convert_samples","trim",sample_action_trim);
+
 	cf->save("res://export.cfg");
 
 }
@@ -1841,6 +1860,35 @@ String EditorImportExport::script_get_encryption_key() const{
 }
 
 
+void EditorImportExport::sample_set_action(SampleAction p_action) {
+
+	sample_action=p_action;
+}
+
+EditorImportExport::SampleAction EditorImportExport::sample_get_action() const{
+
+	return sample_action;
+}
+
+void EditorImportExport::sample_set_max_hz(int p_hz){
+
+	sample_action_max_hz=p_hz;
+}
+int EditorImportExport::sample_get_max_hz() const{
+
+	return sample_action_max_hz;
+}
+
+void EditorImportExport::sample_set_trim(bool p_trim){
+
+	sample_action_trim=p_trim;
+}
+bool EditorImportExport::sample_get_trim() const{
+
+	return sample_action_trim;
+}
+
+
 void EditorImportExport::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("image_export_group_create"),&EditorImportExport::image_export_group_create);
@@ -1868,8 +1916,13 @@ EditorImportExport::EditorImportExport() {
 	image_formats.insert("png");
 	image_shrink=1;
 
+
 	script_action=SCRIPT_ACTION_COMPILE;
 
+	sample_action=SAMPLE_ACTION_NONE;
+	sample_action_max_hz=44100;
+	sample_action_trim=false;
+
 }
 
 

+ 19 - 0
tools/editor/editor_import_export.h

@@ -245,6 +245,12 @@ public:
 		SCRIPT_ACTION_ENCRYPT
 	};
 
+	enum SampleAction {
+
+		SAMPLE_ACTION_NONE,
+		SAMPLE_ACTION_COMPRESS_RAM,
+	};
+
 protected:
 
 	struct ImageGroup {
@@ -274,6 +280,10 @@ protected:
 	ScriptAction script_action;
 	String script_key;
 
+	SampleAction sample_action;
+	int sample_action_max_hz;
+	bool sample_action_trim;
+
 	static EditorImportExport* singleton;
 
 	static void _bind_methods();
@@ -343,6 +353,15 @@ public:
 	void script_set_encryption_key(const String& p_key);
 	String script_get_encryption_key() const;
 
+	void sample_set_action(SampleAction p_action);
+	SampleAction sample_get_action() const;
+
+	void sample_set_max_hz(int p_hz);
+	int sample_get_max_hz() const;
+
+	void sample_set_trim(bool p_trim);
+	bool sample_get_trim() const;
+
 	void load_config();
 	void save_config();
 

+ 1 - 0
tools/editor/editor_node.cpp

@@ -5488,6 +5488,7 @@ EditorNode::EditorNode() {
 	editor_import_export->add_import_plugin( Ref<EditorTranslationImportPlugin>( memnew(EditorTranslationImportPlugin(this))));
 
 	editor_import_export->add_export_plugin( Ref<EditorTextureExportPlugin>( memnew(EditorTextureExportPlugin)));
+	editor_import_export->add_export_plugin( Ref<EditorSampleExportPlugin>( memnew(EditorSampleExportPlugin)));
 
 	add_editor_plugin( memnew( CanvasItemEditorPlugin(this) ) );
 	add_editor_plugin( memnew( SpatialEditorPlugin(this) ) );

+ 88 - 5
tools/editor/io_plugins/editor_sample_import_plugin.cpp

@@ -35,6 +35,7 @@
 #include "io/resource_saver.h"
 #include "os/file_access.h"
 #include "io/marshalls.h"
+#include "tools/editor/editor_settings.h"
 
 class _EditorSampleImportOptions : public Object {
 
@@ -156,7 +157,7 @@ public:
 		edit_normalize=true;
 		edit_loop=false;
 
-		compress_mode=COMPRESS_MODE_DISABLED;
+		compress_mode=COMPRESS_MODE_RAM;
 		compress_bitrate=COMPRESS_128;
 	}
 
@@ -580,8 +581,7 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
 
 	int compression = from->get_option("compress/mode");
 	bool force_mono = from->get_option("force/mono");
-	if (compression==_EditorSampleImportOptions::COMPRESS_MODE_RAM)
-		force_mono=true;
+
 
 	if (force_mono && chans==2) {
 
@@ -608,9 +608,47 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
 	if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) {
 
 		dst_format=Sample::FORMAT_IMA_ADPCM;
+		if (chans==1) {
+			_compress_ima_adpcm(data,dst_data);
+		} else {
+
+			print_line("INTERLEAAVE!");
+
+
+
+			//byte interleave
+			Vector<float> left;
+			Vector<float> right;
+
+			int tlen = data.size()/2;
+			left.resize(tlen);
+			right.resize(tlen);
+
+			for(int i=0;i<tlen;i++) {
+				left[i]=data[i*2+0];
+				right[i]=data[i*2+1];
+			}
+
+			DVector<uint8_t> bleft;
+			DVector<uint8_t> bright;
 
-		_compress_ima_adpcm(data,dst_data);
-		print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size()));
+			_compress_ima_adpcm(left,bleft);
+			_compress_ima_adpcm(right,bright);
+
+			int dl = bleft.size();
+			dst_data.resize( dl *2 );
+
+			DVector<uint8_t>::Write w=dst_data.write();
+			DVector<uint8_t>::Read rl=bleft.read();
+			DVector<uint8_t>::Read rr=bright.read();
+
+			for(int i=0;i<dl;i++) {
+				w[i*2+0]=rl[i];
+				w[i*2+1]=rr[i];
+			}
+		}
+
+//		print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size()));
 
 	} else {
 
@@ -781,9 +819,54 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D
 
 }
 
+
+EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL;
+
+
+
 EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) {
 
+	singleton=this;
 	dialog = memnew( EditorSampleImportDialog(this));
 	p_editor->get_gui_base()->add_child(dialog);
 }
 
+Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) {
+
+
+
+	if (EditorImportExport::get_singleton()->sample_get_action()==EditorImportExport::SAMPLE_ACTION_NONE || p_path.extension().to_lower()!="wav") {
+
+		return Vector<uint8_t>();
+	}
+
+	Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
+
+	imd->add_source(EditorImportPlugin::validate_source_path(p_path));
+
+	imd->set_option("force/8_bit",false);
+	imd->set_option("force/mono",false);
+	imd->set_option("force/max_rate",true);
+	imd->set_option("force/max_rate_hz",EditorImportExport::get_singleton()->sample_get_max_hz());
+	imd->set_option("edit/trim",EditorImportExport::get_singleton()->sample_get_trim());
+	imd->set_option("edit/normalize",false);
+	imd->set_option("edit/loop",false);
+	imd->set_option("compress/mode",1);
+
+	String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp");
+	Error err = EditorSampleImportPlugin::singleton->import(savepath,imd);
+
+
+	ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>());
+
+	p_path=p_path.basename()+".smp";
+	return FileAccess::get_file_as_array(savepath);
+
+}
+
+
+EditorSampleExportPlugin::EditorSampleExportPlugin() {
+
+}
+
+

+ 14 - 0
tools/editor/io_plugins/editor_sample_import_plugin.h

@@ -43,6 +43,8 @@ class EditorSampleImportPlugin : public EditorImportPlugin {
 	void _compress_ima_adpcm(const Vector<float>& p_data,DVector<uint8_t>& dst_data);
 public:
 
+	static EditorSampleImportPlugin *singleton;
+
 	virtual String get_name() const;
 	virtual String get_visible_name() const;
 	virtual void import_dialog(const String& p_from="");
@@ -52,4 +54,16 @@ public:
 	EditorSampleImportPlugin(EditorNode* p_editor);
 };
 
+class EditorSampleExportPlugin : public EditorExportPlugin {
+
+	OBJ_TYPE( EditorSampleExportPlugin, EditorExportPlugin);
+
+
+public:
+
+	virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform);
+
+	EditorSampleExportPlugin();
+};
+
 #endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H

+ 1 - 0
tools/editor/io_plugins/editor_texture_import_plugin.h

@@ -123,6 +123,7 @@ public:
 	virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform);
 	EditorTextureExportPlugin();
 };
+
 class EditorImportTextureOptions : public VBoxContainer {
 
 	OBJ_TYPE( EditorImportTextureOptions, VBoxContainer );

+ 7 - 1
tools/editor/plugins/editor_preview_plugins.cpp

@@ -491,8 +491,14 @@ Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) {
 					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[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF);
+							(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];

+ 7 - 1
tools/editor/plugins/sample_editor_plugin.cpp

@@ -156,8 +156,14 @@ void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<Imag
 					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[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF);
+							(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];

+ 33 - 0
tools/editor/project_export.cpp

@@ -252,6 +252,13 @@ void ProjectExportDialog::_script_edited(Variant v) {
 
 }
 
+void ProjectExportDialog::_sample_convert_edited(int what) {
+	EditorImportExport::get_singleton()->sample_set_action( EditorImportExport::SampleAction(sample_mode->get_selected()));
+	EditorImportExport::get_singleton()->sample_set_max_hz(  sample_max_hz->get_val() );
+	EditorImportExport::get_singleton()->sample_set_trim(  sample_trim->is_pressed() );
+
+}
+
 void ProjectExportDialog::_notification(int p_what) {
 
 	switch(p_what) {
@@ -319,6 +326,15 @@ void ProjectExportDialog::_notification(int p_what) {
 			_update_group();
 			_update_group_tree();
 
+			sample_mode->select( EditorImportExport::get_singleton()->sample_get_action() );
+			sample_max_hz->set_val( EditorImportExport::get_singleton()->sample_get_max_hz() );
+			sample_trim->set_pressed( EditorImportExport::get_singleton()->sample_get_trim() );
+
+			sample_mode->connect("item_selected",this,"_sample_convert_edited");
+			sample_max_hz->connect("value_changed",this,"_sample_convert_edited");
+			sample_trim->connect("toggled",this,"_sample_convert_edited");
+
+
 		} break;
 		case NOTIFICATION_EXIT_TREE: {
 
@@ -1045,6 +1061,7 @@ void ProjectExportDialog::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_group_select_none"),&ProjectExportDialog::_group_select_none);
 	ObjectTypeDB::bind_method(_MD("_script_edited"),&ProjectExportDialog::_script_edited);
 	ObjectTypeDB::bind_method(_MD("_update_script"),&ProjectExportDialog::_update_script);
+	ObjectTypeDB::bind_method(_MD("_sample_convert_edited"),&ProjectExportDialog::_sample_convert_edited);
 
 
 	ObjectTypeDB::bind_method(_MD("export_platform"),&ProjectExportDialog::export_platform);
@@ -1316,6 +1333,22 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
 	hbc->add_child(button_reload);
 */
 
+
+	sample_vbox = memnew( VBoxContainer );
+	sample_vbox->set_name("Samples");
+	sections->add_child(sample_vbox);
+	sample_mode = memnew( OptionButton );
+	sample_vbox->add_margin_child("Sample Conversion Mode: (.wav files):",sample_mode);
+	sample_mode->add_item("Keep");
+	sample_mode->add_item("Compress (RAM - IMA-ADPCM)");
+	sample_max_hz = memnew( SpinBox );
+	sample_max_hz->set_max(192000);
+	sample_max_hz->set_min(8000);
+	sample_vbox->add_margin_child("Sampling Rate Limit: (hz)",sample_max_hz);
+	sample_trim = memnew( CheckButton );
+	sample_trim->set_text("Trim");
+	sample_vbox->add_margin_child("Trailing Silence:",sample_trim);
+
 	script_vbox = memnew( VBoxContainer );
 	script_vbox->set_name("Script");
 	sections->add_child(script_vbox);

+ 6 - 0
tools/editor/project_export.h

@@ -139,6 +139,10 @@ private:
 	OptionButton *script_mode;
 	LineEdit *script_key;
 
+	VBoxContainer *sample_vbox;
+	OptionButton *sample_mode;
+	SpinBox *sample_max_hz;
+	CheckButton *sample_trim;
 
 
 	void _export_mode_changed(int p_idx);
@@ -162,6 +166,8 @@ private:
 	void _image_export_edited(int what);
 	void _shrink_edited(float what);
 
+	void _sample_convert_edited(int what);
+
 	void _update_group_list();
 	void _select_group(const String& p_by_name);