BackendWorker(Api::Ptr api, Parameters::Accessor::Ptr params) : SdlApi(api) , Params(params) , WasInitialized(SdlApi->SDL_WasInit(SDL_INIT_EVERYTHING)) , Queue(Parameters::ZXTune::Sound::Backends::Sdl::BUFFERS_DEFAULT) { if (0 == WasInitialized) { Dbg("Initializing"); CheckCall(SdlApi->SDL_Init(SDL_INIT_AUDIO) == 0, THIS_LINE); } else if (0 == (WasInitialized & SDL_INIT_AUDIO)) { Dbg("Initializing sound subsystem"); CheckCall(SdlApi->SDL_InitSubSystem(SDL_INIT_AUDIO) == 0, THIS_LINE); } }
virtual void Startup() { Dbg("Starting playback"); SDL_AudioSpec format; format.format = -1; const bool sampleSigned = Sample::MID == 0; switch (Sample::BITS) { case 8: format.format = sampleSigned ? AUDIO_S8 : AUDIO_U8; break; case 16: format.format = sampleSigned ? AUDIO_S16SYS : AUDIO_U16SYS; break; default: assert(!"Invalid format"); } const RenderParameters::Ptr sound = RenderParameters::Create(Params); const BackendParameters backend(*Params); format.freq = sound->SoundFreq(); format.channels = static_cast< ::Uint8>(Sample::CHANNELS); format.samples = sound->SamplesPerFrame(); //fix if size is not power of 2 if (0 != (format.samples & (format.samples - 1))) { unsigned msk = 1; while (format.samples > msk) { msk <<= 1; } format.samples = msk; } format.callback = OnBuffer; format.userdata = &Queue; Queue.SetSize(backend.GetBuffersCount()); CheckCall(SdlApi->SDL_OpenAudio(&format, 0) >= 0, THIS_LINE); SdlApi->SDL_PauseAudio(0); }
enum VariableType GetExpressionType(TreeNode* currentNode, MethodSymbols* methodTable) { enum VariableType temp1,temp2; switch(currentNode->type) { case TREE_OR : return CheckOperatorBoolsOnly("||",currentNode,methodTable); case TREE_AND : return CheckOperatorBoolsOnly("&&",currentNode,methodTable); case TREE_EQ : return CheckOperatorComparison("==",currentNode,methodTable); case TREE_NEQ : return CheckOperatorComparison("!=",currentNode,methodTable); case TREE_LT : return CheckOperatorCompareIntsOnly("<",currentNode,methodTable); case TREE_GT : return CheckOperatorCompareIntsOnly(">",currentNode,methodTable); case TREE_LEQ : return CheckOperatorCompareIntsOnly("<=",currentNode,methodTable); case TREE_GEQ : return CheckOperatorCompareIntsOnly(">=",currentNode,methodTable); case TREE_ADD : return CheckOperatorIntsOnly("+",currentNode,methodTable); case TREE_SUB : return CheckOperatorIntsOnly("-",currentNode,methodTable); case TREE_MUL : return CheckOperatorIntsOnly("*",currentNode,methodTable); case TREE_DIV : return CheckOperatorIntsOnly("/",currentNode,methodTable); case TREE_MOD : return CheckOperatorIntsOnly("%",currentNode,methodTable); case TREE_NOT : if((temp1=GetExpressionType(currentNode->sons->node,methodTable))==VARIABLE_BOOL) return VARIABLE_BOOL; else { PrintSemanticError("Operator %s cannot be applied to type %s\n","!",VarTypeToString(temp1)); return VARIABLE_INVALID; } case TREE_PLUS : if((temp1=GetExpressionType(currentNode->sons->node,methodTable))==VARIABLE_INT) return VARIABLE_INT; else { PrintSemanticError("Operator %s cannot be applied to type %s\n","+",VarTypeToString(temp1)); return VARIABLE_INVALID; } case TREE_MINUS : if((temp1=GetExpressionType(currentNode->sons->node,methodTable))==VARIABLE_INT) return VARIABLE_INT; else { PrintSemanticError("Operator %s cannot be applied to type %s\n","-",VarTypeToString(temp1)); return VARIABLE_INVALID; } case TREE_LENGTH : temp1=GetExpressionType(currentNode->sons->node,methodTable); switch (temp1) { case VARIABLE_BOOLARRAY : case VARIABLE_INTARRAY : case VARIABLE_STRINGARRAY : return VARIABLE_INT; default : PrintSemanticError("Operator %s cannot be applied to type %s\n",".length",VarTypeToString(temp1)); return VARIABLE_INVALID; } return VARIABLE_INT; case TREE_LOADARRAY : temp1=GetExpressionType(currentNode->sons->node,methodTable); /*look up variable type*/ temp2=GetExpressionType(currentNode->sons->next->node,methodTable); /*Look up indexer type*/ if (temp2!=VARIABLE_INT) { /*indexer value is not an int*/ PrintSemanticError("Operator %s cannot be applied to types %s, %s\n","[",VarTypeToString(temp1),VarTypeToString(temp2)); return VARIABLE_INVALID; } /*Check if the indexed variable is a valid array type*/ switch (temp1) { case VARIABLE_BOOLARRAY : return VARIABLE_BOOL; case VARIABLE_INTARRAY : return VARIABLE_INT; case VARIABLE_STRINGARRAY : /*Can't do anything with this particular array type*/ default : /*operator [] being used in something not indexable*/ PrintSemanticError("Operator %s cannot be applied to types %s, %s\n","[",VarTypeToString(temp1),VarTypeToString(temp2)); return VARIABLE_INVALID; } case TREE_CALL : return CheckCall(currentNode,methodTable); case TREE_NEWINT : temp1 = GetExpressionType(currentNode->sons->node,methodTable); if (temp1!=VARIABLE_INT) { /*Size must be an int*/ PrintSemanticError("Operator %s cannot be applied to type %s\n","new int",VarTypeToString(temp1)); return VARIABLE_INVALID; } return VARIABLE_INTARRAY; case TREE_NEWBOOL : temp1 = GetExpressionType(currentNode->sons->node,methodTable); if (temp1!=VARIABLE_INT) { /*Size must be an int*/ PrintSemanticError("Operator %s cannot be applied to type %s\n","new boolean",VarTypeToString(temp1)); return VARIABLE_INVALID; } return VARIABLE_BOOLARRAY; case TREE_PARSEARGS : temp1=GetExpressionType(currentNode->sons->node,methodTable); /*look up variable type*/ temp2=GetExpressionType(currentNode->sons->next->node,methodTable); /*Look up indexer type*/ if (temp2!=VARIABLE_INT) { /*indexer value is not an int*/ PrintSemanticError("Operator %s cannot be applied to types %s, %s\n","Integer.parseInt",VarTypeToString(temp1),VarTypeToString(temp2)); return VARIABLE_INVALID; } switch (temp1) { /*parseArgs only takes string arrays*/ case VARIABLE_STRINGARRAY : return VARIABLE_INT; /*Parseargs always returns an int since it's Integer.parseInt*/ break; default : /*operator [] being used in something not indexable*/ PrintSemanticError("Operator %s cannot be applied to types %s, %s\n","Integer.parseInt",VarTypeToString(temp1),VarTypeToString(temp2)); return VARIABLE_INVALID; } return VARIABLE_INVALID; case TREE_ID : return CheckID(currentNode,methodTable); case TREE_INTLIT : return CheckLitInt((char*)currentNode->args); case TREE_BOOLLIT : return CheckLitBool((char*)currentNode->args); default : return VARIABLE_INVALID; } }