• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C++ audio::AudioStream类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中audio::AudioStream的典型用法代码示例。如果您正苦于以下问题:C++ AudioStream类的具体用法?C++ AudioStream怎么用?C++ AudioStream使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



在下文中一共展示了AudioStream类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: preFetchCompSpeech

uint32 Sound::preFetchCompSpeech(uint32 speechId, uint16 **buf) {
    int cd = _vm->_resman->getCD();
    uint32 numSamples;

    SoundFileHandle *fh = (cd == 1) ? &_speechFile[0] : &_speechFile[1];

    Audio::AudioStream *input = getAudioStream(fh, "speech", cd, speechId, &numSamples);

    if (!input)
        return 0;

    *buf = NULL;

    // Decompress data into speech buffer.

    uint32 bufferSize = 2 * numSamples;

    *buf = (uint16 *)malloc(bufferSize);
    if (!*buf) {
        delete input;
        fh->file.close();
        return 0;
    }

    uint32 readSamples = input->readBuffer((int16 *)*buf, numSamples);

    fh->file.close();
    delete input;

    return 2 * readSamples;
}
开发者ID:iPodLinux-Community,项目名称:iScummVM,代码行数:31,代码来源:music.cpp


示例2: playSoundData

void Sound::playSoundData(Audio::SoundHandle *handle, byte *soundData, uint sound, int pan, int vol, bool loop) {
	byte *buffer, flags;
	uint16 compType;
	int blockAlign, rate;

	int size = READ_LE_UINT32(soundData + 4);
	Common::MemoryReadStream stream(soundData, size);
	if (!Audio::loadWAVFromStream(stream, size, rate, flags, &compType, &blockAlign)) {
		error("playSoundData: Not a valid WAV data");
	}

	// The Feeble Files originally used DirectSound, which specifies volume
	// and panning differently than ScummVM does, using a logarithmic scale
	// rather than a linear one.
	//
	// Volume is a value between -10,000 and 0.
	// Panning is a value between -10,000 and 10,000.
	//
	// In both cases, the -10,000 represents -100 dB. When panning, only
	// one speaker's volume is affected - just like in ScummVM - with
	// negative values affecting the left speaker, and positive values
	// affecting the right speaker. Thus -10,000 means the left speaker is
	// silent.

	int v, p;

	vol = CLIP(vol, -10000, 0);
	pan = CLIP(pan, -10000, 10000);

	if (vol) {
		v = (int)((double)Audio::Mixer::kMaxChannelVolume * pow(10.0, (double)vol / 2000.0) + 0.5);
	} else {
		v = Audio::Mixer::kMaxChannelVolume;
	}

	if (pan < 0) {
		p = (int)(255.0 * pow(10.0, (double)pan / 2000.0) + 127.5);
	} else if (pan > 0) {
		p = (int)(255.0 * pow(10.0, (double)pan / -2000.0) - 127.5);
	} else {
		p = 0;
	}

	if (loop == true)
		flags |= Audio::Mixer::FLAG_LOOP;
	
	if (compType == 2) {
		Audio::AudioStream *sndStream = Audio::makeADPCMStream(&stream, size, Audio::kADPCMMS, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
		buffer = (byte *)malloc(size * 4);
		size = sndStream->readBuffer((int16*)buffer, size * 2);
		size *= 2; // 16bits.
		delete sndStream;
	} else {
		buffer = (byte *)malloc(size);
		memcpy(buffer, soundData + stream.pos(), size);
	}

	_mixer->playRaw(handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, -1, v, p);
}
开发者ID:iPodLinux-Community,项目名称:iScummVM,代码行数:59,代码来源:sound.cpp


示例3: cmdRawToWav

bool Console::cmdRawToWav(int argc, const char **argv) {
	if (argc != 3) {
		debugPrintf("Use %s <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n", argv[0]);
		return true;
	}

	Common::File file;
	if (!_engine->getSearchManager()->openFile(file, argv[1])) {
		warning("File not found: %s", argv[1]);
		return true;
	}

	Audio::AudioStream *audioStream = makeRawZorkStream(argv[1], _engine);

	Common::DumpFile output;
	output.open(argv[2]);

	output.writeUint32BE(MKTAG('R', 'I', 'F', 'F'));
	output.writeUint32LE(file.size() * 2 + 36);
	output.writeUint32BE(MKTAG('W', 'A', 'V', 'E'));
	output.writeUint32BE(MKTAG('f', 'm', 't', ' '));
	output.writeUint32LE(16);
	output.writeUint16LE(1);
	uint16 numChannels;
	if (audioStream->isStereo()) {
		numChannels = 2;
		output.writeUint16LE(2);
	} else {
		numChannels = 1;
		output.writeUint16LE(1);
	}
	output.writeUint32LE(audioStream->getRate());
	output.writeUint32LE(audioStream->getRate() * numChannels * 2);
	output.writeUint16LE(numChannels * 2);
	output.writeUint16LE(16);
	output.writeUint32BE(MKTAG('d', 'a', 't', 'a'));
	output.writeUint32LE(file.size() * 2);
	int16 *buffer = new int16[file.size()];
	audioStream->readBuffer(buffer, file.size());
#ifndef SCUMM_LITTLE_ENDIAN
	for (int i = 0; i < file.size(); ++i)
		buffer[i] = TO_LE_16(buffer[i]);
#endif
	output.write(buffer, file.size() * 2);

	delete[] buffer;


	return true;
}
开发者ID:Cruel,项目名称:scummvm,代码行数:50,代码来源:console.cpp


示例4: endOfData

bool LoopingAudioStream::endOfData() const {
	if (!_stream)
		return true;
	if (_loop)
		return false;
	return _stream->endOfData();
}
开发者ID:CatalystG,项目名称:scummvm,代码行数:7,代码来源:sound.cpp


示例5:

extern "C" int SimpleRate_readFudge(Audio::AudioStream &input, int16 *a, int b)
{
#ifdef DEBUG_RATECONV
	debug("Reading ptr=%x n%d", a, b);
#endif
	return input.readBuffer(a, b);
}
开发者ID:Deledrius,项目名称:residual,代码行数:7,代码来源:rate_arm.cpp


示例6: getAudioStream

void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) {
	Audio::Timestamp timeDiff = time.convertToFramerate(_wvInfo.samplesPerSec) - frameTime.convertToFramerate(_wvInfo.samplesPerSec);
	int skipFrames = timeDiff.totalNumberOfFrames();

	if (skipFrames <= 0)
		return;

	Audio::AudioStream *audioStream = getAudioStream();
	if (!audioStream)
		return;

	if (audioStream->isStereo())
		skipFrames *= 2;

	int16 *tempBuffer = new int16[skipFrames];
	audioStream->readBuffer(tempBuffer, skipFrames);
	delete[] tempBuffer;
}
开发者ID:Tkachov,项目名称:scummvm,代码行数:18,代码来源:avi_decoder.cpp


