示例#1
0
void AudioView::ImportMP3()
{
  #if 0 // seems to be working better now!
    static bool warned=false;

    if (!warned) {
	wxMessageBox("Warning: This feature is not stable and may crash.  "
				 "Proceed at your own risk.");
	warned = true;
    }
  #endif // 0

  wxString fileName =
	wxFileSelector("Select a MP3 File...",
				   "", // Path
				   "", // Name
				   ".mp3", // Extension
				   "*.mp3", // Wildcard
				   0, // Flags
				   GetFrame()); // Parent
  
  if (fileName == "")
    return;

  WaveTrack *left = 0;
  WaveTrack *right = 0;

  if (::ImportMP3(fileName, &left, &right,
		  &((AudioDoc *)GetDocument())->dirManager)) {  
    if (left || right) {
      SelectNone();
    }
    
    if (left) {
      GetTracks()->Add(left);
      left->selected = true;
    }
    
    if (right) {
      GetTracks()->Add(right);
      right->selected = true;
    }
    
    PushState();
    
    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
  }
}
示例#2
0
bool AudioView::ProcessEvent(wxEvent& event)
{
  if (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED &&
      event.GetId() >= FirstEffectID &&
      event.GetId() < FirstEffectID + numEffects) {
    Effect *f = Effect::GetEffect(event.GetId() - FirstEffectID);

    TrackList *tracks = GetTracks();
    VTrack *t = tracks->First();
    
    while(t) {
      if (t->selected && t->GetKind() == (VTrack::Wave)) {
	f->DoInPlaceEffect((WaveTrack *)t, sel0, sel1);
      }
      
      t = tracks->Next();
    }
    
    PushState();
    
    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
    
    // This indicates we handled the event.
    return true;
  }
  
  return wxView::ProcessEvent(event);
}
示例#3
0
void AudioView::Cut()
{
  ClearClipboard();

  TrackList *tracks = GetTracks();
  VTrack *n = tracks->First();
  VTrack *dest = 0;

  while(n) {
	if (n->selected) {
	  n->Cut(sel0, sel1, &dest);
	  if (dest)
		clipboard->Add(dest);
	}
	n = tracks->Next();
  }

  clipLen = (sel1 - sel0);

  sel1 = sel0;

  PushState();

  FixScrollbars();
  REDRAW(trackPanel);
  REDRAW(rulerPanel);
  UpdateMenus();
}
示例#4
0
void AudioView::Copy()
{
  ClearClipboard();

  TrackList *tracks = GetTracks();
  VTrack *n = tracks->First();
  VTrack *dest = 0;

  while(n) {
	if (n->selected) {
	  n->Copy(sel0, sel1, &dest);
	  if (dest)
		clipboard->Add(dest);
	}
	n = tracks->Next();
  }

  clipLen = (sel1 - sel0);

  sel1 = sel0;
  UpdateMenus();

  //  PushState();
  //  Not an undoable operation
}
示例#5
0
void AudioView::Paste()
{
  if (sel0 != sel1)
    Clear();
    
  wxASSERT(sel0 == sel1);

  double tsel = sel0;

  TrackList *tracks = GetTracks();
  VTrack *n = tracks->First();
  VTrack *c = clipboard->First();

  while(n && c) {
	if (n->selected) {
	  n->Paste(tsel, c);
	  c = clipboard->Next();
	}
	  
	n = tracks->Next();
  }

  // TODO: What if we clicked past the end of the track?

  sel0 = tsel;
  sel1 = tsel + clipLen;

  PushState();

  FixScrollbars();
  REDRAW(trackPanel);
  REDRAW(rulerPanel);
  UpdateMenus();
}
示例#6
0
void AudioView::ImportMIDI()
{
  wxString fileName =
	wxFileSelector("Select a MIDI File...",
				   "", // Path
				   "", // Name
				   ".mid", // Extension
				   "*.mid", // Wildcard
				   0, // Flags
				   GetFrame()); // Parent

  if (fileName == "")
    return;

  NoteTrack *newTrack =
	new NoteTrack(&((AudioDoc *)GetDocument())->dirManager);
  
  if (::ImportMIDI(fileName, newTrack)) {

    SelectNone();
    GetTracks()->Add(newTrack);
	newTrack->selected = true;
    
    PushState();

    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
  }
}
示例#7
0
void AudioView::Pitch()
{
  VTrack *t;
  bool success = false;

  TrackList *tracks = GetTracks();
  t = tracks->First();
  while(t) {
    if (t->selected && t->GetKind() == VTrack::Wave) {
      NoteTrack *note = PitchExtract((WaveTrack *)t,
				     &((AudioDoc *)GetDocument())->dirManager);
      if (note) {
		success = true;
		tracks->Add(note);
      }
    }

    t = tracks->Next();
  }

  if (success) {
    PushState();
    
    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
  }
}
示例#8
0
void AudioView::PushState()
{
  TrackList *l = new TrackList(GetTracks());

  undoManager.PushState(l, sel0, sel1);
  delete l;
}
示例#9
0
AV_MEDIA_ERR MP4MediaFormat::Open(IAVMediaIO* io)
{
	if (io == nullptr)
		return AV_COMMON_ERR_INVALIDARG;
	if (_av_io != nullptr)
		return AV_COMMON_ERR_CHANGED_STATE;

	if (!RESET_AV_MEDIA_IO(io))
		return AV_IO_ERR_SEEK_FAILED;

	unsigned io_buf_size = _IO_BUFFER_SIZE_LOCAL;
	if (io->IsAliveStream())
		io_buf_size = _IO_BUFFER_SIZE_NETWORK;

	auto io_pool = std::make_shared<IOPoolReader>(io,_force_io_pool_size == 0 ? io_buf_size:_force_io_pool_size);
	_av_io = io_pool.get();

	unsigned isom_err_code = 0;
	auto core = std::make_shared<Aka4Splitter>(this);
	bool result = core->Open(&isom_err_code,true);
	_av_io = nullptr;
	if (!result)
		return AV_OPEN_ERR_PROBE_FAILED;
	if (core->GetTracks()->GetCount() == 0)
		return AV_OPEN_ERR_HEADER_INVALID;

	_av_io = io_pool.get();
	_stream_count = 0;
	if (!MakeAllStreams(core) || _stream_count == 0)
	{
		_av_io = nullptr;
		return AV_OPEN_ERR_STREAM_INVALID;
	}

	if (core->GetTracks()->GetCount() == 1)
		if (core->GetTracks()->Get(0)->Type == Aka4Splitter::TrackInfo::TrackType_Audio)
			_is_m4a_file = true;

	_io_pool = std::move(io_pool);
	_core = std::move(core);

	LoadAllChapters();
	return AV_ERR_OK;
}
示例#10
0
void AudioView::SelectNone()
{
  TrackList *tracks = GetTracks();

  VTrack *t = tracks->First();
  while(t) {
	t->selected = false;
	t = tracks->Next();
  }
}
示例#11
0
void AudioView::Import()
{
  wxString fileName =
	wxFileSelector("Select an audio file...",
				   "", // Path
				   "", // Name
				   "", // Extension
				   "", // Wildcard
				   0, // Flags
				   GetFrame()); // Parent

  if (fileName == "")
    return;

  WaveTrack *left = 0;
  WaveTrack *right = 0;
  
  if (ImportWAV(fileName, &left, &right, &((AudioDoc *)GetDocument())->dirManager)) {

	if (left || right) {
	  SelectNone();
	}

    if (left) {
      GetTracks()->Add(left);
	  left->selected = true;
    }

    if (right) {
      GetTracks()->Add(right);
	  right->selected = true;
    }

    PushState();

    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
  }
  
}
示例#12
0
void AudioView::PopState(TrackList *l)
{
  TrackList *tracks = GetTracks();

  tracks->Clear();
  VTrack *t = l->First();
  while(t) {
	//    printf("Popping track with %d samples\n",
	//           ((WaveTrack *)t)->numSamples);
    //	((WaveTrack *)t)->Debug();
    tracks->Add(t->Duplicate());
    t = l->Next();
  }
}
示例#13
0
void AudioView::SpectrumDisplay()
{
  TrackList *tracks = GetTracks();
  VTrack *n = tracks->First();

  while(n) {
	if (n->selected && n->GetKind() == VTrack::Wave)
	  ((WaveTrack *)n)->SetDisplay(WaveTrack::SpectrumDisplay);
	n = tracks->Next();
  }

  REDRAW(trackPanel);
  REDRAW(rulerPanel);
}
示例#14
0
void AudioView::SelectAll()
{
  TrackList *tracks = GetTracks();

  VTrack *t = tracks->First();
  while(t) {
	t->selected = true;
	t = tracks->Next();
  }
  sel0 = 0.0;
  sel1 = tracks->GetMaxLen();
  
  REDRAW(trackPanel);
  REDRAW(rulerPanel);
  UpdateMenus();
}
示例#15
0
void AudioView::NewLabelTrack()
{
  LabelTrack *t = new LabelTrack(&((AudioDoc *)GetDocument())->dirManager);

  SelectNone();

  GetTracks()->Add(t);
  t->selected = true;

  PushState();

  FixScrollbars();
    
  REDRAW(trackPanel);
  REDRAW(rulerPanel);
}
示例#16
0
void AudioView::RemoveTracks()
{
  TrackList *list = GetTracks();
  VTrack *t = list->First();

  while(t) {
	if (t->selected)
	  t = list->RemoveCurrent();
	else
	  t = list->Next();
  }

  PushState();

  REDRAW(trackPanel);
  REDRAW(rulerPanel);
  UpdateMenus();
}
示例#17
0
void AudioView::Clear()
{
  TrackList *tracks = GetTracks();
  VTrack *n = tracks->First();

  while(n) {
	if (n->selected)
	  n->Clear(sel0, sel1);
	n = tracks->Next();
  }

  sel1 = sel0;

  PushState();
  FixScrollbars();
  REDRAW(trackPanel);
  REDRAW(rulerPanel);
  UpdateMenus();
}
示例#18
0
VTrack *AudioView::FindTrack(int mouseX, int mouseY, bool label,
							 wxRect *trackRect, int *trackNum)
{
  wxRect r;
  if (label) {
	r.x = 0;
	r.width = labelWidth - 1;
  }
  else {
	int wid, ht;
	r.x = labelWidth;
	trackPanel->GetSize(&wid, &ht);
	r.width = wid - labelWidth;
  }
  r.y = -vpos;

  TrackList *tracks = GetTracks();
  VTrack *t = tracks->First();

  int n=1;
  
  while(t) {
	r.height = t->GetHeight();
	
  	if (r.Inside(mouseX, mouseY)) {
      if (trackRect)
        *trackRect = r;
      if (trackNum)
        *trackNum = n;
      return t;
    }

	r.y += r.height;
	n++;
	t = tracks->Next();
  }

  if (mouseY >= r.y && trackNum)
	*trackNum = n-1;
  
  return NULL;
}
示例#19
0
void AudioView::QuickMix()
{
  WaveTrack **waveArray;
  VTrack *t;
  int numWaves = 0;
  int w;

  TrackList *tracks = GetTracks();
  t = tracks->First();
  while(t) {
    if (t->selected && t->GetKind() == VTrack::Wave)
      numWaves++;
    t = tracks->Next();
  }
  
  if (numWaves == 0)
	return;

  waveArray = new WaveTrack*[numWaves];
  w = 0;
  t = tracks->First();
  while(t) {
    if (t->selected && t->GetKind() == VTrack::Wave)
      waveArray[w++] = (WaveTrack *)t;
    t = tracks->Next();
  }  

  WaveTrack *mix = ::QuickMix(numWaves, waveArray,
			    &((AudioDoc *)GetDocument())->dirManager);
  if (mix) {
    tracks->Add(mix);

    PushState();
    
    FixScrollbars();
    REDRAW(trackPanel);
    REDRAW(rulerPanel);
  }
}
示例#20
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();
  }
}
示例#21
0
void AudioView::Export()
{
  VTrack *left = 0;
  VTrack *right = 0;
  VTrack *t;
  int numSelected = 0;

  TrackList *tracks = GetTracks();
  t = tracks->First();
  while(t) {
	if (t->selected)
	  numSelected++;
	if (t->GetKind() != VTrack::Wave) {
	  wxMessageBox("Only audio tracks can be exported.");
	  return;
	}
	t = tracks->Next();
  }

  if (numSelected == 0) {
	wxMessageBox("Please select one or two tracks before trying to export.");
	return;
  }

  if (numSelected > 2) {
	wxMessageBox("Cannot export more than two tracks (stereo).  "
				 "Please select either one or two tracks.");
  }

  left = tracks->First();  
  while (left && (!left->selected))
	left = tracks->Next();
  
  do {
	right = tracks->Next();
  } while (right && (!right->selected));
  
  ::Export((WaveTrack *)left, (WaveTrack *)right);
}
/*****************************************************************************
 * Open: open cdda
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys;
    vcddev_t     *vcddev;
    char         *psz_name;

    if( !p_access->psz_filepath || !*p_access->psz_filepath )
    {
        /* Only when selected */
        if( !p_access->psz_access || !*p_access->psz_access )
            return VLC_EGENERIC;

        psz_name = var_InheritString( p_this, "cd-audio" );
        if( !psz_name )
            return VLC_EGENERIC;
    }
    else psz_name = ToLocaleDup( p_access->psz_filepath );

