Exemplo n.º 1
1
//--------------------------------------------------------------
void SoundManager::playSound(string name, bool isLoop, float volume, int* speakers,int nbSpeakers)
{
    SoundPlayer* pSoundPlayer = getSoundPlayer(name);
    if (pSoundPlayer)
	{
		if (speakers == 0)
	        pSoundPlayer->play();
     	else
	        pSoundPlayer->playTo(speakers,nbSpeakers);
	 
		pSoundPlayer->setLoop(isLoop);
        pSoundPlayer->setVolume(volume);
    }
}
Exemplo n.º 2
0
//--------------------------------------------------------------
void SoundManager::setup(ofxXmlSettings& settings)
{

	m_driver = settings.getValue("murmur:soundOutput:driver", 0);
	printf("- setting sound output driver [%d]\n", m_driver);
	ofFmodSelectDriver(m_driver);

	m_driver = ofFmodGetDriverSelected();
	printf("- selected driver is [%d]\n", m_driver);

	int nbOutputs = settings.getValue("murmur:soundOutput:nbSpeakers", 2);
	printf("- setting sound output for %d speakers\n", nbOutputs);
	ofFmodSetNumOutputs( nbOutputs );

		settings.pushTag("murmur");
		settings.pushTag("soundOutput");
		settings.pushTag("soundMain");
		int nbSpeakers = settings.getNumTags("speaker");
		mp_soundMainSpeakers = new int[nbSpeakers];
		for (int i=0;i<nbSpeakers;i++)
		{
			mp_soundMainSpeakers[i] = settings.getValue("speaker",0,i);
	        printf("- adding for sound main speaker [%d]\n", i);
		}
		m_nbSoundMainSpeakers = nbSpeakers;
		settings.popTag();
		settings.popTag();

	string soundMainFile = settings.getAttribute("murmur:soundOutput:soundMain","file", "main.wav");
	printf("- sound main is [%s]\n", soundMainFile.c_str());


	ofDirectory dirSounds("Sounds");
	if (dirSounds.exists())
	{
		dirSounds.listDir();
		printf("DIR %s [%d file(s)]\n", dirSounds.path().c_str(),dirSounds.size());
        
		vector<ofFile> files = dirSounds.getFiles();
		vector<ofFile>::iterator it;
		for (it = files.begin(); it != files.end(); ++it)
        {
            if ((*it).getExtension() == "mp3" || (*it).getExtension() == "wav")
			{
                string filename = (*it).getFileName();

                printf("- [%s]\n", filename.c_str());
                
                SoundPlayer* pSoundPlayer = new SoundPlayer(filename);
                pSoundPlayer->loadSound( "Sounds/"+filename );
                pSoundPlayer->setLoop(false);
                pSoundPlayer->setMultiPlay(true);

                m_listSoundPlayer.push_back( pSoundPlayer );
            }
        }
    }

	mp_soundMain = getSoundPlayer(soundMainFile);
}
Exemplo n.º 3
0
void EmulApp::trigSound(int sndtrig)
{
    const bool dostop = sndtrig < 0;    
    const unsigned snd = dostop ? -sndtrig : sndtrig;
    lastSndEvt = sndtrig;

    SoundPlayerMap::iterator it = soundPlayerMap.find(snd);
    SoundPlayer *sp = 0;
    if (it == soundPlayerMap.end()) {
        Error() << "Triggered unknown sound " << snd;
        return;
    }
    else sp = it->second;
    Debug() << "Got sound trig " << sndtrig << " for filename `" << sp->fileName() << "'";
    if (dostop) {
        //Debug() << "sound " << snd << " stop";
        sp->stop();
        controlwin->untriggeredSound(snd);
    } else {
        //Debug() << "sound " << snd << " play";
        sp->stop();
        sp->play();
        controlwin->triggeredSound(snd);
    }    
}
Exemplo n.º 4
0
// 初期化
void FirstSceneController::onInit() {
	LOGD("FirstSceneController::onInit()");
	
	ApplicationController *ctr = ApplicationController::SharedInstance();
	
	// 音読み込み
	int bgmid = SoundPlayer::loadBGM("sound/bgm_house.ogg");
	SoundPlayer *player = SoundPlayer::SharedInstance();
	player->play(bgmid);
	sid = SoundPlayer::loadSE("sound/se_yay.ogg");
	
	// シーン作成
	Scene_ptr sceneMain(new Scene("SceneFirst"));
	// プレート追加
	Figure_ptr fig;
	fig = Figure_ptr(new Figure("Fig"));
	fig->mesh = PrimitiveObject::createPlate(Sizef(5, 5));
	// マテリアルとシェーダー設定
	fig->material = Material_ptr(new Material());
	fig->material->texture0 = Texture_ptr(new Texture("model/gclue_logo.png"));
	fig->material->ambientColor = Colorf(0, 0, 0.5);
//	fig->shader = ShaderManager::GetShader(ShaderTypeColor);
//	fig->shader = ShaderManager::GetShader(ShaderTypeFlat);
	fig->shader = ShaderManager::GetShader(ShaderTypeTex);
	fig->transform.translate(0, 3, 0);
	fig->touchEventListener = this;
	fig->isTouchable = true;
	
	// シーン変更
	sceneMain->addChildNode(fig);
	ctr->sceneMap[1] = sceneMain;
	ctr->changeScene(1);
}
Exemplo n.º 5
0
bool UpdateMap(std::shared_ptr<VisibleObject> &player,
               std::vector<std::shared_ptr<VisibleObject> > &objectVec, Map &map,
               unsigned int &score, SoundPlayer &soundPlayer,
               ResourceManager &resMan)
{
    bool powerPill(false);
    glm::ivec2 where((int)(player->GetX()),
                     (int)(player->GetY()));
    Object obj(map.GetWhichObject(where));
    if(obj == Object::tree || obj == Object::powerPill || obj == Object::specialObject)
    {
        UpdateObject(where, map, player->GetPlayer(), objectVec);
        switch(obj)
        {
        case Object::tree:
            score += 10;
            soundPlayer.AddToPlay(*(resMan.GetSound("chop.ogg")));
            break;
        case Object::powerPill:
            score += 10;
            soundPlayer.AddToPlay(*(resMan.GetSound("chainsaw.ogg")));
            powerPill = true;
            break;
        case Object::specialObject:
            soundPlayer.AddToPlay(*(resMan.GetSound("woodpile.ogg")));
            score += 100;
            break;
        default:
            break;
        }
    }
    return powerPill;
}
Exemplo n.º 6
0
Status SoundManager::createMeidaPlayer( SoundClip* clip )
{
    SoundPlayer* newPlayer = new SoundPlayer();
    newPlayer->init( clip );

    connect( newPlayer, &SoundPlayer::durationChanged, this, &SoundManager::onDurationChanged );

    return Status::OK;
}
Exemplo n.º 7
0
int main(int argc, char** argv)
{
    QApplication app(argc,argv);
    SoundPlayer sp;
    app.setMainWidget(&sp);
    sp.setCaption("Qt Example - Sounds");
    sp.show();
    return app.exec();
}
Exemplo n.º 8
0
// ノードタッチイベント
void FirstSceneController::onTouchNode(TouchableNode& node, const TouchEvent &event) {
	if (event.action == TouchActionDown) {
		// 音再生
		SoundPlayer *player = SoundPlayer::SharedInstance();
		player->play(sid);
		// シーン遷移
		ApplicationController *ctr = ApplicationController::SharedInstance();
		ctr->changeScene(2);
		// サブウィンドウ表示
		Window_ptr mainWindow = ctr->windowArray[1];
		mainWindow->isVisible = true;
	}
}
int main() {

    SoundPlayer soundPlayer = SoundPlayer();
    Mp3Decoder mp3Decoder = Mp3Decoder();
    MicRecorder micRecorder = MicRecorder();

    unsigned char buffer[BUFSIZE*50] = {};
    unsigned char recBuffer[BUFSIZE*50] = {};

    // Put path to file here
    std::string path = "smw_coin.mp3";
    // TODO: Manage more than int16_t encoding format, mono and 44.1kHz
    Mp3Format mp3Format = mp3Decoder.Open(path);
    //std::cout << "encoding: " << mp3Format.encoding << std::endl;
    //std::cout << "channels: " << mp3Format.channels << std::endl;
    //std::cout << "rate: " << mp3Format.rate << std::endl;

    int decodeNumber = 0;

    int decodedQty = 0;
    while ((decodedQty = mp3Decoder.Decode(buffer+decodeNumber*BUFSIZE, BUFSIZE)) > 0) {

        soundPlayer.Play(buffer+decodeNumber*BUFSIZE, decodedQty);

        // Record some data in the buffer
        micRecorder.Record(recBuffer+decodeNumber*BUFSIZE, decodedQty);

        decodeNumber++;
    }
    unsigned int samplesQty = (decodeNumber-1)*BUFSIZE/sizeof(int16_t)+decodedQty;

    mp3Decoder.Close();

    // Process the signals as wanted here
    int delay = SignalProcessor::GetDelay((int16_t*)buffer, (int16_t*)recBuffer, samplesQty);
    SignalProcessor::Delay((int16_t*)buffer, samplesQty, delay);
    SignalProcessor::Scale((int16_t*)buffer, samplesQty, 1, 2);
    SignalProcessor::Subtract((int16_t*)recBuffer, (int16_t*)buffer, samplesQty);

    // Play back for more fun
    for (unsigned int i = 0; i < decodeNumber; i++) {

        soundPlayer.Play(recBuffer+i*BUFSIZE, BUFSIZE);

    }

    printToFile(samplesQty, {(int16_t*)buffer, (int16_t*)recBuffer});

}
Exemplo n.º 10
0
int SoundDataManager::loadFromFile(const char* pFilePath)
{
    int nSoundID = 0;

    do
    {
        BREAK_IF(! FileUtils::isFileExisted(pFilePath));
        int nID = BKDRHash(pFilePath);

        // if we have loaded the file before,break
        tEffectElement *pElement = NULL;
        HASH_FIND_INT(m_pEffects, &nID, pElement);
        if (pElement)
        {
            nSoundID = nID;
            break;
        }

        // calculate the buffer size we needed
        SoundPlayer TempPlayer;
        int nBufferSize = TempPlayer.GetFileBufferSize(pFilePath);
        // can not calculate the size,load failed
        BREAK_IF(nBufferSize < 0);

        // load the file data
        unsigned char* buffer = NULL;
        buffer = new unsigned char[nBufferSize];
        BREAK_IF(!buffer);
        int nSize = TempPlayer.DecodeFile(buffer, nBufferSize, pFilePath);
        BREAK_IF(nSize < 0);

        // record the id
        nSoundID = nID;

        // add the data to hash map
        pElement = (tEffectElement*)calloc(sizeof(*pElement), 1);
        pElement->nSoundID    = nSoundID;
        pElement->pDataBuffer = buffer;
        pElement->nDataSize   = nBufferSize;
        pElement->FileName    = "";
        pElement->nPlayerSoundID = -1;
        HASH_ADD_INT(m_pEffects, nSoundID, pElement);
    } while (0);

    return nSoundID;
}
Exemplo n.º 11
0
gboolean SoundPlayer::checkBuffer(gpointer data) {
	// Cast the passed pointer onto self
	SoundPlayer* self = reinterpret_cast<SoundPlayer*>(data);

	// Check for active source and buffer
	if (self->_source != 0 && self->_buffer != 0) {
		ALint state;
		// Query the state of the source
		alGetSourcei(self->_source, AL_SOURCE_STATE, &state);
		if (state == AL_STOPPED) {
			// Erase the buffer
			self->clearBuffer();

			// Disable the timer to stop calling this function
			self->_timer.disable();
			return false;
		}
	}

	// Return true, so that the timer gets called again
	return true;
}
Exemplo n.º 12
0
void AudioView::OnPlayButton()
{
  SoundPlayer player;
  double plays0 = sel0;
  double plays1 = sel1;

  if (sel0 == sel1) {
	plays0 = 0.0;
	plays1 = 10000000000.0;
  }

  TrackList *tracks = GetTracks();
  VTrack *t = tracks->First();  
  while(t) {
	if (t->selected && t->GetKind() == (VTrack::Wave)) {
	  player.Begin((WaveTrack *)t, plays0, plays1);
	  return;
	}
	
	t = tracks->Next();
  }
}
Exemplo n.º 13
0
  void update(const double progressing_seconds) noexcept override {
    for (auto& controller : children_) {
      controller->update(progressing_seconds);
    }
    
    // 無効なControllerを削除
    boost::remove_erase_if(children_,
                           [](ControllerPtr& child) {
                             return !child->isActive();
                           });

    // 予約されたサウンドを再生
    player_.update(sound_);
  }