示例7: fprintf

extern "C" int SimpleRate_readFudge(Audio::AudioStream &input,
                                    int16 *a, int b)
{
#ifdef DEBUG_RATECONV
    fprintf(stderr, "Reading ptr=%x n%d\n", a, b);
    fflush(stderr);
#endif
    return input.readBuffer(a, b);
}
开发者ID:iPodLinux-Community,项目名称:iScummVM,代码行数:9,代码来源:rate_arm.cpp


示例8: queueBuffer

void AppendableSnd::queueBuffer(Common::SeekableReadStream *bufferIn) {
	assert (_as);

	// Setup the ADPCM decoder
	uint32 sizeIn = bufferIn->size();
	Audio::AudioStream *adpcm = makeDecoder(bufferIn, sizeIn);

	// Setup the output buffer
	uint32 sizeOut = sizeIn * 2;
	byte *bufferOut = new byte[sizeOut * 2];

	// Decode to raw samples
	sizeOut = adpcm->readBuffer((int16 *)bufferOut, sizeOut);
	assert (adpcm->endOfData());
	delete adpcm;

	// Queue the decoded samples
	_as->queueBuffer(bufferOut, sizeOut * 2);
}
开发者ID:jvprat,项目名称:scummvm-express,代码行数:19,代码来源:snd.cpp


示例9: readBuffer

int LoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
	if (!_loop) {
		return _stream->readBuffer(buffer, numSamples);
	}

	int16 *buf = buffer;
	int samplesLeft = numSamples;

	while (samplesLeft > 0) {
		int len = _stream->readBuffer(buf, samplesLeft);
		if (len < samplesLeft) {
			delete _stream;
			_stream = _parent->makeAudioStream(_loopSound);
		}
		samplesLeft -= len;
		buf += len;
	}

	return numSamples;
}
开发者ID:CatalystG,项目名称:scummvm,代码行数:20,代码来源:sound.cpp


示例10: convertRawToWav

