Exemple #1
0
dwgs :: ~dwgs()
{
  for(int k=0;k<4;k++)
    delete d[k];
  for(int m=0;m<M;m++)
	destroy_filter(&(dispersion[m]));
  destroy_filter(&lowpass);
  destroy_filter(&fracdelay);
  destroy_filter(&bottomfilter);
}
image_p image_scale(image_p src, int w, int h,int mode)
{
	image_p dst;
	uint8 * temp;
	uint8 recover = 0;
	uint32 spitch, dpitch;
	filter_base* filter = create_filter(mode);
	dst = image_create(w,h,src->dtype);
	dst->dontswizzle = 1;
	if(src->swizzle ==1){
		unswizzle_swap(src);
		recover = 1;
	}
	temp = malloc(dst->w*src->h*src->bpb);
	memset(temp,0,dst->w*src->h*src->bpb);
	spitch = src->texw;
	dpitch = dst->texw;
    horiz_scale(filter,src->data,src->w,src->h,temp,dst->w,src->h,spitch,src->dtype);
	vert_scale (filter,temp,dst->w,src->h,dst->data,dst->w,dst->h,dpitch,src->dtype);
	free(temp);
	destroy_filter(filter);
	if(recover)
		swizzle_swap(src);	
	return dst;
}
Exemple #3
0
/**
* @brief Main entry point for R
*
* @param bamfilenameR Filename of read container
* @param aRgvals Vector containing the user arguments
* @param filterList passed from R in the form list("chr1"=c(100,200,3000,3010...start,end...))
* @return R list in the form list("chr1"=c(1,2,1,2,1,1,...),"chr1_gind"=c(1100,1200...),"chr1_lind"=c(0,112,...),"chrX"=NA,...) and a Statistics vector
* @details All chromosome of the filter or all chromosomes in the file header will be scanned and passed to an R list
* @note
* @todo high_cov not yet implemented.
*/
SEXP construct_dc(SEXP bamfilenameR, SEXP aRgvals, SEXP filterList) {

	double *statsp;//resulting statistics in the order "total reads" "coverage" "local coverage" "max score"
	uint32_t upcounter=0,i=0;
	time_t tstart,tstop;
	global_densities_t gd={0};
    user_arguments_t user_args;
    filter_t ft;
    SEXP histogram,stats;
    int *argvalsp;

    signal(SIGINT,SIG_DFL);//make this thing stop on CTRL+C
    time(&tstart);

    /* Set user defined values */

    PROTECT(aRgvals=AS_INTEGER(aRgvals));upcounter++;
    if(LENGTH(aRgvals)!=10)error("Invalid amount of arguments - arguments[%d] / should be %d!\n",LENGTH(aRgvals),9);
    argvalsp=INTEGER_POINTER(aRgvals);
    user_args.bamfilename = STRING_VALUE(bamfilenameR);
    user_args.READTHROUGH = argvalsp[0];//bool. read from start to end and 0 take whole read whithout CIGAR splice info
    user_args.PAIRED = argvalsp[1];
    user_args.STRANDED = argvalsp[2];//Set to 1 / -1 it will use only forward / reverse reads respectively. 0 means all reads are processed
    user_args.TMAPQ = argvalsp[3];//Minimum MPAQ score. Lower scored reads will be skipped
    user_args.COLLAPSE = argvalsp[4];
    user_args.EXTEND = argvalsp[5];//extend each read in its direction by this amount of BPs
    user_args.HWINDOW = argvalsp[6];
    user_args.COMPRESSION = argvalsp[7];//minimum BPs needed between data blocks to collapse the gap and index it
    user_args.VERBOSE = argvalsp[8];
    user_args.UNIQUE = argvalsp[9];


    /* Try to open the file */
    samfile_t *bam_file;
    bam_file=open_samtools(user_args.bamfilename);
	if(!bam_file){
		warning("sam/bam file not found!\n");
		UNPROTECT(upcounter);
	    return(R_NilValue);
	}

    if(user_args.HWINDOW>user_args.COMPRESSION){
    	warning("HWINDOW has to be smaller than COMPRESSION! HWINDOW updated to %d\n",user_args.COMPRESSION);
    	user_args.HWINDOW=user_args.COMPRESSION;
    }

	PROTECT(histogram = NEW_INTEGER(UINT16_MAX));upcounter++;//initialize compressed scores
	gd.histogramp = (uint32_t*) INTEGER_POINTER(histogram);
	for(i = 0; i < UINT16_MAX; i++) gd.histogramp[i] = 0;

	gd.total_elements=bam_file->header->n_targets;//one vector per chromosome needed
	/* ####  CHECK IF THERE IS AN ACTIVE FILTER IN PLACE */
    user_args.FILTER=isNewList(filterList) ? 1 : 0;
    if(user_args.FILTER){
    	upcounter+=set_filter(filterList,&ft);
    	gd.total_elements=ft.seqn;//overwrite total elements if filter is passed, since one density is returned per slice
    }

	// Creating a list with vector elements as many as sequences plus a character string vector:
    PROTECT(gd.list = allocVector(VECSXP, (gd.total_elements*3)+2));upcounter++;//3x for the two indexes and scores per chromosome
    PROTECT(gd.list_names = allocVector(STRSXP,(gd.total_elements*3)+2));upcounter++;//+1 for statistics vector +1 for the histogram

	/* PASS EVERYTHING */
	write_density(&gd,&user_args,bam_file,&ft);
	if(!gd.total_reads)goto NO_READS_FOUND;
	// 1 total_reads  2 gcoverage  3 lcoverage  4 maxscore  5 lmaxscore  6 lowqual  7 filtered  8 collapsed  9 paired  10 proper_pairs 11 pos  12 neg 13 fmapmass 14 lsize 15 gsize
	SET_STRING_ELT(gd.list_names,gd.total_elements*3,mkChar("Statistics"));
	PROTECT(stats = NEW_NUMERIC(15));upcounter++;
	statsp = NUMERIC_POINTER(stats);
	*statsp++=(double)gd.total_reads;
	*statsp++=(double)gd.mapmass/(double)gd.gsize;
	*statsp++=(double)gd.lmapmass/(double)gd.lsize;
	*statsp++=(double)gd.maxscore;
	*statsp++=(double)gd.lmaxScore;
	*statsp++=(double)gd.lowqual;
	*statsp++=(double)gd.filtered_reads;
	*statsp++=(double)gd.collapsed;
	*statsp++=(double)gd.paired;
	*statsp++=(double)gd.ppairs/2;
	*statsp++=(double)gd.pos_strand;
	*statsp++=(double)gd.neg_strand;
	*statsp=(double)gd.mapmass;
	*statsp++=(double)gd.lsize;
	*statsp++=(double)gd.gsize;


	if(gd.lmaxScore>=umaxof(usersize)-1){
		warning("\nThe maximum pile up is exceeding the maximal value of UINT16_MAX=%d. Reads have been capped to that value.\nConsider to rerun using the maxDups option!\n",UINT16_MAX);
	}

	SET_VECTOR_ELT(gd.list,gd.total_elements*3, stats);

	SET_STRING_ELT(gd.list_names,(gd.total_elements*3)+1,mkChar("Histogram"));
	SET_VECTOR_ELT(gd.list,(gd.total_elements*3)+1,histogram);

    setAttrib(gd.list, R_NamesSymbol, gd.list_names);

    NO_READS_FOUND:
    time(&tstop);
	if(user_args.VERBOSE>0)printf("About %.0f seconds passed. %llu reads processed \n", difftime(tstop, tstart),gd.total_reads);
	close_bamfile(bam_file);
	if(user_args.FILTER)destroy_filter(&ft);
    UNPROTECT(upcounter+gd.upcounter);
    if(!gd.total_reads)return(R_NilValue);
    else return(gd.list);
}
Exemple #4
0
int main(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Usage: %s <iterations>\n", argv[0]);
        return (EXIT_FAILURE);
    }

    int iterations = atoi(argv[1]);

    printf("main_cuda()\n");
    printf("Iterations: %d\n", iterations);

    bool ok = true;

    /* Read input file into buffer. */

    unsigned char (**image_buffer_h)[CHANNELS];

    if (ok)
        ok = read_image((unsigned char ***) &image_buffer_h);

    /* Allocate memory for image data. */

    float (**image_h)[CHANNELS];

    if (ok)
        ok = alloc_float_array((float ***) &image_h,
            B + HEIGHT + B, B + WIDTH + B, CHANNELS);

    /* Convert input. */

    unsigned int i, j, c;

    if (ok)
    {
        for (i = 0; i < HEIGHT; i++)
            for (j = 0; j < WIDTH; j++)
                for (c = 0; c < CHANNELS; c++)
                    image_h[i + B][j + B][c] = (float) image_buffer_h[i][j][c];
    }

    /* Device memory allocation. */

    float (**prev_image_d)[CHANNELS];
    float (**curr_image_d)[CHANNELS];

    float *prev_image_p;
    float *curr_image_p;

    if (ok)
        ok = alloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p,
            B + HEIGHT + B, B + WIDTH + B, CHANNELS);

    if (ok)
        ok = alloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p,
            B + HEIGHT + B, B + WIDTH + B, CHANNELS);

    /* Initialize filter in device memory space. */

    float (**filter_d)[1];
    float *filter_p;

    if (ok)
        ok = init_filter(&filter_d, &filter_p, filter);

    /* Device parameters for nVidia 9600GT (G94), passed to main filter function. */

    /* nVidia G94 supports 8 resident blocks per SMP, 768 resident threads per SMP. */

    unsigned int block_size = 64; // maximum 512 threads per block for nVidia G94
    printf("Block size: %u\n", block_size);

    /* nVidia G94 supports 2-dimensional grids with a maximum of 65535 for x,y dimension. */

    unsigned int grid_dim = HEIGHT * WIDTH / block_size;
    double sqr = sqrt(grid_dim);
    grid_dim = sqr;
    grid_dim++;
    printf("Grid: %ux%u\n", grid_dim, grid_dim);

    /* Start timing. */

    float memcopy, compute;
    timestamp t_start;
    t_start = getTimestamp();

    /* Copy image data to device. */

    if (ok)
        ok = (cudaSuccess == cudaMemcpy(curr_image_p, &(image_h[0][0][0]),
            (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float),
            cudaMemcpyHostToDevice));

    memcopy = getElapsedtime(t_start);

    /* Clear host image data. */

    memset(&(image_h[0][0][0]), 0, (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float));

    /* Apply filter. */

    t_start = getTimestamp();

    unsigned int n;

    if (ok)
    {
        for (n = 0; iterations == 0 || n < iterations; n++)
        {
            /* Fill borders with edge image data. */

            fill_borders(curr_image_d, HEIGHT, WIDTH);

            /* Apply filter. */

            apply_filter_cuda(prev_image_d, curr_image_d, filter_d, block_size, grid_dim);

            /* Switch current / previous image buffers. */

            float (**temp)[CHANNELS];
            temp = prev_image_d;
            prev_image_d = curr_image_d;
            curr_image_d = temp;

            float *tmp;
            tmp = prev_image_p;
            prev_image_p = curr_image_p;
            curr_image_p = tmp;
        }
    }

    /* Stop time measurement, print time. */

    cudaThreadSynchronize();

    compute = getElapsedtime(t_start);
    t_start = getTimestamp();

    /* Copy processed image data from device. */

    if (ok)
        ok = (cudaSuccess == cudaMemcpy(&(image_h[0][0][0]), curr_image_p,
            (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float),
            cudaMemcpyDeviceToHost));

    memcopy += getElapsedtime(t_start);

    printf("Completed in %.3f sec\n", compute / 1000);
    printf("Memory copy in %.3f sec\n", memcopy / 1000);

    /* Convert output. */

    if (ok)
    {
        for (i = 0; i < HEIGHT; i++)
            for (j = 0; j < WIDTH; j++)
                for (c = 0; c < CHANNELS; c++)
                    image_buffer_h[i][j][c] = (unsigned char) image_h[i + B][j + B][c];
    }

    /* Create output files, one for each channel. */

    if (ok)
        ok = write_channels(image_buffer_h, HEIGHT, WIDTH);

    /* Free allocated memory. */

    dealloc_uchar_array((unsigned char ***) &image_buffer_h);
    dealloc_float_array((float ***) &image_h);
    dealloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p);
    dealloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p);
    destroy_filter(&filter_d, &filter_p);

    return ok ? (EXIT_SUCCESS) : (EXIT_FAILURE);
}
Exemple #5
0
void obe_close( obe_t *h )
{
    void *ret_ptr;

    fprintf( stderr, "closing obe \n" );

    /* Cancel input thread */
    for( int i = 0; i < h->num_devices; i++ )
    {
        pthread_cancel( h->devices[i]->device_thread );
        pthread_join( h->devices[i]->device_thread, &ret_ptr );
    }

    fprintf( stderr, "input cancelled \n" );

    /* Cancel filter threads */
    for( int i = 0; i < h->num_filters; i++ )
    {
        pthread_mutex_lock( &h->filters[i]->queue.mutex );
        h->filters[i]->cancel_thread = 1;
        pthread_cond_signal( &h->filters[i]->queue.in_cv );
        pthread_mutex_unlock( &h->filters[i]->queue.mutex );
        pthread_join( h->filters[i]->filter_thread, &ret_ptr );
    }

    fprintf( stderr, "filters cancelled \n" );

    /* Cancel encoder threads */
    for( int i = 0; i < h->num_encoders; i++ )
    {
        pthread_mutex_lock( &h->encoders[i]->queue.mutex );
        h->encoders[i]->cancel_thread = 1;
        pthread_cond_signal( &h->encoders[i]->queue.in_cv );
        pthread_mutex_unlock( &h->encoders[i]->queue.mutex );
        pthread_join( h->encoders[i]->encoder_thread, &ret_ptr );
    }

    fprintf( stderr, "encoders cancelled \n" );

    /* Cancel encoder smoothing thread */
    if ( h->obe_system == OBE_SYSTEM_TYPE_GENERIC )
    {
        pthread_mutex_lock( &h->enc_smoothing_queue.mutex );
        h->cancel_enc_smoothing_thread = 1;
        pthread_cond_signal( &h->enc_smoothing_queue.in_cv );
        pthread_mutex_unlock( &h->enc_smoothing_queue.mutex );
        /* send a clock tick in case smoothing is waiting for one */
        pthread_mutex_lock( &h->obe_clock_mutex );
        pthread_cond_broadcast( &h->obe_clock_cv );
        pthread_mutex_unlock( &h->obe_clock_mutex );
        pthread_join( h->enc_smoothing_thread, &ret_ptr );
    }

    fprintf( stderr, "encoder smoothing cancelled \n" );

    /* Cancel mux thread */
    pthread_mutex_lock( &h->mux_queue.mutex );
    h->cancel_mux_thread = 1;
    pthread_cond_signal( &h->mux_queue.in_cv );
    pthread_mutex_unlock( &h->mux_queue.mutex );
    pthread_join( h->mux_thread, &ret_ptr );

    fprintf( stderr, "mux cancelled \n" );

    /* Cancel mux smoothing thread */
    pthread_mutex_lock( &h->mux_smoothing_queue.mutex );
    h->cancel_mux_smoothing_thread = 1;
    pthread_cond_signal( &h->mux_smoothing_queue.in_cv );
    pthread_mutex_unlock( &h->mux_smoothing_queue.mutex );
    pthread_join( h->mux_smoothing_thread, &ret_ptr );

    fprintf( stderr, "mux smoothing cancelled \n" );

    /* Cancel output_thread */
    pthread_mutex_lock( &h->output_queue.mutex );
    h->cancel_output_thread = 1;
    pthread_cond_signal( &h->output_queue.in_cv );
    pthread_mutex_unlock( &h->output_queue.mutex );
    pthread_join( h->output_thread, &ret_ptr );
    /* could be blocking on OS so have to cancel thread too */
    pthread_cancel( h->output_thread );
    pthread_join( h->output_thread, &ret_ptr );

    fprintf( stderr, "output thread cancelled \n" );

    /* Destroy devices */
    for( int i = 0; i < h->num_devices; i++ )
        destroy_device( h->devices[i] );

    fprintf( stderr, "devices destroyed \n" );

    /* Destroy filters */
    for( int i = 0; i < h->num_filters; i++ )
        destroy_filter( h->filters[i] );

    fprintf( stderr, "filters destroyed \n" );

    /* Destroy encoders */
    for( int i = 0; i < h->num_encoders; i++ )
        destroy_encoder( h->encoders[i] );

    fprintf( stderr, "encoders destroyed \n" );

    // FIXME destroy smoothing thread

    /* Destroy mux */
    destroy_mux( h );

    fprintf( stderr, "mux destroyed \n" );

    /* Destroy output */
    destroy_output( h );

    fprintf( stderr, "output destroyed \n" );

    free( h->output_streams );
    /* TODO: free other things */

    free( h );
    h = NULL;
}
LRESULT album_list_window::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{

	switch (msg)
	{
	case WM_CREATE:
	{
		list_wnd.add_item(this);

		initialised = true;

		modeless_dialog_manager::g_add(wnd);

		create_tree();
		create_filter();

		if (cfg_populate) refresh_tree();

		static_api_ptr_t<library_manager_v3>()->register_callback(this);
	}
	break;
	/*case WM_GETMINMAXINFO:
	{
	LPMINMAXINFO mmi = LPMINMAXINFO(lp);
	mmi->ptMinTrackSize.y = cfg_height;
	return 0;
	}*/
	case WM_SIZE:
		on_size(LOWORD(lp), HIWORD(lp));
		break;
		/*	case DM_GETDEFID:
		return (DC_HASDEFID<<16|IDOK);
		case WM_GETDLGCODE:
		return DLGC_DEFPUSHBUTTON;*/
		//		break;
	case WM_TIMER:
		if (wp == EDIT_TIMER_ID)
		{
			refresh_tree();
			KillTimer(wnd, wp);
			m_timer = false;
		}
		break;
	case WM_COMMAND:
		switch (wp)
		{
		case IDC_FILTER | (EN_CHANGE << 16) :
			if (m_timer)
				KillTimer(wnd_edit, 500);
			m_timer = SetTimer(wnd, EDIT_TIMER_ID, 500, NULL) != 0;
			return TRUE;
		case IDOK:
			if (GetKeyState(VK_SHIFT) & KF_UP) do_playlist(p_selection, false);
			else if (GetKeyState(VK_CONTROL) & KF_UP) do_playlist(p_selection, true, true);
			else do_playlist(p_selection, true);
			return 0;
		}
		break;
	case WM_CONTEXTMENU:
	{
		enum { ID_SEND = 1, ID_ADD, ID_NEW, ID_AUTOSEND, ID_REMOVE, ID_REMOVEDEAD, ID_REFRESH, ID_FILT, ID_CONF, ID_VIEW_BASE };

		HMENU menu = CreatePopupMenu();

		POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
		service_ptr_t<contextmenu_manager> p_menu_manager;

		unsigned IDM_MANAGER_BASE = 0;

		HWND list = wnd_tv;

		HTREEITEM treeitem = NULL;

		TVHITTESTINFO ti;
		memset(&ti, 0, sizeof(ti));

		if (pt.x != -1 && pt.y != -1)
		{
			ti.pt = pt;
			ScreenToClient(list, &ti.pt);
			uSendMessage(list, TVM_HITTEST, 0, (long)&ti);
			if (ti.hItem && (ti.flags & TVHT_ONITEM))
			{
				//FIX THIS AND AUTOSEND
				//TreeView_Select(list, ti.hItem, TVGN_DROPHILITE);
				//uSendMessage(list,TVM_SELECTITEM,TVGN_DROPHILITE,(long)ti.hItem);
				treeitem = ti.hItem;
			}
		}
		else
		{
			treeitem = TreeView_GetSelection(list);
			RECT rc;
			if (treeitem && TreeView_GetItemRect(wnd_tv, treeitem, &rc, TRUE))
			{
				MapWindowPoints(wnd_tv, HWND_DESKTOP, (LPPOINT)&rc, 2);

				pt.x = rc.left;
				pt.y = rc.top + (rc.bottom - rc.top) / 2;

			}
			else
			{
				GetMessagePos(&pt);
			}
		}

		TreeView_Select(list, treeitem, TVGN_DROPHILITE);

		HMENU menu_view = CreatePopupMenu();
		unsigned n, m = cfg_view_list.get_count();
		string8_fastalloc temp;
		temp.prealloc(32);

		uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(directory_structure_view_name, view) ? MF_CHECKED : 0), ID_VIEW_BASE + 0, directory_structure_view_name);

		list_t<string_simple, pfc::alloc_fast> views;

		views.add_item(string_simple(directory_structure_view_name));

		for (n = 0; n<m; n++)
		{
			temp = cfg_view_list.get_name(n);
			string_simple item(temp.get_ptr());

			if (item)
			{
				uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(temp, view) ? MF_CHECKED : 0), ID_VIEW_BASE + views.add_item(item), temp);
			}

		}


		IDM_MANAGER_BASE = ID_VIEW_BASE + views.get_count();

		uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)menu_view, "View");

		if (!m_populated && !cfg_populate)
			uAppendMenu(menu, MF_STRING, ID_REFRESH, "Populate");
		uAppendMenu(menu, MF_STRING | (m_filter ? MF_CHECKED : 0), ID_FILT, "Filter");
		uAppendMenu(menu, MF_STRING, ID_CONF, "Settings");

		bool show_shortcuts = standard_config_objects::query_show_keyboard_shortcuts_in_menus();

		node * p_node = NULL;
		TVITEMEX tvi;
		memset(&tvi, 0, sizeof(tvi));
		tvi.hItem = treeitem;
		tvi.mask = TVIF_HANDLE | TVIF_PARAM;
		TreeView_GetItem(list, &tvi);
		p_node = (node*)tvi.lParam;

		if (treeitem && p_node)
		{
			uAppendMenu(menu, MF_SEPARATOR, 0, "");
			uAppendMenu(menu, MF_STRING, ID_SEND, (show_shortcuts ? "&Send to playlist\tEnter" : "&Send to playlist"));
			uAppendMenu(menu, MF_STRING, ID_ADD, show_shortcuts ? "&Add to playlist\tShift+Enter" : "&Add to playlist");
			uAppendMenu(menu, MF_STRING, ID_NEW, show_shortcuts ? "Send to &new playlist\tCtrl+Enter" : "Send to &new playlist");
			uAppendMenu(menu, MF_STRING, ID_AUTOSEND, "Send to &autosend playlist");

			if (!static_api_ptr_t<core_version_info_v2>()->test_version(0, 9, 6, 0))
			{
				uAppendMenu(menu, MF_STRING, ID_REMOVE, "&Remove from library");
				uAppendMenu(menu, MF_STRING, ID_REMOVEDEAD, "Remove &dead entries (slow)");
			}
			uAppendMenu(menu, MF_SEPARATOR, 0, "");

			contextmenu_manager::g_create(p_menu_manager);
			p_node->sort_entries();

			if (p_menu_manager.is_valid())
			{
				p_menu_manager->init_context(p_node->get_entries(), 0);

				p_menu_manager->win32_build_menu(menu, IDM_MANAGER_BASE, -1);
				menu_helpers::win32_auto_mnemonics(menu);
			}
		}

		int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, get_wnd(), 0);
		DestroyMenu(menu);

		TreeView_Select(list, NULL, TVGN_DROPHILITE);

		if (cmd)
		{
			if (p_menu_manager.is_valid() && (unsigned)cmd >= IDM_MANAGER_BASE)
			{
				p_menu_manager->execute_by_id(cmd - IDM_MANAGER_BASE);
			}
			else if (cmd >= ID_VIEW_BASE)
			{
				unsigned n = cmd - ID_VIEW_BASE;
				if (n<views.get_count())
				{
					view = views[n].get_ptr();
					refresh_tree();
				}
			}
			else if (cmd<ID_VIEW_BASE)
			{
				unsigned cmd2 = 0;
				switch (cmd)
				{
				case ID_NEW:
					do_playlist(p_node, true, true);
					break;
				case ID_SEND:
					do_playlist(p_node, true);
					break;
				case ID_ADD:
					do_playlist(p_node, false);
					break;
				case ID_AUTOSEND:
					do_autosend_playlist(p_node, view, true);
					break;
				case ID_CONF:
				{
					static_api_ptr_t<ui_control>()->show_preferences(g_guid_preferences_album_list_panel);
				}
				break;
				case ID_FILT:
				{
					m_filter = !m_filter;
					create_or_destroy_filter();
				}
				break;
				case ID_REMOVE:
					p_node->remove_from_db();
					break;
				case ID_REMOVEDEAD:
					p_node->remove_dead();
					break;
				case ID_REFRESH:
					if (!m_populated && !cfg_populate)
						refresh_tree();
					break;
				}
				if (cmd2) uSendMessage(get_wnd(), WM_COMMAND, cmd2, 0);
			}
		}

		p_menu_manager.release();

		/*			if (treeitem_context && (treeitem_context != treeitem) && cfg_autosend)
		TreeView_SelectItem(wnd_tv,treeitem);*/


	}
	return 0;
	case WM_NOTIFY:
	{
		LPNMHDR hdr = (LPNMHDR)lp;

		switch (hdr->idFrom)
		{

		case IDC_TREE:
		{
			if (hdr->code == TVN_ITEMEXPANDING)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;
				if (cfg_picmixer && (param->action == TVE_EXPAND))
				{
					TreeView_CollapseOtherNodes(param->hdr.hwndFrom, param->itemNew.hItem);
				}
			}

			else if (hdr->code == TVN_SELCHANGED)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;

				p_selection = (node*)param->itemNew.lParam;
				if ((param->action == TVC_BYMOUSE || param->action == TVC_BYKEYBOARD))
				{
					if (cfg_autosend)
						do_autosend_playlist(p_selection, view);
				}
				if (m_selection_holder.is_valid())
				{
					m_selection_holder->set_selection(p_selection.is_valid() ? p_selection->get_entries() : metadb_handle_list());
				}
#if 0
				if (cfg_picmixer)
				{
					HTREEITEM ti_parent_old = TreeView_GetParent(param->hdr.hwndFrom, param->itemOld.hItem);
					HTREEITEM ti_parent_new = TreeView_GetParent(param->hdr.hwndFrom, param->itemNew.hItem);

					if (/*ti_parent_old != param->itemNew.hItem &&  */!TreeView_IsChild(param->hdr.hwndFrom, param->itemNew.hItem, param->itemOld.hItem))
					{
						HTREEITEM ti = //TreeView_GetLevel(param->hdr.hwndFrom, param->itemNew.hItem) < TreeView_GetLevel(param->hdr.hwndFrom, param->itemOld.hItem) ? 
							TreeView_GetCommonParentChild(param->hdr.hwndFrom, param->itemOld.hItem, param->itemNew.hItem)
							//: param->itemOld.hItem
							;
						if (ti && ti != TVI_ROOT) TreeView_Expand(param->hdr.hwndFrom, ti, TVE_COLLAPSE);
					}

					if (ti_parent_new)
					{

						HTREEITEM child = TreeView_GetChild(param->hdr.hwndFrom, ti_parent_new);
						while (child)
						{
							if (child != param->itemNew.hItem)
							{

							}
						}
					}
				}
#endif
			}
		}
		break;
		}

	}
	break;
	case WM_DESTROY:
		static_api_ptr_t<library_manager_v3>()->unregister_callback(this);
		modeless_dialog_manager::g_remove(wnd);
		destroy_tree();
		destroy_filter();
		m_selection_holder.release();
		m_root.release();
		p_selection.release();
		if (initialised)
		{
			list_wnd.remove_item(this);
			if (list_wnd.get_count() == 0)
			{
				DeleteFont(g_font);
				g_font = 0;
			}
			initialised = false;
		}
		break;
	}
	return DefWindowProc(wnd, msg, wp, lp);
}