Exemplo n.º 14
0
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void EffectNodeImplemented::PlaySound_(Instance& instance, SoundTag tag, Manager* manager)
{
	SoundPlayer* player = manager->GetSoundPlayer();
	if( player == NULL )
	{
		return;
	}

	if( Sound.WaveId >= 0 )
	{
		SoundPlayer::InstanceParameter parameter;
		parameter.Data = m_effect->GetWave( Sound.WaveId );
		parameter.Volume = Sound.Volume.getValue( *manager );
		parameter.Pitch = Sound.Pitch.getValue( *manager );
		parameter.Pan = Sound.Pan.getValue( *manager );
		
		parameter.Mode3D = (Sound.PanType == ParameterSoundPanType_3D);
		Vector3D::Transform( parameter.Position, 
			Vector3D(0.0f, 0.0f, 0.0f), instance.GetGlobalMatrix43() );
		parameter.Distance = Sound.Distance;

		player->Play( tag, parameter );
	}
}
Exemplo n.º 15
0
	void playSPVoice(int vtrack) {
		sp.playVoice(vtrack);
	}
Exemplo n.º 16
0
//--------------------------------------------------------------
void SoundManager::setup(ofxXmlSettings& settings)
{
	OFAPPLOG->begin("SoundManager::setup()");

	m_driver = settings.getValue("murmur:soundOutput:driver", 0);
	OFAPPLOG->println(" - setting sound output driver ["+ofToString(m_driver)+"]");
	ofFmodSelectDriver(m_driver);

	m_driver = ofFmodGetDriverSelected();
	OFAPPLOG->println(" - selected driver is "+ofToString(m_driver));

	int nbOutputs = settings.getValue("murmur:soundOutput:nbSpeakers", 2);
	OFAPPLOG->println(" - setting sound output for "+ofToString(nbOutputs)+" speaker(s)");
	ofFmodSetNumOutputs( nbOutputs );

		settings.pushTag("murmur");
		settings.pushTag("soundOutput");
		settings.pushTag("soundMain");
		int nbSpeakers = settings.getNumTags("speaker");
		mp_soundMainSpeakers = new int[nbSpeakers];
		for (int i=0;i<nbSpeakers;i++)
		{
			mp_soundMainSpeakers[i] = settings.getValue("speaker",0,i);
			OFAPPLOG->println(" - adding for sound main speaker ["+ofToString(i)+"]");
		}
		m_nbSoundMainSpeakers = nbSpeakers;
		settings.popTag();
		settings.popTag();

	string soundMainFile = settings.getAttribute("murmur:soundOutput:soundMain","file", "main.wav");
	OFAPPLOG->println(" - sound main is '"+soundMainFile+"'");


	ofDirectory dirSounds("Sounds");
	if (dirSounds.exists())
	{
		dirSounds.listDir();
		OFAPPLOG->println(" - DIR is '"+dirSounds.path()+"' ["+ofToString(dirSounds.size())+" file(s)]");
     
		vector<ofFile> files = dirSounds.getFiles();
		vector<ofFile>::iterator it;
		string strFileNames = "";
		string strFileNamesSep = "";
		for (it = files.begin(); it != files.end(); ++it)
        {
            if ((*it).getExtension() == "mp3" || (*it).getExtension() == "wav")
			{
                string filename = (*it).getFileName();

                strFileNames += strFileNamesSep + filename;
                
                SoundPlayer* pSoundPlayer = new SoundPlayer(filename);
                pSoundPlayer->loadSound( "Sounds/"+filename );
                pSoundPlayer->setLoop(false);
                pSoundPlayer->setMultiPlay(true);

                m_listSoundPlayer.push_back( pSoundPlayer );

				strFileNamesSep = ", ";
            }
        }

		OFAPPLOG->println(" - FILES are '"+strFileNames+"'");
    }
	mp_soundMain = getSoundPlayer(soundMainFile);

	OFAPPLOG->end();
}
Exemplo n.º 17
0
//--------------------------------------------------------------
void SoundManager::setVolume(string name, float volume)
{
    SoundPlayer* pSoundPlayer = getSoundPlayer(name);
    if (pSoundPlayer)
        pSoundPlayer->setVolume(volume);
}
Exemplo n.º 18
0
  RootController(ci::JsonTree& params,
                 ci::TimelineRef timeline,
                 Event<std::vector<Touch> >& touch_event) noexcept :
    params_(params),
    timeline_(timeline),
    ui_camera_(createCamera(params["ui_view.camera"])),
    fov_(ui_camera_.getFov()),
    near_z_(ui_camera_.getNearClip()),
    far_z_(ui_camera_.getFarClip()),
    autolayout_(ui_camera_),
    touch_event_(touch_event),
    view_creator_(params, timeline, ui_camera_, autolayout_, event_, touch_event),
    sound_(params["sounds"]),
    background_(Json::getColor<float>(params["app.background"])),
    records_(params["version"].getValue<float>())
  {
    DOUT << "RootController()" << std::endl;
    
    event_.connect("begin-progress",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<ProgressController>(params_, timeline_, event_,
                                                       view_creator_.create("ui_progress.json"));
                   });
    
    event_.connect("begin-gameover",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<GameoverController>(params_, timeline_, event_,
                                                       param,
                                                       view_creator_.create("ui_gameover.json"));
                   });

    event_.connect("begin-stageclear",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<StageclearController>(params_, timeline_, event_, param,
                                                         view_creator_.create("ui_stageclear.json"));
                   });

    event_.connect("begin-pause",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<PauseController>(params_, timeline_, event_,
                                                    view_creator_.create("ui_pause.json"));
                   });

    event_.connect("begin-records",
                   [this](const Connection&, EventParam& param) noexcept {
                     EventParam records = {
                       { "total_play",  records_.getTotalPlayNum() },
                       { "total_time",  records_.getTotalPlayTime() },
                       { "high_score",  records_.getHighScore() },
                       { "total_item",  records_.getTotalItemNum() },
                       { "stage_ranks", records_.stageRanks() },
                     };
                     
                     addController<RecordsController>(params_, timeline_, event_, records,
                                                      view_creator_.create("ui_records.json"));
                   });

    event_.connect("begin-credits",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<CreditsController>(params_, timeline_, event_,
                                                      view_creator_.create("ui_credits.json"));
                   });

    event_.connect("begin-title",
                   [this](const Connection&, EventParam& param) noexcept {
                     startTitle(param);
                   });

    event_.connect("begin-settings",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<SettingsController>(params_, timeline_, event_, records_,
                                                       view_creator_.create("ui_settings.json"));
                   });

    event_.connect("begin-regulat-stageclear",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<AllStageClearController>(params_["regular_stageclear"], timeline_, event_,
                                                            param,
                                                            view_creator_.create("ui_regularstageclear.json"));
                   });

    event_.connect("begin-all-stageclear",
                   [this](const Connection&, EventParam& param) noexcept {
                     addController<AllStageClearController>(params_["all_stageclear"], timeline_, event_,
                                                            param,
                                                            view_creator_.create("ui_allstageclear.json"));
                   });

    // GameOver時に色々チェック
    event_.connect("check-after-gameover",
                   [this](const Connection&, EventParam& param) noexcept {
                     DOUT << "check-after-gameover" << std::endl;
                     Rating::popup([this]() {
                         AppSupport::pauseDraw(true);
                       },
                       [this]() {
                         AppSupport::pauseDraw(false);
                       });
                     Achievment::atGameOver(records_);
                   });

    // サウンド再生
    event_.connect("sound-play",
                   [this](const Connection&, EventParam& param) noexcept {
                     auto& name = boost::any_cast<const std::string&>(param.at("sound"));
                     player_.play(name);
                     // DOUT << "sound:" << name << std::endl;
                   });

    
    event_.connect("se-silent",
                   [this](const Connection&, EventParam& param) noexcept {
                     sound_.setBufferSilent(boost::any_cast<bool>(param["silent"]));
                   });

    event_.connect("bgm-silent",
                   [this](const Connection&, EventParam& param) noexcept {
                     sound_.setFileSilent(boost::any_cast<bool>(param["silent"]));
                   });

    