void convertRawToWav(const Common::String &inputFile, ZVision *engine, const Common::String &outputFile) {
	Common::File file;
	if (!file.open(inputFile))
		return;

	Audio::AudioStream *audioStream = makeRawZorkStream(inputFile, engine);

	Common::DumpFile output;
	output.open(outputFile);

	output.writeUint32BE(MKTAG('R', 'I', 'F', 'F'));
	output.writeUint32LE(file.size() * 2 + 36);
	output.writeUint32BE(MKTAG('W', 'A', 'V', 'E'));
	output.writeUint32BE(MKTAG('f', 'm', 't', ' '));
	output.writeUint32LE(16);
	output.writeUint16LE(1);
	uint16 numChannels;
	if (audioStream->isStereo()) {
		numChannels = 2;
		output.writeUint16LE(2);
	} else {
		numChannels = 1;
		output.writeUint16LE(1);
	}
	output.writeUint32LE(audioStream->getRate());
	output.writeUint32LE(audioStream->getRate() * numChannels * 2);
	output.writeUint16LE(numChannels * 2);
	output.writeUint16LE(16);
	output.writeUint32BE(MKTAG('d', 'a', 't', 'a'));
	output.writeUint32LE(file.size() * 2);
	int16 *buffer = new int16[file.size()];
	audioStream->readBuffer(buffer, file.size());
	output.write(buffer, file.size() * 2);

	delete[] buffer;
}
开发者ID:lukaslw,项目名称:scummvm,代码行数:36,代码来源:utility.cpp


示例11:

	AudioStreamWrapper(Audio::AudioStream *stream) {
		_stream = stream;

		int rate = _stream->getRate();

		// A file where the sample rate claims to be 11025 Hz is
		// probably compressed with the old tool. We force the real
		// sample rate, which is 11840 Hz.
		//
		// However, a file compressed with the newer tool is not
		// guaranteed to have a sample rate of 11840 Hz. LAME will
		// automatically resample it to 12000 Hz. So in all other
		// cases, we use the rate from the file.

		if (rate == 11025)
			_rate = 11840;
		else
			_rate = rate;
	}
开发者ID:AReim1982,项目名称:scummvm,代码行数:19,代码来源:sound.cpp


示例12: load

bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader) {
	Audio::AudioStream *voxStream;
	size_t soundResourceLength;
	bool result = false;
	GameSoundTypes resourceType = kSoundPCM;
	byte *data = 0;
	int rate = 0, size = 0;
	Common::File* file;

	if (resourceId == (uint32)-1) {
		return false;
	}

#ifdef ENABLE_IHNM
	//TODO: move to resource_res so we can use normal "getResourceData" and "getFile" methods
	if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
		char soundFileName[40];
		int dirIndex = resourceId / 64;

		if ((context->fileType() & GAME_VOICEFILE) != 0) {
			if (_voiceSerial == 0) {
				sprintf(soundFileName, "Voices/VoicesS/Voices%d/VoicesS%03x", dirIndex, resourceId);
			} else {
				sprintf(soundFileName, "Voices/Voices%d/Voices%d/Voices%d%03x", _voiceSerial, dirIndex, _voiceSerial, resourceId);
			}
		} else {
			sprintf(soundFileName, "SFX/SFX%d/SFX%03x", dirIndex, resourceId);
		}

		file = new Common::File();

		file->open(soundFileName);
		soundResourceLength = file->size();
	} else
#endif
	{
		ResourceData* resourceData = context->getResourceData(resourceId);
		file = context->getFile(resourceData);

		file->seek(resourceData->offset);
		soundResourceLength = resourceData->size;
	}

	Common::SeekableReadStream& readS = *file;
	bool uncompressedSound = false;

	if (soundResourceLength >= 8) {
		byte header[8];

		readS.read(&header, 8);
		readS.seek(readS.pos() - 8);

		if (!memcmp(header, "Creative", 8)) {
			resourceType = kSoundVOC;
		} else if (!memcmp(header, "RIFF", 4) != 0) {
			resourceType = kSoundWAV;
		} else if (!memcmp(header, "FORM", 4) != 0) {
			resourceType = kSoundAIFF;
		} else if (!memcmp(header, "ajkg", 4) != 0) {
			resourceType = kSoundShorten;
		}

		// If patch data exists for sound resource 4 (used in ITE intro), don't treat this sound as compressed
		// Patch data for this resource is in file p2_a.iaf or p2_a.voc
		if (_vm->getGameId() == GID_ITE && resourceId == 4 && context->getResourceData(resourceId)->patchData != NULL)
			uncompressedSound = true;

		// FIXME: Currently, the SFX.RES file in IHNM cannot be compressed
		if (_vm->getGameId() == GID_IHNM && (context->fileType() & GAME_SOUNDFILE))
			uncompressedSound = true;

		if (context->isCompressed() && !uncompressedSound) {
			if (header[0] == char(0)) {
				resourceType = kSoundMP3;
			} else if (header[0] == char(1)) {
				resourceType = kSoundOGG;
			} else if (header[0] == char(2)) {
				resourceType = kSoundFLAC;
			}
		}

	}

	// Default sound type is 16-bit signed PCM, used in ITE by PCM and VOX files
	buffer.isCompressed = context->isCompressed();
	buffer.soundType = resourceType;
	buffer.originalSize = 0;
	// Set default flags and frequency for PCM, VOC and VOX files, which got no header
	buffer.flags = Audio::FLAG_16BITS;
	buffer.frequency = 22050;
	if (_vm->getGameId() == GID_ITE) {
		if (_vm->getFeatures() & GF_8BIT_UNSIGNED_PCM) {	// older ITE demos
			buffer.flags |= Audio::FLAG_UNSIGNED;
			buffer.flags &= ~Audio::FLAG_16BITS;
		} else {
			// Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded
			if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc"))
				resourceType = kSoundVOX;
		}
	}