#if defined( _WIN32 ) || defined( __OS2__ )
    if( psz_name[0] && psz_name[1] == ':' &&
        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
#endif

    /* Open CDDA */
    if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_name ) ) == NULL )
    {
        msg_Warn( p_access, "could not open %s", psz_name );
        free( psz_name );
        return VLC_EGENERIC;
    }
    free( psz_name );

    /* Set up p_access */
    STANDARD_BLOCK_ACCESS_INIT
    p_sys->vcddev = vcddev;

    /* Do we play a single track ? */
    p_sys->i_track = var_InheritInteger( p_access, "cdda-track" ) - 1;

    if( p_sys->i_track < 0 )
    {
        /* We only do separate items if the whole disc is requested */
        input_thread_t *p_input = access_GetParentInput( p_access );

        int i_ret = -1;
        if( p_input )
        {
            input_item_t *p_current = input_GetItem( p_input );
            if( p_current )
                i_ret = GetTracks( p_access, p_current );

            vlc_object_release( p_input );
        }
        if( i_ret < 0 )
            goto error;
    }
    else
    {
        /* Build a WAV header for the output data */
        memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
        SetWLE( &p_sys->waveheader.Format, 1 ); /*WAVE_FORMAT_PCM*/
        SetWLE( &p_sys->waveheader.BitsPerSample, 16);
        p_sys->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
        p_sys->waveheader.Length = 0;               /* we just don't know */
        p_sys->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
        p_sys->waveheader.SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
        SetDWLE( &p_sys->waveheader.SubChunkLength, 16);
        SetWLE( &p_sys->waveheader.Modus, 2);
        SetDWLE( &p_sys->waveheader.SampleFreq, 44100);
        SetWLE( &p_sys->waveheader.BytesPerSample,
                    2 /*Modus*/ * 16 /*BitsPerSample*/ / 8 );
        SetDWLE( &p_sys->waveheader.BytesPerSec,
                    2*16/8 /*BytesPerSample*/ * 44100 /*SampleFreq*/ );
        p_sys->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
        p_sys->waveheader.DataLength = 0;           /* we just don't know */

        p_sys->i_first_sector = var_InheritInteger( p_access,
                                                    "cdda-first-sector" );
        p_sys->i_last_sector  = var_InheritInteger( p_access,
                                                    "cdda-last-sector" );
        /* Tracknumber in MRL */
        if( p_sys->i_first_sector < 0 || p_sys->i_last_sector < 0 )
        {
            const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
                                                     p_sys->vcddev, &p_sys->p_sectors );
            if( p_sys->i_track >= i_titles )
            {
                msg_Err( p_access, "invalid track number" );
                goto error;
            }
            p_sys->i_first_sector = p_sys->p_sectors[p_sys->i_track];
            p_sys->i_last_sector = p_sys->p_sectors[p_sys->i_track+1];
        }

        p_sys->i_sector = p_sys->i_first_sector;
        p_access->info.i_size = (p_sys->i_last_sector - p_sys->i_first_sector)
                                     * (int64_t)CDDA_DATA_SIZE;
    }

    return VLC_SUCCESS;