#ifdef DEBUG
    event_.connect("force-regular-completed",
                   [this](const Connection&, EventParam& param) noexcept {
                     records_.forceRegularStageComplated();
                   });

    event_.connect("cancel-regular-completed",
                   [this](const Connection&, EventParam& param) noexcept {
                     records_.cancelRegularStageComplated();
                   });

    event_.connect("clear-records",
                   [this](const Connection&, EventParam& param) noexcept {
                     records_ = Records(params_["version"].getValue<float>());
                   });

    event_.connect("do-snapshot",
                   [this](const Connection&, EventParam& param) noexcept {
                     auto surface = ci::app::copyWindowSurface();
                     auto full_path = getDocumentPath() / std::string("snapshot" + createUniquePath() + ".png");
                     ci::writeImage(full_path, surface);
                   });
    
    event_.connect("reset-records",
                   [this](const Connection&, EventParam& param) noexcept {
                     records_ = Records(params_["version"].getValue<float>());
                   });
    
    event_.connect("reset-achievement",
                   [this](const Connection&, EventParam& param) noexcept {
                     DOUT << "reset-achievement" << std::endl;
                     GameCenter::resetAchievement();
                   });
#endif

    records_.load(params["game.records"].getValue<std::string>());
    
    sound_.setBufferSilent(!records_.isSeOn());
    sound_.setFileSilent(!records_.isBgmOn());
      
    addController<FieldController>(params, touch_event_, event_, records_);

    addController<IntroController>(params_, timeline_, event_,
                                   records_.getTotalPlayNum(),
                                   view_creator_.create("ui_intro.json"));

    // 自動PAUSE
    // getSignalDidEnterBackground(Backgroundになった直後)
    // getSignalWillResignActive(アクティブでなくなる直前)
    resign_active_ = ci::app::App::get()->getSignalWillResignActive().connect([this]() noexcept {
        DOUT << "SignalWillResignActive" << std::endl;
        EventParam params = {
          { "force", true }
        };
        event_.signal("pause-agree", params);
        
        GameCenter::writeCachedAchievement();
      });
  }