//.........这里部分代码省略.........
开发者ID:Templier,项目名称:scummvm-test,代码行数:101,代码来源:sndres.cpp


示例13: getAudioStream

bool VideoDecoder::AudioTrack::endOfTrack() const {
	Audio::AudioStream *stream = getAudioStream();
	return !stream || !g_system->getMixer()->isSoundHandleActive(_handle) || stream->endOfData();
}
开发者ID:86400,项目名称:scummvm,代码行数:4,代码来源:video_decoder.cpp


示例14: playHESound


//.........这里部分代码省略.........
		if (READ_BE_UINT32(ptr) == MKID_BE('WSOU'))
			ptr += 8;

		size = READ_LE_UINT32(ptr + 4);
		Common::MemoryReadStream stream(ptr, size);

		if (!Audio::loadWAVFromStream(stream, size, rate, flags, &compType, &blockAlign)) {
			error("playHESound: Not a valid WAV file (%d)", soundID);
		}

		assert(heOffset >= 0 && heOffset < size);

		// FIXME: Disabled sound offsets, due to asserts been triggered
		heOffset = 0;

		_vm->setHETimer(heChannel + 4);
		_heChannel[heChannel].sound = soundID;
		_heChannel[heChannel].priority = priority;
		_heChannel[heChannel].rate = rate;
		_heChannel[heChannel].sbngBlock = (codeOffs != -1) ? 1 : 0;
		_heChannel[heChannel].codeOffs = codeOffs;
		memset(_heChannel[heChannel].soundVars, 0, sizeof(_heChannel[heChannel].soundVars));

		// TODO: Extra sound flags
		if (heFlags & 1) {
			flags |= Audio::Mixer::FLAG_LOOP;
			_heChannel[heChannel].timer = 0;
		} else {
			_heChannel[heChannel].timer = size * 1000 / rate;
		}

		_mixer->stopHandle(_heSoundChannels[heChannel]);
		if (compType == 17) {
			Audio::AudioStream *voxStream = Audio::makeADPCMStream(&stream, false, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);

			sound = (char *)malloc(size * 4);
			size = voxStream->readBuffer((int16*)sound, size * 2);
			size *= 2; // 16bits.
			delete voxStream;

			_heChannel[heChannel].rate = rate;
			if (_heChannel[heChannel].timer)
				_heChannel[heChannel].timer = size * 1000 / rate;

			flags |= Audio::Mixer::FLAG_AUTOFREE;
			_mixer->playRaw(type, &_heSoundChannels[heChannel], sound + heOffset, size - heOffset, rate, flags, soundID);
		} else {
			_mixer->playRaw(type, &_heSoundChannels[heChannel], ptr + stream.pos() + heOffset, size - heOffset, rate, flags, soundID);
		}
	}
	// Support for sound in Humongous Entertainment games
	else if (READ_BE_UINT32(ptr) == MKID_BE('DIGI') || READ_BE_UINT32(ptr) == MKID_BE('TALK')) {
		byte *sndPtr = ptr;
		int codeOffs = -1;

		priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18);
		rate = READ_LE_UINT16(ptr + 22);

		// Skip DIGI/TALK (8) and HSHD (24) blocks
		ptr += 32;

		if (_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
			int curSnd = _heChannel[heChannel].sound;
			if (curSnd == 1 && soundID != 1)
				return;
			if (curSnd != 0 && curSnd != 1 && soundID != 1 && _heChannel[heChannel].priority > priority)
开发者ID:havlenapetr,项目名称:Scummvm,代码行数:67,代码来源:sound_he.cpp


示例15: playHESound

void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
	Audio::RewindableAudioStream *stream = 0;
	byte *ptr, *spoolPtr;
	int size = -1;
	int priority, rate;
	byte flags = Audio::FLAG_UNSIGNED;

	Audio::Mixer::SoundType type = Audio::Mixer::kSFXSoundType;
	if (soundID > _vm->_numSounds)
		type = Audio::Mixer::kMusicSoundType;
	else if (soundID == 1)
		type = Audio::Mixer::kSpeechSoundType;


	if (heChannel == -1)
		heChannel = (_vm->VAR_RESERVED_SOUND_CHANNELS != 0xFF) ? findFreeSoundChannel() : 1;

	debug(5,"playHESound: soundID %d heOffset %d heChannel %d heFlags %d", soundID, heOffset, heChannel, heFlags);

	if (soundID >= 10000) {
		// Special codes, used in pjgames
		return;
	}

	if (soundID > _vm->_numSounds) {
		int music_offs;
		Common::File musicFile;
		Common::String buf(_vm->generateFilename(-4));

		if (musicFile.open(buf) == false) {
			warning("playHESound: Can't open music file %s", buf.c_str());
			return;
		}
		if (!getHEMusicDetails(soundID, music_offs, size)) {
			debug(0, "playHESound: musicID %d not found", soundID);
			return;
		}

		musicFile.seek(music_offs, SEEK_SET);

		_mixer->stopHandle(_heSoundChannels[heChannel]);
		spoolPtr = _vm->_res->createResource(rtSpoolBuffer, heChannel, size);
		assert(spoolPtr);
		musicFile.read(spoolPtr, size);
		musicFile.close();

		if (_vm->_game.heversion == 70) {
			stream = Audio::makeRawStream(spoolPtr, size, 11025, flags, DisposeAfterUse::NO);
			_mixer->playStream(type, &_heSoundChannels[heChannel], stream, soundID);
			return;
		}
	}

	if (soundID > _vm->_numSounds) {
		ptr = _vm->getResourceAddress(rtSpoolBuffer, heChannel);
	} else {
		ptr = _vm->getResourceAddress(rtSound, soundID);
	}

	if (!ptr) {
		return;
	}

	// Support for sound in later HE games
	if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F') || READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) {
		uint16 compType;
		int blockAlign;
		int codeOffs = -1;

		priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18);

		byte *sbngPtr = findSoundTag(MKTAG('S','B','N','G'), ptr);
		if (sbngPtr != NULL) {
			codeOffs = sbngPtr - ptr + 8;
		}

		if (_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
			int curSnd = _heChannel[heChannel].sound;
			if (curSnd == 1 && soundID != 1)
				return;
			if (curSnd != 0 && curSnd != 1 && soundID != 1 && _heChannel[heChannel].priority > priority)
				return;
		}

		if (READ_BE_UINT32(ptr) == MKTAG('W','S','O','U'))
			ptr += 8;

		size = READ_LE_UINT32(ptr + 4);
		Common::MemoryReadStream memStream(ptr, size);

		if (!Audio::loadWAVFromStream(memStream, size, rate, flags, &compType, &blockAlign)) {
			error("playHESound: Not a valid WAV file (%d)", soundID);
		}

		assert(heOffset >= 0 && heOffset < size);

		// FIXME: Disabled sound offsets, due to asserts been triggered
		heOffset = 0;

		_vm->setHETimer(heChannel + 4);