error:
    free( p_sys->p_sectors );
    ioctl_Close( VLC_OBJECT(p_access), p_sys->vcddev );
    free( p_sys );
    return VLC_EGENERIC;
}
示例#23
0
文件: Remuxer.c 项目: neurocis/sagetv
static int RemuxMessageDumper( void* pContext, unsigned char* pData, int nSize )
{
	REMUXER *pRemuxer = (REMUXER*)pContext;
	MESSAGE_DATA *message = (MESSAGE_DATA*)pData;
	if ( strstr( message->title, "LANGUAGE" ) )
	{
		unsigned long language_code = LanguageCode( message->message );
		SetupEPGDumpLanguage( pRemuxer, language_code );
		//SetupEPGDumpLanguage( pRemuxer,  LanguageCode( "eng" ) );
	} else
	if ( !strcmp( message->title, "STATUS" ) )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("*********** PARSER STATUS: %s ***********"), message->message ));
		if ( strstr( (char*)message->message, "STREAM START" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			ResetBlockBuffer( pRemuxer->demuxer, slot_index );

			if ( pRemuxer->state >= 2 )
			{
				if ( pRemuxer->ps_builder != NULL )
					pRemuxer->ps_builder->state = PUMPOUT_DATA;
				if ( pRemuxer->ts_builder != NULL )
					pRemuxer->ts_builder->state = PUMPOUT_DATA;
			}

		} else
		if ( strstr( (char*)message->message, "STREAM READY" ) )
		{
			int slot_index = 0;
			const char *p;
			TRACKS *tracks, *tracks_out;

			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			tracks = GetTracks( pRemuxer->demuxer, slot_index );
			tracks_out = pRemuxer->output_track[slot_index];

			if ( SourceIsPSType( pRemuxer->demuxer ) && IsSageTVRecording( pRemuxer->demuxer ) )
			{
				PickupSageTVMainTrack( pRemuxer->demuxer, tracks );
			}

			CheckTracksAttr( tracks , pRemuxer->language_code );
			if ( FindMainVideoAudio( tracks ) )
			{
				SageLog(( _LOG_TRACE, 3, TEXT("Main video at track:%d; Main audio at track:%d"), 
							                tracks->main_video_index,	tracks->main_audio_index ));
				if ( pRemuxer->remuxer_ctrl & MAIN_TRACK_ONLY )
				{
					DisableAuxTrack( tracks );
				}

			} else
			{
				SageLog(( _LOG_ERROR, 3, TEXT("ERROR: main video and audio track not found" ) ));
			}

			TracksIndexing( tracks );
			_display_av_inf( tracks );
			
			SetupRemuxOutput( tracks, tracks_out );

			if ( pRemuxer->ps_builder != NULL )
			{
				CreatSageStreamHeader( pRemuxer->ps_builder );
			} else
			if ( pRemuxer->ts_builder != NULL )
			{
				UpdatePMT( pRemuxer->ts_builder, slot_index );
			} 

			if ( pRemuxer->state == 1 )
			{
				pRemuxer->state = 2; //output data
			}
			
			if ( pRemuxer->task == STRIP_STREAM )
			{
				char avinf[1024];
				int bytes;
				bytes = snprintf( avinf, sizeof(avinf), "AV-INF|f=" );
				bytes += TracksInfo( tracks, avinf+bytes, sizeof(avinf)-bytes );
				if ( pRemuxer->dumper.avinf_dumper != NULL )
					pRemuxer->dumper.avinf_dumper( pRemuxer->dumper.avinf_dumper_context, avinf, bytes );
				SageLog(( _LOG_TRACE, 3, TEXT("OUTPUT:%s"), avinf ));
			} else
			{
				char avinf[1024];
				int bytes;
				bytes = snprintf( avinf, sizeof(avinf), "AV-INF|f=" );
				bytes += TracksInfo( tracks_out, avinf+bytes, sizeof(avinf)-bytes );
				if ( pRemuxer->dumper.avinf_dumper != NULL )
					pRemuxer->dumper.avinf_dumper( pRemuxer->dumper.avinf_dumper_context, avinf, bytes );
				SageLog(( _LOG_TRACE, 3, TEXT("OUTPUT:%s"), avinf ));
			} 

			//start dumping data
			if ( pRemuxer->task == REMUX_STREAM )
			{
				if ( pRemuxer->ps_builder != NULL )
					pRemuxer->ps_builder->state = PUMPOUT_DATA;
				if ( pRemuxer->ts_builder != NULL )
					pRemuxer->ts_builder->state = PUMPOUT_DATA;
			} else
			//if remux a file, rewind to begining of a file to start
			if ( pRemuxer->task == REMUX_FILE && pRemuxer->state < 3  )
			{
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				QueueZeroDemux( pRemuxer->demuxer );
				
				DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
				SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																							 (unsigned long)pos ));
				PTSLog(( 0, 0, 0, 0, 0 ) ); 

				pRemuxer->state = 3; //rewinded  
			}

			if ( pRemuxer->ps_builder != NULL )
			{
				OUTPUT_DATA output_data={0};
				if ( !(pRemuxer->ps_builder->build_ctrl & BUILD_HEADER_IN_BUFFER ) )
				{
					//dump a system head block (PACK+SYSTEM HEADER)
					output_data.data_ptr = pRemuxer->ps_builder->block_buffer; 
					output_data.bytes    = pRemuxer->ps_builder->system_packet_bytes;
					pRemuxer->ps_builder->dumper.stream_dumper( pRemuxer->ps_builder->dumper.stream_dumper_context, 
						                              &output_data, sizeof(output_data) );
					//PadingBuffer( pRemuxer->ps_builder->block_buffer, pRemuxer->ps_builder->buffer_size ); //clean up pading buffer
					pRemuxer->ps_builder->system_packet_bytes = 0;
				} else
				{
					BLOCK_BUFFER *block_buffer;
					TRACK track={0}; 
					track.channel_index = 0;
					block_buffer = RequestBlockBuffer( pRemuxer->demuxer, &track );
					if ( block_buffer != NULL )
					{
						ASSERT( block_buffer->buffer_size >= pRemuxer->ps_builder->system_packet_bytes );
						memcpy( block_buffer->buffer_start, pRemuxer->ps_builder->block_buffer, 
															pRemuxer->ps_builder->system_packet_bytes );
						//PadingBuffer( block_buffer->data_start+pRemuxer->ps_builder->system_packet_bytes, 
						//	          block_buffer->data_size-pRemuxer->ps_builder->system_packet_bytes ); 
						output_data.data_ptr = block_buffer->data_start; 
						output_data.bytes    = pRemuxer->ps_builder->system_packet_bytes;
						pRemuxer->ps_builder->dumper.stream_dumper( pRemuxer->ps_builder->dumper.stream_dumper_context, 
																					  &output_data, sizeof(output_data) );
						ReturnBlockBuffer( pRemuxer->demuxer, block_buffer );
					}
				}
			}
			if ( pRemuxer->state == 2 )
			{
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				SageLog(( _LOG_ERROR, 3, TEXT("****** Find AVINF (pos:%d) ******" ), (unsigned long)pos ));
			}

			//debug_dump_content = 1;  //ZQ

		} else
		if ( strstr( (char*)message->message, "STREAM REBUILD" ) )
		{
			int slot_index = 0;
			const char *p;
			SageLog(( _LOG_TRACE, 3, TEXT("****** PARSER STATUS: %s ******"), message->message ));
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );
			 {
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				QueueZeroDemux( pRemuxer->demuxer );
				DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
				SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																							(unsigned long)pos ));
			}


		} else
		if ( strstr( (char*)message->message, "STREAM FAILED" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

		} else
		if ( strstr( (char*)message->message, "STREAM END" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			if ( pRemuxer->task != REMUX_FILE )
			{
				//do nothing
			} else
			{
				if ( pRemuxer->state == 1 )  //parsing information, not done yet, force it done
				{
					TRACKS *tracks, *tracks_out;
					tracks = GetTracks( pRemuxer->demuxer, slot_index );
					tracks_out = pRemuxer->output_track[slot_index];

					CheckTracksAttr( tracks , pRemuxer->language_code );
					if ( FindMainVideoAudio( tracks ) )
					{
						SageLog(( _LOG_TRACE, 3, TEXT("Main video at track:%d; Main audio at track:%d"), 
												  tracks->main_video_index,	tracks->main_audio_index ));

						if ( pRemuxer->remuxer_ctrl & MAIN_TRACK_ONLY )
						{
							DisableAuxTrack( tracks );
						}

					} else
					{
						SageLog(( _LOG_ERROR, 3, TEXT("ERROR: main video and audio track not found" ) ));
					}
					TracksIndexing( tracks );
					_display_av_inf( tracks );

					SetupRemuxOutput( tracks, tracks_out );
					if ( pRemuxer->ps_builder != NULL )
					{
						CreatSageStreamHeader( pRemuxer->ps_builder );
					} else
					if ( pRemuxer->ts_builder != NULL )
					{
						UpdatePMT( pRemuxer->ts_builder, slot_index );
					} 

					pRemuxer->state = 2; //output data

					{
						ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
						QueueZeroDemux( pRemuxer->demuxer );

						DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
						SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																									 (unsigned long)pos ));
						PTSLog(( 0, 0, 0, 0, 0 ) ); 
					}

				} else
				{
					FlushRemuxer( pRemuxer, slot_index );
				}
			}
		}
	}

	return 1;
}
示例#24
0
void AudioView::UpdateMenus()
{
  numEffects = Effect::GetNumEffects();

  if (undoManager.UndoAvailable())
    editMenu->Enable(editMenu->FindItem(wxString("Undo")), TRUE);
  else
    editMenu->Enable(editMenu->FindItem(wxString("Undo")), FALSE);    

  if (undoManager.RedoAvailable())
    editMenu->Enable(editMenu->FindItem(wxString("Redo")), TRUE);
  else
    editMenu->Enable(editMenu->FindItem(wxString("Redo")), FALSE);    

  if (clipboard->First() != 0) {
    editMenu->Enable(editMenu->FindItem(wxString("Paste")), TRUE);
  }
  else {
    editMenu->Enable(editMenu->FindItem(wxString("Paste")), FALSE);
  }
	
  TrackList *tracks = GetTracks();

  int numTracks=0;
  int numSelected=0;

  VTrack *t = tracks->First();
  while(t) {
	numTracks++;
	if (t->selected)
	  numSelected++;
	t = tracks->Next();
  }
  
  if (numSelected>0) {
    trackMenu->Enable(trackMenu->FindItem(wxString("Quick Mix")), TRUE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Waveform Display")), TRUE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Spectrum Display")), TRUE);
    trackMenu->Enable(trackMenu->FindItem(wxString("AutoCorrelate")), TRUE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Pitch Extract")), TRUE);

    trackMenu->Enable(trackMenu->FindItem(wxString("Remove")), TRUE);
		
    fileMenu->Enable(projectMenu->FindItem(wxString("Export")), TRUE);
	
	for (int fi = 0; fi < numEffects; fi++)
	  effectMenu->Enable(effectMenu->FindItem(
        (Effect::GetEffect(fi))->GetEffectName()), TRUE);

	editMenu->Enable(editMenu->FindItem(wxString("Cut")), TRUE);
	editMenu->Enable(editMenu->FindItem(wxString("Copy")), TRUE);
	editMenu->Enable(editMenu->FindItem(wxString("Clear")), TRUE);
  }
  else {	
    for (int fi = 0; fi < numEffects; fi++)
      effectMenu->Enable(effectMenu->FindItem
			 ((Effect::GetEffect(fi))->GetEffectName()), FALSE);

    editMenu->Enable(editMenu->FindItem(wxString("Cut")), FALSE);
    editMenu->Enable(editMenu->FindItem(wxString("Copy")), FALSE);
    editMenu->Enable(editMenu->FindItem(wxString("Clear")), FALSE);

    trackMenu->Enable(trackMenu->FindItem(wxString("Quick Mix")), FALSE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Waveform Display")), FALSE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Spectrum Display")), FALSE);
    trackMenu->Enable(trackMenu->FindItem(wxString("AutoCorrelate")), FALSE);
    trackMenu->Enable(trackMenu->FindItem(wxString("Pitch Extract")), FALSE);

    trackMenu->Enable(trackMenu->FindItem(wxString("Remove")), FALSE);
		
    fileMenu->Enable(projectMenu->FindItem(wxString("Export")), FALSE);
  }
}
示例#25
0
void AudioView::FixScrollbars()
{
  if (!hsbar || !vsbar)
    return;

  AudioDoc *doc = ((AudioDoc *)GetDocument());
  if (!doc)
    return;
    
  bool rescroll = false;

  TrackList *tracks = GetTracks();
  int totalHeight = (tracks->GetHeight() + 32);

  int panelWidth, panelHeight;
  trackPanel->GetSize(&panelWidth, &panelHeight);

  sinfo.total = tracks->GetMaxLen() + 1.0;
  sinfo.screen = ((double)panelWidth) / sinfo.zoom;

  if (sinfo.h > sinfo.total - sinfo.screen) {
  	sinfo.h = sinfo.total - sinfo.screen;
  	rescroll = true;
  }
  if (sinfo.h < 0.0) {
  	sinfo.h = 0.0;
  	rescroll = true;
  }

  sinfo.sbarTotal = (int)(sinfo.total * sinfo.zoom) / sinfo.scrollStep;
  sinfo.sbarScreen = (int)(sinfo.screen * sinfo.zoom) / sinfo.scrollStep;

  sinfo.sbarH = (int)(sinfo.h * sinfo.zoom) / sinfo.scrollStep;

  vpos =
	vsbar->GetThumbPosition() * sinfo.scrollStep;

  if (vpos >= totalHeight)
	vpos = totalHeight-1;
  if (vpos < 0)
	vpos = 0;

  hsbar->Show(sinfo.screen < sinfo.total);
  vsbar->Show(panelHeight < totalHeight);

  if (panelHeight >= totalHeight && vpos != 0) {
	vpos = 0;
	REDRAW(trackPanel);
	REDRAW(rulerPanel);
	rescroll = false;
  }
  if (sinfo.screen >= sinfo.total && sinfo.sbarH != 0) {
	sinfo.sbarH = 0;
	REDRAW(trackPanel);
	REDRAW(rulerPanel);
	rescroll = false;
  }

  hsbar->SetScrollbar(sinfo.sbarH, sinfo.sbarScreen,
					  sinfo.sbarTotal, sinfo.sbarScreen, TRUE);
  vsbar->SetScrollbar(vpos / sinfo.scrollStep,
					  panelHeight / sinfo.scrollStep,
					  totalHeight / sinfo.scrollStep,
					  panelHeight / sinfo.scrollStep,
					  TRUE);

  sinfo.lastZoom = sinfo.zoom;
  
  if (rescroll && sinfo.screen < sinfo.total) {
	  REDRAW(trackPanel);
		REDRAW(rulerPanel);
  }
}
示例#26
0
// Draw all tracks
void AudioView::DrawTracks(wxDC *dc, wxRect *visible)
{
  wxRect r;
  
  r.x = visible->x;
  r.y = -vpos;
  r.width = visible->width;
  
  TrackList *tracks = GetTracks();
  VTrack *t;
  int num=0;
  
  t = tracks->First();
  while(t) {
	r.height = t->GetHeight();
	
	// If it's visible at all (vertically)
	if (r.y < (visible->y + visible->height) && (r.y + r.height) > visible->y)
	  {
	    double h = sinfo.h + (r.x / sinfo.zoom);
	    
		bool sel = t->selected;
		
		// Tell VTrack to draw itself

		wxRect innerRect = r;
		innerRect.x += labelWidth;
		innerRect.width -= labelWidth;
		innerRect.y += 4;
		innerRect.height -= 16;
		
		if (!t->IsCollapsed()) {
		  if (sel)
			t->Draw(*dc, innerRect, h, sinfo.zoom, sel0, sel1);
		  else
			t->Draw(*dc, innerRect, h, sinfo.zoom, 0.0, 0.0);
		}
		else {
		  dc->SetBrush(backgroundBrush);
		  dc->SetPen(backgroundPen);
		  
		  dc->DrawRectangle(innerRect);
		}
		
		// Draw label

		wxRect labelRect = r;
		  
		labelRect.width = labelWidth;
		  
		dc->SetBrush(mediumBrush[sel]);
		dc->SetPen(mediumPen[sel]);
		
		dc->DrawRectangle(labelRect);
		
		dc->SetPen(lightPen[sel]);
		
		dc->DrawLine(labelRect.x, labelRect.y,
					 labelRect.x + labelRect.width, labelRect.y);
		dc->DrawLine(labelRect.x, labelRect.y,
					 labelRect.x, labelRect.y + labelRect.height);
		dc->DrawLine(labelRect.x+1, labelRect.y+1,
					 labelRect.x + labelRect.width, labelRect.y+1);
		dc->DrawLine(labelRect.x+1, labelRect.y+1,
					 labelRect.x+1, labelRect.y + labelRect.height);	
		
		dc->SetPen(darkPen[sel]);
		
		dc->DrawLine(labelRect.x, labelRect.y + labelRect.height,
					 labelRect.x + labelRect.width, labelRect.y + labelRect.height);
		dc->DrawLine(labelRect.x+1, labelRect.y + labelRect.height-1,
					 labelRect.x + labelRect.width, labelRect.y + labelRect.height-1);
		
		dc->DrawLine(labelRect.x+labelRect.width-1,labelRect.y+4,
					 labelRect.x+labelRect.width-1,labelRect.y+labelRect.height-10);
		dc->DrawLine(labelRect.x+labelRect.width-2,labelRect.y+4,
					 labelRect.x+labelRect.width-2,labelRect.y+labelRect.height-10);
		
		int ctr = labelRect.y + (labelRect.height/2);
		dc->SetTextForeground(wxColour(0,0,0));
		char str[100];
		sprintf(str,"%d",num+1);		
		dc->DrawText(str, labelRect.x+15, ctr-8);		
		if (t->GetKind()==VTrack::Wave) {
		  sprintf(str,"%dk",(int)(((WaveTrack *)t)->rate/1000));
		  dc->DrawText(str, labelRect.x+5, ctr+8);
		}

		r.x += labelWidth;

		// Draw top bevels

		dc->SetPen(lightPen[sel]);
		dc->DrawLine(r.x, r.y, r.x + r.width, r.y);
		dc->DrawLine(r.x, r.y+1, r.x + r.width, r.y+1);
		dc->SetPen(mediumPen[sel]);
		dc->DrawLine(r.x, r.y+2, r.x + r.width, r.y+2);
		dc->DrawLine(r.x, r.y+3, r.x + r.width, r.y+3);
		dc->SetPen(darkPen[sel]);
		dc->DrawLine(r.x, r.y+4, r.x + r.width, r.y+4);
		dc->DrawLine(r.x, r.y+5, r.x + r.width, r.y+5);

		// Draw bottom bevels

		dc->SetPen(lightPen[sel]);
		dc->DrawLine(r.x, r.y+r.height-12, r.x + r.width, r.y+r.height-12);
		dc->DrawLine(r.x, r.y+r.height-11, r.x + r.width, r.y+r.height-11);
		dc->SetPen(darkPen[sel]);
		dc->DrawLine(r.x, r.y+r.height-1, r.x + r.width, r.y+r.height-1);
		dc->DrawLine(r.x, r.y+r.height-2, r.x + r.width, r.y+r.height-2);

		dc->SetPen(mediumPen[sel]);

		int j;
		for(j=3; j<=10; j++)
		  dc->DrawLine(r.x, r.y+r.height-j, r.x + r.width, r.y+r.height-j);

		dc->SetPen(lightPen[sel]);
		for(j=r.width/2-40; j<r.width/2+40; j+=4)
		  dc->DrawLine(r.x+j, r.y+r.height-9, r.x+j, r.y+r.height-5);
		dc->SetPen(darkPen[sel]);
		for(j=r.width/2-39; j<r.width/2+41; j+=4)
		  dc->DrawLine(r.x+j, r.y+r.height-9, r.x+j, r.y+r.height-5);

		r.x -= labelWidth;
	  }
  
    r.y += r.height;
	num++;
    t = tracks->Next();
  }

  r.height = visible->height;
  dc->SetBrush(backgroundBrush);
  dc->SetPen(backgroundPen);
  dc->DrawRectangle(r);
}
示例#27
0
bool AudioView::DragTrack(wxMouseEvent &event)
{
  VTrack *t;
  wxRect r;
  int num;
  
  if (capturedTrack) {
	t = capturedTrack;
	r = capturedRect;
	num = capturedNum;
  }
  else
	t = FindTrack(event.m_x, event.m_y, false, &r, &num);
  
  if (t) {
	mouseMostRecentX = event.m_x;
	mouseMostRecentY = event.m_y;

	if (resizing) {
	  int delta = (event.m_y - mouseClickY);
	  int newTrackHeight = initialTrackHeight + delta;
	  if (newTrackHeight < 20)
		newTrackHeight = 20;
	  t->SetHeight(newTrackHeight);
	  REDRAW(trackPanel);
	}
    else if (dragging) {
      double selend = sinfo.h + ((event.m_x - r.x) / sinfo.zoom);

	  if (selend < 0.0)
		selend = 0.0;
      
      if (selend != selstart) {
        t->Offset(selend - selstart);
        REDRAW(trackPanel);
      }
    
      selstart = selend;
    }
    else {
	  // Selecting

      double selend = sinfo.h + ((event.m_x - r.x) / sinfo.zoom);
      
	  if (selend < 0.0)
		selend = 0.0;

      if (selend >= selstart) {
		sel0 = selstart;
		sel1 = selend;
	  }
	  else {
		sel0 = selend;
		sel1 = selstart;
	  }

	  // Handle which tracks are selected

	  int num2;
	  if (0 != FindTrack(event.m_x, event.m_y, false, NULL, &num2)) {
		// The tracks numbered num...num2 should be selected
		
		TrackList *tracks = GetTracks();
		VTrack *t = tracks->First();
		int i=1;
		while(t) {
		  t->selected = (i>=num && i<=num2) || (i>=num2 && i<=num);
		  t = tracks->Next();
		  i++;
		}
	  }

	  wxString str;
	  str.Printf("Selection: %lf - %lf seconds",sel0,sel1);
	  status->SetLabel(str);

      REDRAW(trackPanel);
    }
 
    return true;
  }
  else
    return false;
}
示例#28
0
// What to do when a view is created. Creates actual
// windows for displaying the view.
bool AudioView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
{
  gNumViewsOpen++;

  frame = wxGetApp().CreateChildFrame(doc, this, TRUE);

  //
  // Create Menu Bar
  //

  menuBar = new wxMenuBar();

  fileMenu = new wxMenu();
  fileMenu->Append(wxID_NEW, "&New...\tCtrl+N");
  fileMenu->Append(wxID_OPEN, "&Open...\tCtrl+O");
  fileMenu->Append(wxID_CLOSE, "&Close\tCtrl+W");
  fileMenu->Append(wxID_SAVE, "&Save\tCtrl+S");
  fileMenu->Append(wxID_SAVEAS, "Save As...");
  fileMenu->Append(ExportID, "&Export...");
  fileMenu->AppendSeparator();
  fileMenu->Append(wxID_PRINT, "&Print...\tCtrl+P");
  fileMenu->Append(wxID_PRINT_SETUP, "Print Setup...");
  fileMenu->Append(wxID_PREVIEW, "Print Preview");
  fileMenu->AppendSeparator();
  fileMenu->Append(wxID_EXIT, "E&xit");

  editMenu = new wxMenu();
  editMenu->Append(UndoID, "&Undo\tCtrl+Z");
  editMenu->Append(RedoID, "&Redo\tCtrl+R");
  editMenu->AppendSeparator();
  editMenu->Append(CutID, "Cut\tCtrl+X");
  editMenu->Append(CopyID, "Copy\tCtrl+C");
  editMenu->Append(PasteID, "Paste\tCtrl+V");
  editMenu->Append(ClearID, "Clear\tCtrl+B");
  editMenu->AppendSeparator();
  editMenu->Append(SelectAllID, "Select All\tCtrl+A");

  doc->GetCommandProcessor()->SetEditMenu(editMenu);

  projectMenu = new wxMenu();

  projectMenu->Append(ImportID, "&Import Audio...\tCtrl+I");
  projectMenu->Append(ImportRawID, "Import Raw Data...");
  projectMenu->Append(ImportMIDIID, "Import &MIDI...");
  projectMenu->Append(ImportMP3ID, "Import MP3...");
  projectMenu->AppendSeparator();
  projectMenu->Append(WaveTrackID, "New Audio Track");
  //  projectMenu->Append(LabelTrackID, "New Label Track");
  projectMenu->AppendSeparator();
  projectMenu->Append(RemoveTrackID, "&Remove Track(s)");

  trackMenu = new wxMenu();
  trackMenu->Append(QuickMixID, "Quick Mix");
  trackMenu->AppendSeparator();
  trackMenu->Append(WaveDisplayID, "Waveform Display");
  trackMenu->Append(SpectrumDisplayID, "Spectrum Display");
  trackMenu->AppendSeparator();
  //  trackMenu->Append(AutoCorrelateID, "AutoCorrelate");
  trackMenu->Append(PitchID, "Pitch Extract");
  
  effectMenu = new wxMenu();

  numEffects = Effect::GetNumEffects();
  for(int fi = 0; fi < numEffects; fi++)
    effectMenu->Append(FirstEffectID+fi,
		       (Effect::GetEffect(fi))->GetEffectName());

  helpMenu = new wxMenu;
  helpMenu->Append(wxID_ABOUT, "&About Audacity...");

  menuBar->Append(fileMenu, "&File");
  menuBar->Append(editMenu, "&Edit");
  menuBar->Append(projectMenu, "&Project");
  menuBar->Append(trackMenu, "&Track");
  menuBar->Append(effectMenu, "E&ffect");
  menuBar->Append(helpMenu, "&Help");

  frame->SetMenuBar(menuBar);  
  
  //
  // Make all child windows
  //

  int sbarWidth = 15;

  rulerPanel =
	new RulerPanel(this, frame, wxDefaultPosition,
				   wxSize(600 - labelWidth, 30), 0);

  trackPanel =
	new TrackPanel(this, frame, wxDefaultPosition,
				   wxSize(600, 300), 0);

  hsbar =
	new wxScrollBar(frame, HSBarID, wxDefaultPosition,
					wxSize(600, sbarWidth), wxSB_HORIZONTAL);

  vsbar =
	new wxScrollBar(frame, VSBarID, wxDefaultPosition,
					wxSize(sbarWidth, 300), wxSB_VERTICAL);

  status = new wxStaticText(frame, 0, "", wxDefaultPosition,
			  wxDefaultSize);
  status->SetLabel("");

  wxButton *b1;
  wxButton *b2;
  wxButton *b3;
  wxButton *b4;

  wxBitmap *zoomIn = new wxBitmap();
  wxBitmap *zoomOut = new wxBitmap();
  wxBitmap *play = new wxBitmap();
  wxBitmap *stop = new wxBitmap();

  if (zoomIn->LoadFile(BITMAP_PRE "ZoomIn" BITMAP_SUF,AUDACITY_BITMAP_TYPE) &&
      zoomOut->LoadFile(BITMAP_PRE "ZoomOut" BITMAP_SUF,AUDACITY_BITMAP_TYPE) &&
      play->LoadFile(BITMAP_PRE "Play" BITMAP_SUF,AUDACITY_BITMAP_TYPE) &&
      stop->LoadFile(BITMAP_PRE "Stop" BITMAP_SUF,AUDACITY_BITMAP_TYPE)) {
    
    b1 = (wxButton *)new wxBitmapButton
      (frame, ZoomInButtonID, *zoomIn,
       wxPoint(0, 0), wxSize(36, 36));
    b2 = (wxButton *)new wxBitmapButton
      (frame, ZoomOutButtonID, *zoomOut,
       wxPoint(30, 0), wxSize(36, 36));
    b3 = (wxButton *)new wxBitmapButton
      (frame, PlayButtonID, *play,
	   wxPoint(30, 0), wxSize(36, 36));
    b4 = (wxButton *)new wxBitmapButton
      (frame, StopButtonID, *stop,
       wxPoint(30, 0), wxSize(36, 36));

    b1->SetBackgroundColour(backgroundColor);
    b2->SetBackgroundColour(backgroundColor);
    b3->SetBackgroundColour(backgroundColor);
    b4->SetBackgroundColour(backgroundColor);
  }	  
  else {
	delete zoomIn;
	delete zoomOut;
	delete play;
	delete stop;
	
	b1 = new wxButton(frame, ZoomInButtonID, "<",
					  wxPoint(0, 0), wxSize(36,36));
	b2 = new wxButton(frame, ZoomOutButtonID, ">",
					  wxPoint(0, 0), wxSize(36,36));
	b3 = new wxButton(frame, PlayButtonID, "Play",
					  wxPoint(0, 0), wxSize(128,36));
	b4 = new wxButton(frame, StopButtonID, "Stop",
					  wxPoint(0, 0), wxSize(128,36));
  }

  wxBitmap *smallLogoBitmap = new wxBitmap();
  wxStaticBitmap *smallLogo = 0;
  if (smallLogoBitmap->LoadFile(BITMAP_PRE "AudacitySmall" BITMAP_SUF,
				AUDACITY_BITMAP_TYPE)) {
    smallLogo = new wxStaticBitmap(frame, 0, *smallLogoBitmap,
				   wxDefaultPosition, wxDefaultSize);
  }

  //
  // Lay them out using box sizers
  //

  mainSizer = new wxBoxSizer(wxVERTICAL);
  topSizer = new wxBoxSizer(wxHORIZONTAL);
  bottomSizer = new wxBoxSizer(wxHORIZONTAL);
  trackSizer = new wxBoxSizer(wxVERTICAL);

  mainSizer->Add(topSizer, 1, wxEXPAND, 0);
  mainSizer->Add(bottomSizer, 0, wxEXPAND | wxALL, 2);

  topSizer->Add(trackSizer, 1, wxEXPAND, 0);
  topSizer->Add(vsbar, 0, wxEXPAND | wxBOTTOM, sbarWidth);

  trackSizer->Add(rulerPanel, 0, wxEXPAND | wxLEFT, labelWidth);
  trackSizer->Add(trackPanel, 1, wxEXPAND, 0);
  trackSizer->Add(hsbar, 0, wxEXPAND, 0);

  bottomSizer->Add(b1, 0, wxEXPAND, 0);
  bottomSizer->Add(b2, 0, wxEXPAND, 0);
  bottomSizer->Add(b3, 0, wxEXPAND | wxLEFT, 24);
  bottomSizer->Add(b4, 0, wxEXPAND, 0);
  bottomSizer->Add(status, 1, wxEXPAND | wxLEFT, 24);
  if (smallLogo)
    bottomSizer->Add(smallLogo, 0, wxLEFT | wxRIGHT, 24);

  frame->SetAutoLayout(true);
  frame->SetSizer(mainSizer);

  mainSizer->Fit(frame);
  mainSizer->SetSizeHints(frame);

  //
  //
  //

  InitialState();

  FixScrollbars();
  
  frame->SetBackgroundColour(backgroundColor);

#ifdef __X__
  // X seems to require a forced resize
  int x, y;
  frame->GetSize(&x, &y);
  frame->SetSize(-1, -1, x, y);
#endif

  // Min size, max size
  frame->SetSizeHints(250,200,20000,20000);

  frame->Show(TRUE);

  #ifdef __WXMAC__
  
  // This (hack) tells various windows not to erase the background on update events.
  //frame->m_MacEraseBack = false;
  trackPanel->m_MacEraseBack = false;
  rulerPanel->m_MacEraseBack = false;
  hsbar->m_MacEraseBack = false;
  vsbar->m_MacEraseBack = false;
  #endif

  #ifdef DEBUG_PASTE_BUG  // probably can remove this - fixed

  WaveTrack *left = 0;
  WaveTrack *right = 0;
  ImportWAV("Mussorgsky1.WAV", &left, &right,
			&((AudioDoc *)GetDocument())->dirManager);

  selected->Clear();  
  GetTracks()->Add(left);
  selected->Add(left);

  PushState();

  sel0 = 2.0;
  sel1 = 4.0;

  Cut();

  left->Debug();

  sel0 = 4.0;
  sel1 = 4.0;

  Paste();

  left->Debug();

  FixScrollbars();
  REDRAW(trackPanel);
  REDRAW(rulerPanel);

  #endif
  
  return TRUE;
}