Exemplo n.º 19
0
	void SPDropEngine() {
		sp.dropEngine();
	}
Exemplo n.º 20
0
	void stopSPBGM() {
		sp.stopBGM();
	}
Exemplo n.º 21
0
	void playSPSFX(int strack) {
		sp.playSFX(strack);
	}
Exemplo n.º 22
0
	void playSPBGM(int track) {
		sp.playBGM(track);
	}
Exemplo n.º 23
0
	void setSPBGMVolume(float v) {
		sp.setBGMVolume(v);
	}
Exemplo n.º 24
0
OSDComponent *SkinV2::VolumeOSD() {
    OSDComponent *volume = new OSDComponent;

    /* Images */
    volume->background = LoadImg(_skinDir + L"\\OSD\\back.png");
    volume->mask = LoadImg(_skinDir + L"\\OSD\\glassMask.png");

    /* Sound */
    std::wstring soundName = _skinDir + L"\\sound.wav";
    SoundPlayer *player = new SoundPlayer(soundName);
    if (player->Ready() == false) {
        delete player;
        player = NULL;
    }
    volume->sound = player;

    /* Determine the number of units */
    int units = 10;
    tinyxml2::XMLElement *meterMax = SubElement("osd", "meterMax");
    if (meterMax) {
        meterMax->QueryIntText(&units);
    }
    volume->defaultUnits = units;

    /* Load the meter(s) */
    const char *type = nullptr;
    tinyxml2::XMLElement *meterOrientation
        = SubElement("osd", "meterOrientation");
    if (meterOrientation) {
        type = meterOrientation->GetText();
    }
    int x = 0;
    int y = 0;
    tinyxml2::XMLElement *pos = SubElement("osd", "meterPosition");
    if (pos) {
        tinyxml2::XMLElement *xelem = pos->FirstChildElement("X");
        tinyxml2::XMLElement *yelem = pos->FirstChildElement("Y");
        if (xelem) {
            xelem->QueryIntText(&x);
        }
        if (yelem) {
            yelem->QueryIntText(&y);
        }
    }

    std::wstring meterImg = _skinDir + L"\\OSD\\meter.png";
    std::string meterType(type);
    if (meterType == "vertical") {
        volume->meters.push_back(
            new VerticalBar(meterImg, x, y, units));
    } else if (meterType == "bitstrip") {
        /* For some reason, the number of units in v2 for bit strips was
         * (meterMax + 1), so we update the number of units here. */
        volume->meters.push_back(
            new Bitstrip(meterImg, x, y, units + 1));
    } else {
        /* Horizontal meter is the default */
        volume->meters.push_back(
            new HorizontalBar(meterImg, x, y, units));
    }

    tinyxml2::XMLElement *drawText = SubElement("osd", "drawPercentage");
    if (drawText) {
        bool textEnabled = false;
        drawText->QueryBoolText(&textEnabled);
        if (textEnabled) {
            Text *t = CreateText(volume->background);
            if (t) {
                volume->meters.push_back(t);
            }
        }
    }

    return volume;
}