//.........这里部分代码省略.........
开发者ID:St0rmcrow,项目名称:scummvm,代码行数:101,代码来源:sound_he.cpp


示例16: getChannels

	uint getChannels() const { return _stream->getChannels(); }
开发者ID:waltervn,项目名称:cabal-1,代码行数:1,代码来源:sound.cpp


示例17: isStereo

	bool isStereo() const { return _stream ? _stream->isStereo() : 0; }
开发者ID:CatalystG,项目名称:scummvm,代码行数:1,代码来源:sound.cpp


示例18: getRate

	int getRate() const { return _stream ? _stream->getRate() : 22050; }
开发者ID:CatalystG,项目名称:scummvm,代码行数:1,代码来源:sound.cpp


示例19: endOfStream

	bool endOfStream() const {
		return _stream->endOfStream();
	}
开发者ID:AReim1982,项目名称:scummvm,代码行数:3,代码来源:sound.cpp


示例20: endOfData

	bool endOfData() const {
		return _stream->endOfData();
	}
开发者ID:AReim1982,项目名称:scummvm,代码行数:3,代码来源:sound.cpp



注:本文中的audio::AudioStream类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ audio::GainNodeRef类代码示例发布时间:2022-05-31
下一篇:
C++ attributematrix::Pointer类代码示例发布时间:2022-05-31
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap